Extension { #name : #LePage } { #category : #'*MiniDocs' } LePage >> asHtmlFile [ self asMarkdownFile. self defaultPandocTemplate exists ifFalse: [ MarkupFile installTemplate: 'https://mutabit.com/repos.fossil/mutabit/doc/trunk/plantillas/Pandoc/clean-menu-mod.html' into: self defaultPandocTemplate parent ]. OSSUnixSubprocess new command: 'pandoc' ; arguments: { self markdownFileName. '-o'. self htmlFileName . '--toc' . '--template=', self defaultPandocTemplate basenameWithoutExtension }; workingDirectory: self storage fullName; runAndWaitOnExitDo: [ :process :outString | ^ self storage / self htmlFileName]. ] { #category : #'*MiniDocs' } LePage >> asMarkdeep [ | bodyStream markdeep | bodyStream := '' writeStream. self preorderTraversal do: [ :snippet | bodyStream nextPutAll: snippet asMarkdeep ]. markdeep := Markdeep new title: self title; body: bodyStream contents; file: self storage / self markdeepFileName; navTop: self navTop. "self exportMetadataToHead: markdeep." self metadata at: 'authors' ifPresent: [ :author | markdeep metadata at: 'authors' put: author ]. self metadata at: 'version' ifPresent: [ :version | markdeep metadata at: 'version' put: version ]. ^ markdeep ] { #category : #'*MiniDocs' } LePage >> asMarkdeepFile [ ^ self asMarkdeep notifyExportAsFileOn: self storage / self markdeepFileName ] { #category : #'*MiniDocs' } LePage >> asMarkdown [ | bodyStream markdown | bodyStream := '' writeStream. bodyStream nextPutAll: '---'; nextPutAll: String lf. self metadata keysAndValuesDo: [ :k :v | bodyStream nextPutAll: k , ': "' , v, '"'; nextPutAll: String lf ]. bodyStream nextPutAll: '---' , String lf , String lf, String lf. bodyStream nextPutAll: '# ', self title, String lf , String lf. self preorderTraversal do: [ :snippet | bodyStream nextPutAll: snippet asMarkdown ]. markdown := Markdown new contents: bodyStream contents. ^ markdown ] { #category : #'*MiniDocs' } LePage >> asMarkdownFile [ | folder | folder := self storage. ^ MarkupFile exportAsFileOn: folder / self markdownFileName containing: self asMarkdown contents ] { #category : #'*MiniDocs' } LePage >> config [ | configFile | configFile := self storage / 'config.ston'. configFile exists ifTrue: [^ STON fromString: configFile contents ] ifFalse: [ ^ nil ] ] { #category : #'*MiniDocs' } LePage >> defaultPandocTemplate [ ^ FileLocator home / '.pandoc' / 'templates' / 'clean-menu-mod.html' ] { #category : #'*MiniDocs' } LePage >> detectParentSnippetWithUid: uidString [ uidString = self uid asString36 ifTrue: [ ^ self ]. ^ self preorderTraversal detect: [ :snippet | snippet uidString = uidString ] ] { #category : #'*MiniDocs' } LePage >> exportMetadataToHead: markdeep [ self metadata keysAndValuesDo: [ :k :v | k = 'lang' ifTrue: [ markdeep head add: ''; yourself ] ifFalse: [ markdeep head add: ''; yourself ] ] ] { #category : #'*MiniDocs' } LePage >> exportedFileName [ | sanitized | sanitized := self title asDashedLowercase romanizeAccents copyWithoutAll: #($/ $: $🢒). ^ sanitized , '--' , (self uidString copyFrom: 1 to: 5) ] { #category : #'*MiniDocs' } LePage >> fromMarkdeepUrl: aString [ | docTree pageMetadata | docTree := GrafoscopioUtils xmlFromUrl: aString. pageMetadata := Markdeep new metadataFromXML: docTree. self basicUid: (pageMetadata at: 'id'); title: (pageMetadata at: 'title'); createTime: (pageMetadata at: 'created') asDateAndTime; editTime: (pageMetadata at: 'modified') asDateAndTime; createEmail: (pageMetadata at: 'creator'); editEmail: (pageMetadata at: 'modifier'); optionAt: 'metadata' put: pageMetadata. self populateChildrenFrom: (docTree xpath: '//div') ] { #category : #'*MiniDocs' } LePage >> htmlFileName [ ^ self exportedFileName, '.html' ] { #category : #'*MiniDocs' } LePage >> latestEditTime: aLeTime [ "Used for adding a LePage to database from a shared markdeep LePage version." latestEditTime := aLeTime ] { #category : #'*MiniDocs' } LePage >> localHostAddress [ | localUrl route | MiniDocsServer teapot server isRunning ifFalse: [ MiniDocsServer restart ]. route := MiniDocsServer teapot staticRouter prefix joinUsing: '/'. localUrl := MiniDocsServer teapot server localUrl asString. ^ localUrl, route, '/', self markdeepFileName ] { #category : #'*MiniDocs' } LePage >> markdeepFileName [ ^ self markdownFileName , '.html' ] { #category : #'*MiniDocs' } LePage >> markdownFileName [ ^ self exportedFileName, '.md' ] { #category : #'*MiniDocs' } LePage >> metadata [ ^ self options at: 'metadata' ifAbsentPut: [ self metadataUpdate] ] { #category : #'*MiniDocs' } LePage >> metadataUpdate [ ^ OrderedDictionary new at: 'id' put: self uidString; at: 'title' put: self contentAsString; at: 'created' put: self createTime greaseString; at: 'modified' put: self latestEditTime greaseString; at: 'creator' put: self createEmail greaseString; at: 'modifier' put: self editEmail greaseString; yourself ] { #category : #'*MiniDocs' } LePage >> navTop [ | topNavFile | topNavFile := self storage / '_navtop.html'. topNavFile exists ifFalse: [ ^ '' ] ifTrue: [ ^ topNavFile contents ] ] { #category : #'*MiniDocs' } LePage >> options [ ^ options ] { #category : #'*MiniDocs' } LePage >> preorderTraversal [ ^ self allChildrenDepthFirst ] { #category : #'*MiniDocs' } LePage >> removeSnippetsMetadata [ self preorderTraversal do: [ :snippet | (snippet options isNotNil and: [ snippet options includesKey: 'metadata' ]) ifTrue: [ snippet options removeKey: 'metadata' ] ] ] { #category : #'*MiniDocs' } LePage >> sanitizeMetadata [ self allChildrenDepthFirst do: [:snippet | snippet sanitizeMetadata ] ] { #category : #'*MiniDocs' } LePage >> sharedVariablesBindings [ | codeSnippets shared | codeSnippets := self preorderTraversal select: [:snippet | snippet class = LePharoSnippet and: [ snippet code includesSubstring: ':='] ]. codeSnippets first in: [:snippet | | context | context := snippet coder evaluationContext. snippet coder doItInContext: context. shared := context bindingStrategy bindings detect: [:each | each isKindOf: GtSharedVariablesBindings ] ]. codeSnippets asArray allButFirstDo: [:snippet| | context| context := snippet coder evaluationContext. context addBindings: shared. snippet coder doItInContext: context ]. ^ shared asDictionary ] { #category : #'*MiniDocs' } LePage >> storage [ | current | current := self database attachmentsDirectory parent. self optionAt: 'storage' ifAbsent: [ ^ current ]. (self optionAt: 'storage') ifNil: [ ^ current ]. ^ self optionAt: 'storage' ] { #category : #'*MiniDocs' } LePage >> uiAddCopyButtonFor: anAction [ ^ anAction button tooltip: 'Export Page'; icon: BrGlamorousVectorIcons changes; action: [:aButton | aButton phlow spawnObject: (self page database addPageCopy: self page) ] ] { #category : #'*MiniDocs' } LePage >> uiDefineFolderFor: anAction [ | folderButton | folderButton := anAction dropdown icon: BrGlamorousIcons savetodisk; tooltip: 'Export folder'""; content: [:aButton | BlElement new background: (Color gray alpha: 0.2); size: 100 @ 100; margin: (BlInsets all: 10) ]. ^ folderButton ] { #category : #'*MiniDocs' } LePage >> uiExportButtonFor: anAction [ ^ anAction button tooltip: 'Export Page'; icon: BrGlamorousVectorIcons down; action: [:aButton | aButton phlow spawnObject: self page asMarkdeepFile ] ] { #category : #'*MiniDocs' } LePage >> uiRefreshWebPreviewButtonFor: anAction [ ^ anAction button tooltip: 'Refresh web view'; icon: BrGlamorousVectorIcons refresh; action: [ self page asMarkdeep exportAsFileOn: (self page storage / self page markdeepFileName). GoogleChrome openWindowOn: self page localHostAddress. "TODO: If Chrome/Chromium are not installed, I should execute:" "WebBrowser openOn: self page localHostAddress" ] ]