" I model a Markdown document. At some point the idea is to have a full native parser implemented to deal with my syntax, but meanwhile I will be collaborating with external parsers, particularly the ones provided by Pandoc and/or Lunamark. " Class { #name : #Markdown, #superclass : #Object, #instVars : [ 'contents', 'file' ], #category : #MiniDocs } { #category : #'instance creation' } Markdown class >> fromFile: aFileReference [ ^ self new fromFile: aFileReference ] { #category : #utilities } Markdown class >> yamlMetadataDelimiter [ ^ '---' ] { #category : #operation } Markdown >> commentYAMLMetadata [ | newContents | self detectYAMLMetadata ifFalse: [ ^ self ]. newContents := '' writeStream. newContents nextPutAll: ''; crlf. (self lines copyFrom: self yamlMetadataClosingLineNumber + 2 to: self lines size) do: [ :line | newContents nextPutAll: line; crlf ]. ^ newContents contents. ] { #category : #utilities } Markdown >> containsYAMLMetadataClosing [ ^ self yamlMetadataClosingLineNumber > 0 ] { #category : #accessing } Markdown >> contents [ ^ contents ] { #category : #accessing } Markdown >> contents: anObject [ contents := anObject ] { #category : #utilities } Markdown >> detectYAMLMetadata [ | lines | lines := self lines. ^ self startsWithYAMLMetadataDelimiter and: [ lines allButFirst detect: [ :currentLine | currentLine beginsWith: self class yamlMetadataDelimiter ] ifFound: [ ^ true ] ifNone: [ ^ false ] ] ] { #category : #operation } Markdown >> exportMetadataAsJson [ "TBD: Lua scripts should be checked and installed when missing. Maybe a shared location in '.local/share/Grafoscopio/Scripts' should be developed in the near future." | output luaScript | luaScript := FileLocator home / '.local/share/Brea/scripts/meta-to-json.lua'. Smalltalk platformName = 'unix' ifTrue: [ OSSUnixSubprocess new workingDirectory: self file parent fullName; command: 'pandoc'; arguments: { '--lua-filter=', luaScript fullName . self file basename }; redirectStdout; redirectStdin; runAndWaitOnExitDo: [ :process :outString :errString | output := process isSuccess ifTrue: [ outString ] ifFalse: [ errString ] ]]. ^ output correctAccentedCharacters ] { #category : #operation } Markdown >> exportMetadataAsYaml [ | exportedFile | exportedFile := FileLocator temp / 'metadata.yaml'. MarkupFile exportAsFileOn: exportedFile containing: self yamlMetadataStringWithDelimiters. ^ exportedFile ] { #category : #accessing } Markdown >> file [ ^ file ] { #category : #accessing } Markdown >> file: aFileReference [ "I store the origen/destination of the Markdown contents." file := aFileReference ] { #category : #'instance creation' } Markdown >> fromFile: aFileReference [ self contents: aFileReference contents. self file: aFileReference. ] { #category : #'instance creation' } Markdown >> fromString: markdownString [ self contents: markdownString. ] { #category : #accessing } Markdown >> gtTextFor: aView [ ^ aView textEditor title: 'Text'; text: [ self contents ] ] { #category : #utilities } Markdown >> lines [ ^ self contents lines. ] { #category : #accessing } Markdown >> metadata [ | rawMeta | rawMeta := MiniDocs yamlToJson: self yamlMetadataString. rawMeta associationsDo: [ :assoc | assoc value = 'false' ifTrue: [ assoc value: false ]. assoc value = 'true' ifTrue: [ assoc value: true ] ]. ^ rawMeta ] { #category : #accessing } Markdown >> printOn: aStream [ super printOn: aStream. aStream nextPutAll: '( ', (self metadata at: 'title' ifAbsent: ['untitled']), ' )' ] { #category : #utilities } Markdown >> startsWithYAMLMetadataDelimiter [ ^ self lines first beginsWith: self class yamlMetadataDelimiter ] { #category : #accessing } Markdown >> yamlMetadata [ ^ MiniDocs yamlToJson: self yamlMetadataString ] { #category : #utilities } Markdown >> yamlMetadataClosingLineNumber [ "I return the line where the closing of the YAML metadata occurs or 0 if no closing is found." self startsWithYAMLMetadataDelimiter ifFalse: [ ^ self ]. self lines allButFirst doWithIndex: [ :currentLine :i | (currentLine beginsWith: self class yamlMetadataDelimiter) ifTrue: [ ^ i + 1 ]] ] { #category : #operation } Markdown >> yamlMetadataString [ | output yamlLines | self detectYAMLMetadata ifFalse: [ ^ nil ]. yamlLines := self lines copyFrom: 2 to: self yamlMetadataClosingLineNumber - 1. output := '' writeStream. yamlLines do: [ :line | output nextPutAll: line; nextPut: Character cr. ]. ^ output contents ] { #category : #utilities } Markdown >> yamlMetadataStringWithDelimiters [ | output | self yamlMetadataString ifNil: [ ^ nil ]. output := String new writeStream. output nextPutAll: self class yamlMetadataDelimiter; cr. output nextPutAll: self yamlMetadataString. output nextPutAll: self class yamlMetadataDelimiter; cr. ^ output contents. ]