" 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 : #'Grafoscopio-Utils' } { #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 locateYAMLMetadataClosing + 2 to: self lines size) do: [ :line | newContents nextPutAll: line; crlf ]. self contents: newContents contents. ^ self contents ] { #category : #utilities } Markdown >> containsYAMLMetadataClosing [ ^ self locateYAMLMetadataClosing > 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 yamlMetadataAsString. ^ exportedFile ] { #category : #operation } Markdown >> extractYAMLMetadata [ self detectYAMLMetadata ifFalse: [ ^ nil ]. ^ self lines copyFrom: 2 to: (self locateYAMLMetadataClosing) ] { #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 : #utilities } Markdown >> lines [ ^ self contents lines. ] { #category : #utilities } Markdown >> locateYAMLMetadataClosing [ "I return the line where the closing of the YAML metadata occurs or 0 if no closing is found." | result | self startsWithYAMLMetadataDelimiter ifFalse: [ ^ self ]. result := 0. self lines allButFirst doWithIndex: [ :currentLine :i | (currentLine beginsWith: self class yamlMetadataDelimiter) ifTrue: [ result := i ]]. ^ result ] { #category : #accessing } Markdown >> metadata [ self exportMetadataAsJson. ^ NeoJSONReader fromString: FileLocator temp / 'metadata.json' contents. ] { #category : #utilities } Markdown >> startsWithYAMLMetadataDelimiter [ ^ self lines first beginsWith: self class yamlMetadataDelimiter ] { #category : #utilities } Markdown >> yamlMetadataAsString [ | output | self extractYAMLMetadata ifNil: [ ^ nil ]. output := String new writeStream. output nextPutAll: self class yamlMetadataDelimiter; cr. self extractYAMLMetadata do: [ :line | output nextPutAll: line; cr. ]. output nextPutAll: self class yamlMetadataDelimiter; cr. ^ output contents. ]