[Cuis-dev] Erudite
Gerald Klix
cuis.01 at klix.ch
Sat Oct 15 08:21:17 PDT 2022
Maybe the attached packages helps.
It's a bit old and untested/unused for at least a year,
but it may provide a start.
HTH,
Gerald
On 15.10.22 15:36, Mariano Montone via Cuis-dev wrote:
> El 15/10/22 a las 10:18, Mariano Montone escribió:
>>>
>>> Mariano, in the example you mentioned, the documentation are markdown
>>> files. How does it work with literate programming?
>>>
>> My example was with Markdown, but you would use files in Erudite
>> source format, not Markdown, for your usecase. Then you build Erudite
>> books from those files. It is straightforward. There are no
>> conversions. Only matter: there are no good external editing tools for
>> those files, that can give you a preview, etc. But, are there good
>> user-facing editing tools for TexInfo, for example? Not sure Emacs
>> counts. So, I think it would be more or less like what you have now
>> with TexInfo, but you would have Erudite source files instead. Also,
>> I'm thinking a specialized Erudite editor could be provided for files
>> in Erudite format, coded in Cuis + Erudite, if you wanted.
>>
> Difference is TexInfo can produce HTML, and Erudite does not atm.
> Perhaps implement an Erudite -> TexInfo exporter. Still not sure what
> would be the best option that'd give you what you are looking for in the
> cheapest way.
>
-------------- next part --------------
'From Haver 5.0 [latest update: #4559] on 29 March 2021 at 7:43:01 pm'!
'Description '!
!provides: 'EruditeHTML' 1 2!
SystemOrganization addCategory: 'EruditeHTML'!
!classDefinition: #HTMLEruditeDocRenderer category: 'EruditeHTML'!
Object subclass: #HTMLEruditeDocRenderer
instanceVariableNames: 'stream requestor highlightSyntax book documentClass htmlFilePath'
classVariableNames: ''
poolDictionaries: ''
category: 'EruditeHTML'!
!classDefinition: 'HTMLEruditeDocRenderer class' category: 'EruditeHTML'!
HTMLEruditeDocRenderer class
instanceVariableNames: ''!
!HTMLEruditeDocRenderer commentStamp: '<historical>' prior: 0!
Renders a Book to a Latex file.
Example:
(LatexEruditeDocRenderer on: CuisManual new)
texFilePath: '/home/marian/src/Cuis/Erudite/CuisManual.tex';
render.
(LatexEruditeDocRenderer on: EruditeManual new)
texFilePath: '/home/marian/src/Cuis/Erudite/EruditeManual.tex';
render.
Then process with pdflatex -shell-escape <file.tex>!
!HTMLEruditeDocRenderer methodsFor: 'rendering' stamp: 'KLG 3/25/2021 21:57:27'!
render
self renderWithTemplate: [
book sections do: [:aBookSection |
self renderSection: aBookSection]].
htmlFilePath fileContents: stream contents! !
!HTMLEruditeDocRenderer methodsFor: 'rendering' stamp: 'KLG 3/29/2021 19:24:39'!
renderCode: aDocCode
"Render some (Smalltalk_ code"
self renderElement: 'pre' withContents: aDocCode code
! !
!HTMLEruditeDocRenderer methodsFor: 'rendering' stamp: 'KLG 3/29/2021 19:21:32'!
renderDocument: aDocument
|doc|
doc _ EruditeMarkupParser parse: aDocument contents.
doc contents do: [:node |
node isString
ifTrue: [ | textToRender needsParagraph |
(needsParagraph _ node first = Character newLineCharacter "?: and: [ node second = Character newLineCharacter ]")
ifTrue: [
textToRender _ node copyFrom: 2.
stream
newLine;
nextPutAll: '<p>' ]
ifFalse: [ textToRender _ node ].
stream nextPutAll: (self escapeHTML: textToRender).
needsParagraph ifTrue: [
stream
nextPutAll: '</p>';
newLine ] ]
ifFalse: [ node accept: self].
stream ]! !
!HTMLEruditeDocRenderer methodsFor: 'rendering' stamp: 'KLG 3/26/2021 13:45:18'!
renderElement: anElementName withContents: aString
"Render an element with contents a string."
stream nextPut: $<;
nextPutAll: anElementName;
nextPut: $>;
nextPutAll: aString ;
nextPutAll: '</';
nextPutAll: anElementName;
nextPut: $>
! !
!HTMLEruditeDocRenderer methodsFor: 'rendering' stamp: 'KLG 3/29/2021 18:43:48'!
renderElement: anElementName withContents: aString andAttributes: someAttributes
"Render an element with contents a string."
stream nextPut: $<;
nextPutAll: anElementName.
someAttributes keysAndValuesDo: [ :key :value |
stream
nextPut: ($ );
nextPutAll: key;
nextPut: $=;
nextPutAll: value ].
stream
nextPut: $>;
nextPutAll: aString ;
nextPutAll: '</';
nextPutAll: anElementName;
nextPut: $>
! !
!HTMLEruditeDocRenderer methodsFor: 'rendering' stamp: 'KLG 3/29/2021 18:31:49'!
renderHeading: aTitleString level: anInteger
"Render a heading."
stream nextPutAll: '<h'.
anInteger printOn: stream.
stream
nextPut: $>;
nextPutAll: aTitleString;
nextPutAll: '</h'.
anInteger printOn: stream.
stream
nextPut: $>;
nl
! !
!HTMLEruditeDocRenderer methodsFor: 'rendering' stamp: 'KLG 3/26/2021 23:00:50'!
renderSection: aBookSection
"Render a section of a book."
self
renderHeading: aBookSection title level: 1;
renderDocument: aBookSection document.
aBookSection sections do: [:section |
self renderSubsection: section]! !
!HTMLEruditeDocRenderer methodsFor: 'rendering' stamp: 'KLG 3/26/2021 23:01:08'!
renderSubsection: aBookSection
self
renderHeading: aBookSection title level: 2;
renderDocument: aBookSection document.
aBookSection sections do: [:section |
self renderSubsubsection: section]! !
!HTMLEruditeDocRenderer methodsFor: 'rendering' stamp: 'KLG 3/26/2021 23:00:26'!
renderSubsubsection: aBookSection
self
renderHeading: aBookSection title level: 3;
renderDocument: aBookSection document
! !
!HTMLEruditeDocRenderer methodsFor: 'rendering' stamp: 'KLG 3/29/2021 18:28:18'!
renderWithTemplate: aBlock
"Render with a template; maybe a stylesheet."
stream
nextPutAll: '<html>';
newLine;
nextPutAll: '<head>';
newLine;
nextPutAll: '</head>';
newLine;
nextPutAll: '<body>'.
aBlock value.
stream
newLine;
nextPutAll: '</body>'! !
!HTMLEruditeDocRenderer methodsFor: 'visiting' stamp: 'KLG 3/26/2021 23:02:56'!
visitActionLink: aDocLink
self renderElement: 'u' withContents: aDocLink title! !
!HTMLEruditeDocRenderer methodsFor: 'visiting' stamp: 'KLG 3/25/2021 21:52:19'!
visitCode: aDocCode
self renderCode: aDocCode
"aDocCode action ifNil: [
^ self renderCode: aDocCode].
(aDocCode action at: #action) caseOf: {
[#doIt] -> [self renderCodeDoIt: aDocCode].
[#exploreIt] -> [self renderCodeExploreIt: aDocCode].
[#inspectIt] -> [self renderCodeInspectIt: aDocCode].
[#printIt] -> [self renderCodePrintIt: aDocCode].
[#printItHere] -> [self renderCodePrintItHere: aDocCode].
[#embedIt] -> [self renderCodeEmbedIt: aDocCode].
[#doItWithButton] -> [self renderCodeDoItWithButton: aDocCode].
[#exploreItWithButton] -> [self renderCodeExploreItWithButton: aDocCode].
[#inspectItWithButton] -> [self renderCodeInspectItWithButton: aDocCode].
[#printItWithButton] -> [self renderCodePrintItWithButton: aDocCode]
}."! !
!HTMLEruditeDocRenderer methodsFor: 'visiting' stamp: 'KLG 3/29/2021 18:49:28'!
visitHeading: anEruditeHeading
"?: self renderHeading: anEruditeHeading heading level: anEruditeHeading level.
stream newLine; newLine"! !
!HTMLEruditeDocRenderer methodsFor: 'visiting' stamp: 'KLG 3/26/2021 23:31:29'!
visitLink: aDocLink
"(self linkRendererFor: aDocLink type) ifNotNil: [:aLinkRenderer |
aLinkRenderer render: aDocLink in: document on: stream]"
| label target |
target _ aDocLink target.
label _ aDocLink label ifNil: target.
self
renderElement: 'a'
withContents: label
andAttributes: {'href' -> target} asDictionary! !
!HTMLEruditeDocRenderer methodsFor: 'visiting' stamp: 'KLG 3/26/2021 23:17:18'!
visitStyledText: aStyledText
self
renderElement: (aStyledText style caseOf: {
[ #bold ] -> [ 'b' ].
[ #italic ] -> [ 'em' ].
[ #unformatted ] -> [ 'blockquote' ] })
withContents: aStyledText text! !
!HTMLEruditeDocRenderer methodsFor: 'initialization' stamp: 'KLG 3/25/2021 21:52:19'!
initialize: aBook
book _ aBook.
stream _ WriteStream on: String new.
documentClass _ #book.
highlightSyntax _ true! !
!HTMLEruditeDocRenderer methodsFor: 'as yet unclassified' stamp: 'KLG 3/25/2021 21:52:19'!
linkRendererFor: aLinkType
|handlerClassName|
handlerClassName _ aLinkType asString capitalized, 'DocLinkRenderer'.
^ Smalltalk at: handlerClassName asSymbol ifAbsent: ["self error: 'No link renderer for: ', aLinkType asString" nil]! !
!HTMLEruditeDocRenderer methodsFor: 'as yet unclassified' stamp: 'KLG 3/25/2021 21:52:19'!
renderArticle
documentClass _ #article.
self render! !
!HTMLEruditeDocRenderer methodsFor: 'as yet unclassified' stamp: 'KLG 3/25/2021 21:52:19'!
renderBook
documentClass _ #book.
self render! !
!HTMLEruditeDocRenderer methodsFor: 'as yet unclassified' stamp: 'KLG 3/25/2021 21:52:19'!
renderCodeDoIt: aDocCode
|text button textModel |
text _ Text string: aDocCode code. .
textModel _ EruditeSmalltalkTextModel withText: text.
textModel formatAndStyle.
stream nextPut: textModel actualContents.
stream nextPut: ' '.
button _ Text string: '[doIt]' attributes:
{TextEmphasis underlined.
BlockTextAction do: [:anObject | Compiler evaluate: aDocCode code notifying: anObject textProvider logged: false]}.
stream nextPut: button.
"button _ PluggableButtonMorph model: nil action: #doIt label: 'DoIt'.
button morphExtent: 40 at 15.
stream nextPut: (Text withForm: button)."! !
!HTMLEruditeDocRenderer methodsFor: 'as yet unclassified' stamp: 'KLG 3/25/2021 21:52:19'!
renderCodeDoItWithButton: aDocCode
stream nextPut: (Text string: (aDocCode action at: #button)
attributes:
{TextColor magenta.
TextEmphasis italic.
TextEmphasis underlined .
BlockTextAction do: [:anObject | Compiler evaluate: aDocCode code notifying: anObject textProvider logged: false]})! !
!HTMLEruditeDocRenderer methodsFor: 'as yet unclassified' stamp: 'KLG 3/25/2021 21:52:19'!
renderCodeEmbedIt: aDocCode
| evalString result |
evalString _ aDocCode code.
requestor
ifNil: [
result _ [Compiler evaluate: evalString for: self logged: false]
on: Error do: [:error | error]]
ifNotNil: [
result _ [Compiler evaluate: evalString notifying: requestor logged: false]
on: Error do: [:error | error]].
stream nextPut: (Text streamContents: [:s | result printOn: s])! !
!HTMLEruditeDocRenderer methodsFor: 'as yet unclassified' stamp: 'KLG 3/25/2021 21:52:19'!
renderCodeExploreIt: aDocCode
|text button evalString textModel |
evalString _ aDocCode code.
text _ Text string: aDocCode code. .
textModel _ EruditeSmalltalkTextModel withText: text.
textModel formatAndStyle.
stream nextPut: textModel actualContents.
stream nextPut: ' '.
button _ Text string: '[exploreIt]'
attributes: {TextEmphasis underlined.
BlockTextAction do: [:anObject | (Compiler evaluate: evalString notifying: anObject textProvider logged: false) explore]}.
stream nextPut: button.! !
!HTMLEruditeDocRenderer methodsFor: 'as yet unclassified' stamp: 'KLG 3/25/2021 21:52:19'!
renderCodeExploreItWithButton: aDocCode
stream nextPut: (Text string: (aDocCode action at: #button)
attributes:
{TextColor magenta.
TextEmphasis italic.
TextEmphasis underlined .
BlockTextAction do: [:anObject | (Compiler evaluate: aDocCode code notifying: anObject textProvider logged: false) explore]})! !
!HTMLEruditeDocRenderer methodsFor: 'as yet unclassified' stamp: 'KLG 3/25/2021 21:52:19'!
renderCodeInspectIt: aDocCode
|text button evalString textModel |
evalString _ aDocCode code.
text _ Text string: aDocCode code. .
textModel _ EruditeSmalltalkTextModel withText: text.
textModel formatAndStyle.
stream nextPut: textModel actualContents.
stream nextPut: ' '.
button _ Text string: '[inspectIt]'
attributes: {TextEmphasis underlined.
BlockTextAction do: [:anObject | (Compiler evaluate: evalString notifying: anObject textProvider logged: false) inspect]}.
stream nextPut: button.! !
!HTMLEruditeDocRenderer methodsFor: 'as yet unclassified' stamp: 'KLG 3/25/2021 21:52:19'!
renderCodeInspectItWithButton: aDocCode
stream nextPut: (Text string: (aDocCode action at: #button)
attributes:
{TextColor magenta.
TextEmphasis italic.
TextEmphasis underlined .
BlockTextAction do: [:anObject | (Compiler evaluate: aDocCode code notifying: anObject textProvider logged: false) inspect]})! !
!HTMLEruditeDocRenderer methodsFor: 'as yet unclassified' stamp: 'KLG 3/25/2021 21:52:19'!
renderCodePrintIt: aDocCode
|text button evalString textModel |
evalString _ aDocCode code.
text _ Text string: aDocCode code. .
textModel _ EruditeSmalltalkTextModel withText: text.
textModel formatAndStyle.
stream nextPut: textModel actualContents.
stream nextPut: ' '.
button _ Text string: '[printIt]'
attributes: {TextEmphasis underlined.
BlockTextAction do: [:anObject | Transcript show: (Compiler evaluate: evalString notifying: anObject textProvider logged: false) printString]}.
stream nextPut: button.! !
!HTMLEruditeDocRenderer methodsFor: 'as yet unclassified' stamp: 'KLG 3/25/2021 21:52:19'!
renderCodePrintItHere: aDocCode
|text evalString result textModel |
evalString _ aDocCode code.
text _ Text string: aDocCode code. .
textModel _ EruditeSmalltalkTextModel withText: text.
textModel formatAndStyle.
stream nextPut: textModel actualContents.
stream nextPut: ' '.
requestor ifNil: [
result _ [Compiler evaluate: evalString for: self logged: false]
on: Error do: [:error | error]]
ifNotNil: [
result _ [Compiler evaluate: evalString notifying: requestor logged: false]
on: Error do: [:error | error]].
stream nextPut: '==> ';
nextPut: (Text streamContents: [:s | result printOn: s]).! !
!HTMLEruditeDocRenderer methodsFor: 'accessing' stamp: 'KLG 3/25/2021 21:57:38'!
book
"Answer the value of book"
^ book! !
!HTMLEruditeDocRenderer methodsFor: 'accessing' stamp: 'KLG 3/25/2021 21:52:19'!
book: aBook
book _ aBook! !
!HTMLEruditeDocRenderer methodsFor: 'accessing' stamp: 'KLG 3/25/2021 21:57:38'!
htmlFilePath
"Answer the value of htmlFilePath"
^ htmlFilePath! !
!HTMLEruditeDocRenderer methodsFor: 'accessing' stamp: 'KLG 3/25/2021 21:57:38'!
htmlFilePath: anObject
"Set the value of htmlFilePath"
htmlFilePath _ anObject! !
!HTMLEruditeDocRenderer methodsFor: 'accessing' stamp: 'KLG 3/25/2021 21:52:19'!
requestor
^ requestor! !
!HTMLEruditeDocRenderer methodsFor: 'accessing' stamp: 'KLG 3/25/2021 21:52:19'!
requestor: anObject
requestor _ anObject! !
!HTMLEruditeDocRenderer methodsFor: 'escaping' stamp: 'KLG 3/29/2021 18:16:41'!
characterToEntityMapping
"Answer the character to entity mapping."
^ self class characterToEntityMapping! !
!HTMLEruditeDocRenderer methodsFor: 'escaping' stamp: 'KLG 3/29/2021 18:15:24'!
escapeHTML: aString
"Basic HTML escape."
^ String streamContents: [ :s |
aString do: [ :character |
self characterToEntityMapping
at: character
ifPresent: [ :replacement | s nextPutAll: replacement ]
ifAbsent: [ s nextPut: character ] ] ]! !
!HTMLEruditeDocRenderer class methodsFor: 'instance creation' stamp: 'KLG 3/25/2021 21:52:19'!
on: aBook
^ self new initialize: aBook! !
!HTMLEruditeDocRenderer class methodsFor: 'rendering' stamp: 'KLG 3/25/2021 21:52:19'!
render: aBook
^ (self on: aBook) render! !
!HTMLEruditeDocRenderer class methodsFor: 'rendering' stamp: 'KLG 3/25/2021 21:52:19'!
render: aBook notifying: anObject
^ (self on: aBook)
requestor: anObject;
render! !
!HTMLEruditeDocRenderer class methodsFor: 'escaping' stamp: 'KLG 3/29/2021 18:10:17'!
characterToEntityMapping
"Answer the character to entity mapping."
^ `#(
($< lt)
($> gt)
($" quot)
($' apos)
($& amp)
($!! excl)
($# num)
($$ dollar)
($% percnt)
($( lpar)
($) rpar)
($* ast)
($+ plus)
($, comma)
($. period)
($/ sol)
($; semi)
($= equals)
($? quest)
($[ lsqb)
($\ bsol)
($] rsqb)
($^ hat)
($_ lobar)
($` grave)
(${ lcub)
($| vert)
($} rcub)
($Š copy)
) collect: [ :pair |
pair first -> ('&', pair second, ';' )] :: asDictionary`! !
!EruditeBookEditorMorph methodsFor: '*EruditeHTML' stamp: 'KLG 3/29/2021 18:19:50'!
explorerMenu
|menu|
menu _ super explorerMenu.
menu add: 'toggle live editing' action: #toggleLiveEditing.
menu lastItem setIcon: Theme current switchIcon.
menu addLine.
menu add: 'export to latex' action: #exportToLatex.
menu lastItem setIcon: Theme current saveIcon.
menu add: 'export to HTML' action: #exportToHTML.
menu lastItem setIcon: Theme current saveIcon.
^ menu! !
!EruditeBookEditorMorph methodsFor: '*EruditeHTML' stamp: 'KLG 3/29/2021 18:23:27'!
exportToHTML
| defaultFilePath |
defaultFilePath _ DirectoryEntry currentDirectory / (model title, '.html').
self request: 'Export to:' initialAnswer: defaultFilePath asString do: [:filePath |
(HTMLEruditeDocRenderer on: model)
htmlFilePath: filePath;
render.
self inform: 'Book exported to HTML']! !
More information about the Cuis-dev
mailing list