677 lines
19 KiB
Smalltalk
677 lines
19 KiB
Smalltalk
"
|
||
I model a Mardeep file as described in https://casual-effects.com/markdeep/
|
||
"
|
||
Class {
|
||
#name : #Markdeep,
|
||
#superclass : #Markdown,
|
||
#instVars : [
|
||
'comments',
|
||
'tail',
|
||
'language',
|
||
'config',
|
||
'head',
|
||
'navTop',
|
||
'options'
|
||
],
|
||
#category : #'MiniDocs-Core'
|
||
}
|
||
|
||
{ #category : #'as yet unclassified' }
|
||
Markdeep class >> fromMarkdownFile: aFileReference [
|
||
^ self new fromMarkdownFile: aFileReference.
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep class >> fromPubPubTOC: orderedDictionary folder: folder index: ordinalPossitive [
|
||
| contentSection testFile |
|
||
contentSection := orderedDictionary associations at: ordinalPossitive.
|
||
testFile := folder / (contentSection key,'--', contentSection value),'md'.
|
||
^ self new fromMarkdownFile: testFile.
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> asMarkdownWithMetadataWrappers [
|
||
^ Markdown new
|
||
metadata: self metadata;
|
||
body: self body;
|
||
file: self markdownFile
|
||
]
|
||
|
||
{ #category : #'instance creation' }
|
||
Markdeep >> authors [
|
||
self metadata at: 'authors' ifAbsentPut: [ Dictionary new ].
|
||
"self metadata at: 'authors' ifNotEmpty: [:k | ^ '**', k, '**' ]
|
||
" ^ ''.
|
||
]
|
||
|
||
{ #category : #'instance creation' }
|
||
Markdeep >> authorsString [
|
||
self authors
|
||
ifEmpty: [ ^ '' ] ifNotEmpty: [ ^ ' ', self authors ]
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> body [
|
||
^ body ifNil: [^ '' ]
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> body: anObject [
|
||
body := anObject
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> bodyReplaceAll: original with: replacement [
|
||
self body: (self body copyReplaceAll: original with: replacement)
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> cleanMetadata [
|
||
metadata := nil
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> commentPubPubDelimiters [
|
||
| commented openners |
|
||
openners := #('::: {.pub-body-component}' '::: pub-body-component' '::: {.editor .Prosemirror}' '::: {.pub-notes}').
|
||
commented := self body.
|
||
openners do: [:openner |
|
||
commented := commented copyReplaceAll: openner with: '<!--@div-open ', openner, '-->'
|
||
].
|
||
commented := commented
|
||
copyReplaceAll: ':::
|
||
' with: '<!--@div-close ::: -->
|
||
'.
|
||
self body: commented
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> comments [
|
||
^ comments ifNil: [ ^ comments := true ]
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> comments: aBoolean [
|
||
"I tell if comments are enabled by default or not."
|
||
comments := aBoolean
|
||
]
|
||
|
||
{ #category : #utilities }
|
||
Markdeep >> commentsProvider [
|
||
"I return the url of the default service that provides annotation support.
|
||
I am used to add such support in the contents of the Markdeep page."
|
||
^ 'https://hypothes.is'
|
||
]
|
||
|
||
{ #category : #utilities }
|
||
Markdeep >> commentsProviderStrings [
|
||
"I associate a comments service provider with the string that is required to be added
|
||
to the document to enable such provider."
|
||
| providers |
|
||
providers := Dictionary new.
|
||
providers at: 'https://hypothes.is' put: '<!-- Hypothesis -->
|
||
<script src="https://hypothes.is/embed.js" async></script>'.
|
||
^ providers
|
||
|
||
|
||
]
|
||
|
||
{ #category : #utilities }
|
||
Markdeep >> commentsSupport [
|
||
"I enable comments of the page."
|
||
|
||
self comments ifFalse: [ ^ self ].
|
||
^ self commentsProviderStrings at: self commentsProvider
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> config [
|
||
| configFile |
|
||
configFile := self folder / 'config.ston'.
|
||
configFile exists ifTrue: [ ^ config := STON fromString: configFile contents ].
|
||
^ config ifNil: [ config := Dictionary new]
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> config: aDictionary [
|
||
|
||
config := aDictionary
|
||
]
|
||
|
||
{ #category : #'instance creation' }
|
||
Markdeep >> contents [
|
||
| output |
|
||
self title ifNil: [ ^ self body ].
|
||
output := '' writeStream.
|
||
output
|
||
nextPutAll: self headContents; lf; lf;
|
||
nextPutAll: ' **', self title trimmed accentedCharactersCorrection, '**'; lf;
|
||
nextPutAll: self authorsString ; lf;
|
||
nextPutAll: '', self version; lf;
|
||
nextPutAll: self navTop; lf; lf;
|
||
nextPutAll: self body; lf; lf;
|
||
nextPutAll: self tail; lf; lf; lf; lf;
|
||
nextPutAll: self commentsSupport.
|
||
^ output contents.
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> converPubPubFootnoteBetween: footnote and: nextFootnote in: footnotesArray [
|
||
| currentNoteIndex nextNoteIndex response noteLines |
|
||
currentNoteIndex := footnotesArray indexOf: '[^',footnote, ']: '.
|
||
nextNoteIndex := footnotesArray indexOf: '[^',nextFootnote, ']: '.
|
||
noteLines := footnotesArray copyFrom: currentNoteIndex to: nextNoteIndex - 1.
|
||
response := '' writeStream.
|
||
noteLines do: [:line |
|
||
line
|
||
ifNotEmpty: [ response nextPutAll: line, String lf ]
|
||
"ifEmpty: [ response nextPutAll: ' ' ]?"
|
||
].
|
||
response nextPutAll: String lf.
|
||
^ response contents
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> extractTitleFrom: docTree [
|
||
| tempTitle |
|
||
tempTitle := ((docTree children
|
||
detect: [ :node | node className = 'PPCMIndentedCode' ]) children
|
||
detect: [ :subnode | subnode text trimmed beginsWith: '**' ]) text trimmed.
|
||
self title: (tempTitle copyFrom: 3 to: tempTitle size - 2).
|
||
^ tempTitle
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> extractYamlMetadataFrom: documentTree [
|
||
| yamlComment response |
|
||
yamlComment := documentTree children
|
||
detect: [:node | node className = 'PPCMHtmlBlock' and: [node text trimmed beginsWith: '<!--@yaml']]
|
||
ifNone: [ ^ nil ].
|
||
response := '' writeStream.
|
||
yamlComment children allButFirst allButLast do: [:each |
|
||
response nextPutAll: each text; cr
|
||
].
|
||
^ {YAML2JSON fromString: response contents . yamlComment }
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> file: aFileReference [
|
||
file := aFileReference.
|
||
self fillInContentsFrom: aFileReference
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> fillInContentsFrom: aFileReference [
|
||
| docTree docTreeChildren headTree bodyStartLine bodyEndLine contentLines rawMetadata |
|
||
aFileReference exists ifFalse: [ ^ self ].
|
||
docTree := (Markdown new contents: aFileReference contents) documentTree.
|
||
docTreeChildren := docTree children.
|
||
headTree := docTreeChildren
|
||
detect: [ :node |
|
||
node className = 'PPCMParagraph'
|
||
and: [ (node children detect: [ :subnode | subnode text = '<head>' ]) isNotNil ] ]
|
||
ifNone: [ ^self ].
|
||
headTree children allButFirst allButLast
|
||
do: [ :node | node className = 'PPCMHtml' ifTrue: [ self head add: node text ] ].
|
||
self head: self head asSet asOrderedCollection.
|
||
rawMetadata := (self extractYamlMetadataFrom: docTree).
|
||
rawMetadata ifNotNil: [self metadata: rawMetadata first].
|
||
self title ifNil: [
|
||
self title: (self metadata at: 'title' ifAbsent: [self extractTitleFrom: docTree]).
|
||
self title: (self title trimBoth: [ :char | char = $" ]).
|
||
self metadata at: 'title' put: self title].
|
||
contentLines := self file contents lines.
|
||
bodyStartLine := (contentLines
|
||
detectIndex: [ :line | line includesSubstring: '<!--@yaml' ] ifNone: [ ^ self ]) + rawMetadata second children size.
|
||
bodyEndLine := contentLines detectIndex: [:line | line includesSubstring: '<!-- Markdeep'] ifNone: [ 0 ].
|
||
self body: (contentLines copyFrom: bodyStartLine to: bodyEndLine - 1 ) asStringWithCr.
|
||
^ self .
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> folder [
|
||
^ self file parent
|
||
]
|
||
|
||
{ #category : #utilities }
|
||
Markdeep >> fontAwesomeHeader [
|
||
"I enable the font awesome support in the document header"
|
||
|
||
^ '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">'
|
||
]
|
||
|
||
{ #category : #'instance creation' }
|
||
Markdeep >> fromMarkdownFile: aFileReference [
|
||
"I create a Markdeep document from a given Markdown file."
|
||
self processMarkdownFor: aFileReference.
|
||
self file: aFileReference, 'html'.
|
||
^ self.
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> fromPubPubToMarkdeep [
|
||
self
|
||
removeAutoGeneratedFileNotice;
|
||
removeCCByLicenseDiv;
|
||
commentPubPubDelimiters;
|
||
replaceEscapedCharacters;
|
||
renamePubPubFootnotes;
|
||
removeAlternativeImagesArray
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> gtTextFor: aView [
|
||
<gtView>
|
||
^ aView textEditor
|
||
title: 'Text';
|
||
text: [ self contents ]
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> head [
|
||
|
||
^ head ifNil: [
|
||
head := OrderedCollection new.
|
||
head add: self fontAwesomeHeader; yourself.
|
||
].
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> head: anOrderedCollection [
|
||
head := anOrderedCollection
|
||
]
|
||
|
||
{ #category : #'instance creation' }
|
||
Markdeep >> headContents [
|
||
|
||
^ String streamContents: [ :stream |
|
||
stream
|
||
nextPutAll: '<head>';
|
||
nextPut: Character lf.
|
||
self head do: [ :line |
|
||
stream
|
||
nextPutAll: ' ';
|
||
nextPutAll: line;
|
||
nextPut: Character lf
|
||
].
|
||
self metadata keysAndValuesDo: [:k :v |
|
||
k = 'lang'
|
||
ifTrue: [ stream nextPutAll: ' <meta lang="', v,'">'; cr. ]
|
||
ifFalse: [ stream nextPutAll: ' <meta name="', k, '" content="', v,'">'; cr. ]
|
||
].
|
||
stream
|
||
nextPutAll: '</head>';
|
||
nextPut: Character lf.
|
||
].
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> language [
|
||
^ language
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> language: anObject [
|
||
language := anObject
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> markdeepScriptTag [
|
||
^ '<script src="markdeep.min.js" charset="utf-8"></script>
|
||
<script
|
||
src="https://casual-effects.com/markdeep/latest/markdeep.min.js?"
|
||
charset="utf-8">
|
||
</script>'
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> markdownFile [
|
||
self file ifNil: [
|
||
self file: FileLocator temp / ('untitled--', NanoID generate, '.md.html') ].
|
||
^ (self file fullName withoutSuffix: '.html') asFileReference.
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> markdownFile: aFileReference [
|
||
"Where the Mardown file associated with me is stored. Used for sync. and import/export purposes."
|
||
self file: aFileReference, 'html'
|
||
]
|
||
|
||
{ #category : #'instance creation' }
|
||
Markdeep >> metadata [
|
||
metadata ifNil: [^ metadata := OrderedDictionary new ].
|
||
(metadata isNil and: [ self file contents isNil ])
|
||
ifTrue: [ metadata := OrderedDictionary new ].
|
||
^ metadata
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> metadata: anOrderedDictionary [
|
||
metadata := anOrderedDictionary
|
||
]
|
||
|
||
{ #category : #utilities }
|
||
Markdeep >> metadataFromXML: aXMLDocument [
|
||
| metaDict |
|
||
|
||
metaDict := OrderedDictionary new.
|
||
(aXMLDocument xpath: '//meta') do: [ :each |
|
||
metaDict at: (each @ 'name') stringValue put: (each @ 'content') stringValue ].
|
||
^ metaDict
|
||
]
|
||
|
||
{ #category : #'instance creation' }
|
||
Markdeep >> navTop [
|
||
^ navTop ifNil: [ navTop := '' ]
|
||
]
|
||
|
||
{ #category : #'as yet unclassified' }
|
||
Markdeep >> navTop: aString [
|
||
navTop:= aString.
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> options [
|
||
^ options ifNil: [
|
||
"Setting defaults accoding to: https://casual-effects.com/markdeep/#api"
|
||
options := Dictionary new
|
||
at: 'mode' put: nil;
|
||
at: 'lang' put: nil;
|
||
at: 'tocStyle' put: 'auto';
|
||
at: 'autoLinkImages' put: true;
|
||
yourself
|
||
]
|
||
]
|
||
|
||
{ #category : #'instance creation' }
|
||
Markdeep >> processMarkdownFor: aFileReference [
|
||
"comment stating purpose of message"
|
||
| markdownContent |
|
||
self file: aFileReference, 'html'.
|
||
markdownContent := Markdown fromFile: aFileReference.
|
||
self metadata: markdownContent metadataAsYAML.
|
||
self body: (markdownContent commentYAMLMetadata contents).
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> pubPubFootnoteMetadataFromString: string [
|
||
| sanitized footnoteData altLine altString id |
|
||
(string lines size <= 1) ifTrue: [ ^ nil ].
|
||
sanitized := '' writeStream.
|
||
altString := string copyReplaceAll: '.footnote' with: ''.
|
||
altString := altString copyReplaceAll: ' node-type='
|
||
with: '
|
||
node-type= '.
|
||
altString := altString copyReplaceAll: ' data-value=' with: '
|
||
data-value='.
|
||
altString := altString copyReplaceAll: ' date-structured-value=' with: '
|
||
date-structured-value= '.
|
||
altString lines allButFirstDo: [:line |
|
||
(line beginsWith: '>')
|
||
ifTrue: [ altLine := line allButFirst ]
|
||
ifFalse: [ altLine := line ].
|
||
sanitized
|
||
nextPutAll: altLine trimBoth;
|
||
nextPutAll: String lf
|
||
].
|
||
sanitized := sanitized contents.
|
||
sanitized := sanitized copyReplaceAll: 'type=' with: 'type: '.
|
||
sanitized := sanitized copyReplaceAll: 'value=' with: 'value: '.
|
||
id := (altString lines first) allButFirst trimmed.
|
||
footnoteData := { 'id' -> id } asDictionary.
|
||
footnoteData addAll: (MiniDocs yamlToJson: sanitized trimmed).
|
||
^ footnoteData
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> pubPubFootnoteRawLinks [
|
||
^ self selectPubPubLinksWithSize: 2
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> pubPubFootnotesLinesRangeFor: contentSection [
|
||
| beginningLine endingLine |
|
||
beginningLine := contentSection lines size + 1.
|
||
contentSection lines doWithIndex: [:line :i |
|
||
((line includesSubstring: '::: {.pub-notes}') or: [line includesSubstring: '::: pub-notes'])
|
||
ifTrue: [ beginningLine := i ].
|
||
(i > beginningLine and: [ line beginsWith: ':::' ])
|
||
ifTrue: [
|
||
endingLine := i.
|
||
^ {beginningLine . endingLine}
|
||
]
|
||
]
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> pubPubFootnotesLinesRangeForBody [
|
||
^ self pubPubFootnotesLinesRangeFor: self body
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> pubPubFootnotesLinesRangeForContents [
|
||
^ self pubPubFootnotesLinesRangeFor: self contents
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> pubPubFootnotesText [
|
||
| footnotesLines output |
|
||
footnotesLines := self contents lines
|
||
copyFrom: self pubPubFootnotesLinesRangeForContents first + 3
|
||
to: self pubPubFootnotesLinesRangeForContents second - 1.
|
||
output := '' writeStream.
|
||
footnotesLines do: [:line |
|
||
output
|
||
nextPutAll: line;
|
||
nextPutAll: String crlf.
|
||
].
|
||
^ output contents allButLast
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> pubPubImageLinks [
|
||
^ self selectPubPubLinksWithSize: 3
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> pubPubImagesToMarkdeep [
|
||
| sanitized parsedLinks |
|
||
|
||
parsedLinks := self pubPubImageLinks.
|
||
parsedLinks ifEmpty: [ ^self ].
|
||
sanitized := self body.
|
||
parsedLinks do: [:link |
|
||
sanitized := sanitized copyReplaceAll: '{', link third, '}' with: ''
|
||
].
|
||
self body: sanitized
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> pubPubRawLinks [
|
||
| parser |
|
||
parser := PubPubGrammar2 new document.
|
||
^ (parser parse: self body)
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> reformatPubPubFootnotes [
|
||
| footnotesLines footnotesIDs toReplace response |
|
||
(self = self pubPubFootnotesLinesRangeForContents)
|
||
ifTrue: [^self].
|
||
footnotesLines := self contents lines
|
||
copyFrom: self pubPubFootnotesLinesRangeForContents first
|
||
to: self pubPubFootnotesLinesRangeForContents second.
|
||
footnotesIDs := self replacePubPubFootnotesIdentifiers.
|
||
toReplace := footnotesLines select: [:line |
|
||
(line includesSubstring: ' [[]{.pub-note-content-component}]{#fn-')
|
||
].
|
||
toReplace doWithIndex: [:replacement :i | | index |
|
||
index := footnotesLines indexOf: replacement.
|
||
footnotesLines at: index put: '[^', (footnotesIDs at: i),']: '
|
||
].
|
||
response := '' writeStream.
|
||
footnotesIDs allButLast doWithIndex: [:footnote :i |
|
||
response
|
||
nextPutAll:
|
||
(self
|
||
converPubPubFootnoteBetween: footnote
|
||
and: (footnotesIDs at: i + 1)
|
||
in: footnotesLines)
|
||
].
|
||
^ response contents
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> removeAlternativeImagesArray [
|
||
| replacements |
|
||
self body ifNil: [^ self].
|
||
replacements := self selectPubPubLinksWithSize: 3.
|
||
replacements ifEmpty: [^self].
|
||
replacements do: [:replacement |
|
||
self body:
|
||
(self body copyReplaceAll: replacement third with: '' )
|
||
].
|
||
self body: (self body copyReplaceAll: '{srcset=}' with: '').
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> removeAutoGeneratedFileNotice [
|
||
| autoGeneratedNotice |
|
||
autoGeneratedNotice := '**Notice:** This file is an auto-generated download and, as such, might
|
||
include minor display or rendering errors. For the version of record,
|
||
please visit the HTML version or download the PDF.
|
||
|
||
------------------------------------------------------------------------'.
|
||
self body: (self body copyReplaceAll: autoGeneratedNotice with: '')
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> removeCCByLicenseDiv [
|
||
| licenseDiv|
|
||
licenseDiv := '
|
||
<div>
|
||
|
||
**License:** [Creative Commons Attribution 4.0 International License
|
||
(CC-BY 4.0)](https://creativecommons.org/licenses/by/4.0/)
|
||
|
||
</div>'.
|
||
self body: (self body copyReplaceAll: licenseDiv with: '')
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> renamePubPubFootnotes [
|
||
| reformated bodyLines beforeFootnotes afterFootnotesRaw afterFootnotes newBodyLines response |
|
||
reformated := self reformatPubPubFootnotes.
|
||
(self pubPubFootnotesLinesRangeForBody class = Markdeep) ifTrue: [ ^self ].
|
||
bodyLines := self body lines.
|
||
beforeFootnotes := bodyLines copyFrom: 1 to: self pubPubFootnotesLinesRangeForBody first .
|
||
afterFootnotesRaw := bodyLines copyFrom: self pubPubFootnotesLinesRangeForBody second to: bodyLines size.
|
||
afterFootnotes := OrderedCollection new.
|
||
afterFootnotesRaw do:[:line |
|
||
(line beginsWith: ':::')
|
||
ifTrue: [
|
||
afterFootnotes
|
||
add: (line copyReplaceAll: ':::' with: '<!--@div-closer ::: -->').
|
||
]
|
||
].
|
||
newBodyLines :=
|
||
(beforeFootnotes copyWithAll:
|
||
(#('# Footnotes' '')
|
||
copyWithAll:(reformated lines
|
||
copyWithAll: afterFootnotes))).
|
||
response := '' writeStream.
|
||
newBodyLines do: [:line |
|
||
response nextPutAll: line, String lf
|
||
].
|
||
self body: response contents.
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> replaceBackslashBreaklines [
|
||
self bodyReplaceAll: '\
|
||
' with: '<br>
|
||
'
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> replaceEscapedCharacters [
|
||
self
|
||
title: (self title copyReplaceAll: '\#' with: '#');
|
||
body: (self body copyReplaceAll: '\#' with: '#');
|
||
body: (self body copyReplaceAll: '\[' with: '[');
|
||
body: (self body copyReplaceAll: '\]' with: ']');
|
||
body: (self body copyReplaceAll: '\*' with: '*')
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> replacePubPubFootnotesIdentifiers [
|
||
| footnotes sanitized parsedLinks linkIdentifiers |
|
||
footnotes := OrderedDictionary new.
|
||
parsedLinks := self pubPubFootnoteRawLinks.
|
||
parsedLinks ifEmpty: [ ^self ].
|
||
sanitized := self body.
|
||
linkIdentifiers := OrderedCollection new.
|
||
parsedLinks do: [:link | | id currentLinkText |
|
||
id := (link second splitOn: '.footnote') first trimmed.
|
||
linkIdentifiers add: id.
|
||
currentLinkText := '[', link first, ']{#',link second,'}'.
|
||
sanitized := sanitized copyReplaceAll: currentLinkText with: '[^', id, ']'
|
||
].
|
||
self body: sanitized.
|
||
^ linkIdentifiers
|
||
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> selectPubPubLinksWithSize: naturalNumber [
|
||
^ self pubPubRawLinks select: [ :each | each size = naturalNumber ]
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> tail [
|
||
"I enable the document tail, which, in turn, enables a Markdeep document"
|
||
| output |
|
||
output := '' writeStream.
|
||
output
|
||
nextPutAll: '<!-- Markdeep: -->'; lf; lf;
|
||
nextPutAll: '<style class="fallback">body{visibility:hidden;white-space:pre;font-family:monospace}</style>'; lf;
|
||
nextPutAll: '<script>window.markdeepOptions = {tocStyle: "', self tocStyle,'"}</script>'; lf;
|
||
nextPutAll: self markdeepScriptTag; lf;
|
||
nextPutAll: '<!--<script>window.alreadyProcessedMarkdeep||(document.body.style.visibility="visible")</script>-->'.
|
||
^ output contents
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> tail: anObject [
|
||
tail := anObject
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> title [
|
||
|
||
^ title
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> title: anObject [
|
||
|
||
title := anObject
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> tocStyle [
|
||
^ self options at: 'tocStyle' ifAbsent: [ 'short' ]
|
||
]
|
||
|
||
{ #category : #accessing }
|
||
Markdeep >> tocStyle: aString [
|
||
"A string can be: 'auto' 'none' 'short' 'medium' or 'long'"
|
||
self options at: 'tocStyle' put: aString
|
||
]
|
||
|
||
{ #category : #'instance creation' }
|
||
Markdeep >> version [
|
||
self metadata at: 'version' ifPresent: [:value | ^ 'v',value ].
|
||
^ ''
|
||
]
|