diff --git a/repository/Brea-Tests/BreaPageTest.class.st b/repository/Brea-Tests/BreaPageTest.class.st index a6a5485..5e38b9c 100644 --- a/repository/Brea-Tests/BreaPageTest.class.st +++ b/repository/Brea-Tests/BreaPageTest.class.st @@ -1,203 +1,203 @@ -" -A BreaPageTest is a test class for testing the behavior of BreaPage -" -Class { - #name : #BreaPageTest, - #superclass : #TestCase, - #category : #'Brea-Tests' -} - -{ #category : #initialization } -BreaPageTest >> createHTMLTemplateFile [ - | testFile contents | - testFile := FileLocator temp / 'template.mus.html'. - testFile ensureCreateFile. - contents := -' - -
- - -- {{#show}} You should see me. {{/show}} -
-- {{#unhide}} You should not see me. {{/unhide}} -
- {{{ contents }}} - -'. - - MarkupFile exportAsFileOn: testFile containing: contents. - -] - -{ #category : #initialization } -BreaPageTest >> createJSONFile [ - | testFile contents | - testFile := self jsonTestFile. - testFile ensureCreateFile. - contents := '{ "title": "This is a test", "show": true, "unhide": false }'. - MarkupFile exportAsFileOn: testFile containing: contents. - -] - -{ #category : #initialization } -BreaPageTest >> createMarkdownFile [ - | testFile contents | - testFile := self markdownTestFile. - testFile ensureCreateFile. - contents := -'--- -title: This is a test -show: true -unhide: false - ---- - -# Level one header - -And paragraph contents with _emphasis_ and **strong emphasis**.'. - - MarkupFile exportAsFileOn: testFile containing: contents. - -] - -{ #category : #'as yet unclassified' } -BreaPageTest >> htmlBodyContents [ - ^ 'And paragraph contents with emphasis and strong emphasis.
-' -] - -{ #category : #'as yet unclassified' } -BreaPageTest >> htmlOutput [ - ^ ' - - - - -- You should see me. -
-- -
- ', self htmlBodyContents, -' - -' -] - -{ #category : #'as yet unclassified' } -BreaPageTest >> jsonTestFile [ - ^ FileLocator temp / 'test1.json'. -] - -{ #category : #'as yet unclassified' } -BreaPageTest >> markdownTestFile [ - ^ FileLocator temp / 'test.md'. -] - -{ #category : #'as yet unclassified' } -BreaPageTest >> setUp [ - "I create disposable simple files for testing purposes." - super setUp. - self createMarkdownFile. - self createHTMLTemplateFile. -] - -{ #category : #tests } -BreaPageTest >> testJSONMetadataExtraction [ - - | page testMetadata | - testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. - page := BreaPage new. - page - shortName: 'test1'; - folder: FileLocator temp. - self assert: page metadata equals: testMetadata -] - -{ #category : #tests } -BreaPageTest >> testJSONPopulateMetadata [ - - | page testMetadata | - testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. - page := BreaPage new. - page - shortName: 'test1'; - folder: FileLocator temp. - page templateData at: 'extra' put: 'value'. - self assert: page populateMetadata equals: (testMetadata at: 'extra' put: 'value'; yourself) -] - -{ #category : #tests } -BreaPageTest >> testMarkdownContentExtraction [ - - | page | - page := BreaPage new. - page - shortName: 'test'; - folder: FileLocator temp. - self assert: page contents equals: self markdownTestFile contents. -] - -{ #category : #tests } -BreaPageTest >> testMarkdownHTMLExport [ - - | page | - page := BreaPage new. - page - shortName: 'test'; - folder: FileLocator temp; - template: 'template.mus.html'; - bodyTag: 'contents'. - self assert: (page exportAsHTML contents) equals: self htmlOutput. -] - -{ #category : #tests } -BreaPageTest >> testMarkdownMetadataExtraction [ - - | page testMetadata | - testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. - page := BreaPage new. - page - shortName: 'test'; - folder: FileLocator temp. - self assert: page metadata equals: testMetadata -] - -{ #category : #tests } -BreaPageTest >> testMarkdownPopulateBody [ - - | page | - page := BreaPage new. - page - shortName: 'test'; - folder: FileLocator temp; - bodyTag: 'contents'. - page populateTaggedBody. - self assert: (page templateData at: 'contents') equals: self htmlBodyContents. -] - -{ #category : #tests } -BreaPageTest >> testMarkdownPopulateMetadata [ - - | page testMetadata | - testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. - page := BreaPage new. - page - shortName: 'test'; - folder: FileLocator temp. - page templateData at: 'extra' put: 'value'. - self assert: page populateMetadata equals: (testMetadata at: 'extra' put: 'value'; yourself) -] +" +A BreaPageTest is a test class for testing the behavior of BreaPage +" +Class { + #name : #BreaPageTest, + #superclass : #TestCase, + #category : #'Brea-Tests' +} + +{ #category : #initialization } +BreaPageTest >> createHTMLTemplateFile [ + | testFile contents | + testFile := FileLocator temp / 'template.mus.html'. + testFile ensureCreateFile. + contents := +' + + + + ++ {{#show}} You should see me. {{/show}} +
++ {{#unhide}} You should not see me. {{/unhide}} +
+ {{{ contents }}} + +'. + + MarkupFile exportAsFileOn: testFile containing: contents. + +] + +{ #category : #initialization } +BreaPageTest >> createJSONFile [ + | testFile contents | + testFile := self jsonTestFile. + testFile ensureCreateFile. + contents := '{ "title": "This is a test", "show": true, "unhide": false }'. + MarkupFile exportAsFileOn: testFile containing: contents. + +] + +{ #category : #initialization } +BreaPageTest >> createMarkdownFile [ + | testFile contents | + testFile := self markdownTestFile. + testFile ensureCreateFile. + contents := +'--- +title: This is a test +show: true +unhide: false + +--- + +# Level one header + +And paragraph contents with _emphasis_ and **strong emphasis**.'. + + MarkupFile exportAsFileOn: testFile containing: contents. + +] + +{ #category : #'as yet unclassified' } +BreaPageTest >> htmlBodyContents [ + ^ 'And paragraph contents with emphasis and strong emphasis.
+' +] + +{ #category : #'as yet unclassified' } +BreaPageTest >> htmlOutput [ + ^ ' + + + + ++ You should see me. +
++ +
+ ', self htmlBodyContents, +' + +' +] + +{ #category : #'as yet unclassified' } +BreaPageTest >> jsonTestFile [ + ^ FileLocator temp / 'test1.json'. +] + +{ #category : #'as yet unclassified' } +BreaPageTest >> markdownTestFile [ + ^ FileLocator temp / 'test.md'. +] + +{ #category : #'as yet unclassified' } +BreaPageTest >> setUp [ + "I create disposable simple files for testing purposes." + super setUp. + self createMarkdownFile. + self createHTMLTemplateFile. +] + +{ #category : #tests } +BreaPageTest >> testJSONMetadataExtraction [ + + | page testMetadata | + testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. + page := BreaPage new. + page + shortName: 'test1'; + folder: FileLocator temp. + self assert: page metadata equals: testMetadata +] + +{ #category : #tests } +BreaPageTest >> testJSONPopulateMetadata [ + + | page testMetadata | + testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. + page := BreaPage new. + page + shortName: 'test1'; + folder: FileLocator temp. + page templateData at: 'extra' put: 'value'. + self assert: page populateMetadata equals: (testMetadata at: 'extra' put: 'value'; yourself) +] + +{ #category : #tests } +BreaPageTest >> testMarkdownContentExtraction [ + + | page | + page := BreaPage new. + page + shortName: 'test'; + folder: FileLocator temp. + self assert: page contents equals: self markdownTestFile contents. +] + +{ #category : #tests } +BreaPageTest >> testMarkdownHTMLExport [ + + | page | + page := BreaPage new. + page + shortName: 'test'; + folder: FileLocator temp; + template: 'template.mus.html'; + bodyTag: 'contents'. + self assert: (page exportAsHTML contents) equals: self htmlOutput. +] + +{ #category : #tests } +BreaPageTest >> testMarkdownMetadataExtraction [ + + | page testMetadata | + testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. + page := BreaPage new. + page + shortName: 'test'; + folder: FileLocator temp. + self assert: page metadata equals: testMetadata +] + +{ #category : #tests } +BreaPageTest >> testMarkdownPopulateBody [ + + | page | + page := BreaPage new. + page + shortName: 'test'; + folder: FileLocator temp; + bodyTag: 'contents'. + page populateTaggedBody. + self assert: (page templateData at: 'contents') equals: self htmlBodyContents. +] + +{ #category : #tests } +BreaPageTest >> testMarkdownPopulateMetadata [ + + | page testMetadata | + testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. + page := BreaPage new. + page + shortName: 'test'; + folder: FileLocator temp. + page templateData at: 'extra' put: 'value'. + self assert: page populateMetadata equals: (testMetadata at: 'extra' put: 'value'; yourself) +] diff --git a/repository/Brea-Tests/BreaQueryTest.class.st b/repository/Brea-Tests/BreaQueryTest.class.st index 1917fb2..46ad356 100644 --- a/repository/Brea-Tests/BreaQueryTest.class.st +++ b/repository/Brea-Tests/BreaQueryTest.class.st @@ -1,21 +1,21 @@ -" -A BreaQueryTest is a test class for testing the behavior of BreaQuery -" -Class { - #name : #BreaQueryTest, - #superclass : #TestCase, - #category : #'Brea-Tests' -} - -{ #category : #tests } -BreaQueryTest >> testSTONSerialization [ - - | original store deserialized | - original := BreaQuery new - name: 'plus'; - inputs: {'a' -> 3. 'b' -> 4} asDictionary; - codeBlock: [ :x :y | x + y ]. - store := STON toString: original. - deserialized := (STONReader on: store readStream) next. - self assert: original execute equals: deserialized execute -] +" +A BreaQueryTest is a test class for testing the behavior of BreaQuery +" +Class { + #name : #BreaQueryTest, + #superclass : #TestCase, + #category : #'Brea-Tests' +} + +{ #category : #tests } +BreaQueryTest >> testSTONSerialization [ + + | original store deserialized | + original := BreaQuery new + name: 'plus'; + inputs: {'a' -> 3. 'b' -> 4} asDictionary; + codeBlock: [ :x :y | x + y ]. + store := STON toString: original. + deserialized := (STONReader on: store readStream) next. + self assert: original execute equals: deserialized execute +] diff --git a/repository/Brea-Tests/package.st b/repository/Brea-Tests/package.st index 3af073a..2cda3c5 100644 --- a/repository/Brea-Tests/package.st +++ b/repository/Brea-Tests/package.st @@ -1 +1 @@ -Package { #name : #'Brea-Tests' } +Package { #name : #'Brea-Tests' } diff --git a/repository/Brea/Airtable.class.st b/repository/Brea/Airtable.class.st index c3f8896..84d70ad 100644 --- a/repository/Brea/Airtable.class.st +++ b/repository/Brea/Airtable.class.st @@ -1,51 +1,51 @@ -" -I model an Airtable (https://airtable.com/) database (or Base as they call it). -" -Class { - #name : #Airtable, - #superclass : #Object, - #instVars : [ - 'id', - 'apiKey' - ], - #category : #Brea -} - -{ #category : #accessing } -Airtable >> apiKey [ - ^ apiKey -] - -{ #category : #accessing } -Airtable >> apiKey: aString [ - apiKey := aString -] - -{ #category : #accessing } -Airtable >> id [ - ^ id -] - -{ #category : #accessing } -Airtable >> id: aString [ - id := aString -] - -{ #category : #'as yet unclassified' } -Airtable >> rawRecords [ - - (self id isNil or: [ self apiKey isNil ]) ifTrue: [ ^ self ]. - ^ ZnClient new - url: (self id); - headerAt: 'Authorization' put: 'Bearer ', (self apiKey); - get. - -] - -{ #category : #'as yet unclassified' } -Airtable >> records [ - - ^ ((NeoJSONReader fromString: (self rawRecords)) at: 'records') - select: [ :each | (each at: 'fields') isNotEmpty ] - -] +" +I model an Airtable (https://airtable.com/) database (or Base as they call it). +" +Class { + #name : #Airtable, + #superclass : #Object, + #instVars : [ + 'id', + 'apiKey' + ], + #category : #Brea +} + +{ #category : #accessing } +Airtable >> apiKey [ + ^ apiKey +] + +{ #category : #accessing } +Airtable >> apiKey: aString [ + apiKey := aString +] + +{ #category : #accessing } +Airtable >> id [ + ^ id +] + +{ #category : #accessing } +Airtable >> id: aString [ + id := aString +] + +{ #category : #'as yet unclassified' } +Airtable >> rawRecords [ + + (self id isNil or: [ self apiKey isNil ]) ifTrue: [ ^ self ]. + ^ ZnClient new + url: (self id); + headerAt: 'Authorization' put: 'Bearer ', (self apiKey); + get. + +] + +{ #category : #'as yet unclassified' } +Airtable >> records [ + + ^ ((NeoJSONReader fromString: (self rawRecords)) at: 'records') + select: [ :each | (each at: 'fields') isNotEmpty ] + +] diff --git a/repository/Brea/ArchiveOrgItem.class.st b/repository/Brea/ArchiveOrgItem.class.st index 1cc5f01..842c08a 100644 --- a/repository/Brea/ArchiveOrgItem.class.st +++ b/repository/Brea/ArchiveOrgItem.class.st @@ -1,118 +1,118 @@ -" -I model information of the items published on Internet Archive (https://archive.org/). -" -Class { - #name : #ArchiveOrgItem, - #superclass : #Object, - #instVars : [ - 'id', - 'metadata' - ], - #category : #Brea -} - -{ #category : #utility } -ArchiveOrgItem >> archive [ - ^ 'https://archive.org' -] - -{ #category : #utilities } -ArchiveOrgItem >> createHtmlImageGalleryList [ - "IMPORTANT: This is just a draft snipped. Should become a proper test o be deleted." - self metadata ifNil: [ self getMetadata ]. - ^ ' - ' -] - -{ #category : #utilities } -ArchiveOrgItem >> embeddedUrl [ - - ^ 'https://archive.org/embed/', self id. -] - -{ #category : #utilities } -ArchiveOrgItem >> galleryItemsBaseUrl [ - "I create the place where all image would be located for creating a custom image gallery, - according with the requirements for nanogallery2." - - ^ 'https://', (self metadata at: 'd2'), (self metadata at: 'dir'), '/'. -] - -{ #category : #operation } -ArchiveOrgItem >> getMetadata [ - self id ifNil: [ ^ self ]. - self metadata: (NeoJSONReader fromString: (self archive, '/metadata/', self id) asUrl retrieveContents) -] - -{ #category : #accessing } -ArchiveOrgItem >> id [ - ^ id -] - -{ #category : #accessing } -ArchiveOrgItem >> id: anObject [ - id := anObject -] - -{ #category : #utilities } -ArchiveOrgItem >> imagesGalleryList [ - self metadata ifNil: [ self getMetadata ]. - ^ (self metadata at: 'files') select: [ :file | (file at: 'format') = 'JPEG Thumb' ] -] - -{ #category : #utilities } -ArchiveOrgItem >> imagesGalleryListAsDictionary [ - | galleryImages result | - self imagesGalleryList ifNil: [ ^ self ]. - galleryImages := OrderedCollection new. - self imagesGalleryList do: [ :imgMetadata | - galleryImages - add: (Dictionary new - at: 'imgOriginal' put: (imgMetadata at: 'original'); - at: 'imgThumb' put: (imgMetadata at: 'name'); - yourself) ]. - result := { 'archiveItemImages' -> galleryImages } asDictionary. - ^ result -] - -{ #category : #accessing } -ArchiveOrgItem >> metadata [ - ^ metadata -] - -{ #category : #accessing } -ArchiveOrgItem >> metadata: anObject [ - metadata := anObject -] - -{ #category : #utilities } -ArchiveOrgItem >> subjectTags [ - self id ifNil: [ ^ self ]. - self metadata ifNil: [ self getMetadata ]. - ^ (self metadata at: 'metadata') at: 'subject' -] - -{ #category : #utilities } -ArchiveOrgItem >> subjectTagsAsDictionary [ - | tagList result | - self imagesGalleryList ifNil: [ ^ self ]. - tagList := OrderedCollection new. - self subjectTags do: [ :tag | - tagList - add: (Dictionary new - at: 'tag' put: tag; - yourself) ]. - result := { 'tagList' -> tagList } asDictionary. - ^ result -] +" +I model information of the items published on Internet Archive (https://archive.org/). +" +Class { + #name : #ArchiveOrgItem, + #superclass : #Object, + #instVars : [ + 'id', + 'metadata' + ], + #category : #Brea +} + +{ #category : #utility } +ArchiveOrgItem >> archive [ + ^ 'https://archive.org' +] + +{ #category : #utilities } +ArchiveOrgItem >> createHtmlImageGalleryList [ + "IMPORTANT: This is just a draft snipped. Should become a proper test o be deleted." + self metadata ifNil: [ self getMetadata ]. + ^ ' + ' +] + +{ #category : #utilities } +ArchiveOrgItem >> embeddedUrl [ + + ^ 'https://archive.org/embed/', self id. +] + +{ #category : #utilities } +ArchiveOrgItem >> galleryItemsBaseUrl [ + "I create the place where all image would be located for creating a custom image gallery, + according with the requirements for nanogallery2." + + ^ 'https://', (self metadata at: 'd2'), (self metadata at: 'dir'), '/'. +] + +{ #category : #operation } +ArchiveOrgItem >> getMetadata [ + self id ifNil: [ ^ self ]. + self metadata: (NeoJSONReader fromString: (self archive, '/metadata/', self id) asUrl retrieveContents) +] + +{ #category : #accessing } +ArchiveOrgItem >> id [ + ^ id +] + +{ #category : #accessing } +ArchiveOrgItem >> id: anObject [ + id := anObject +] + +{ #category : #utilities } +ArchiveOrgItem >> imagesGalleryList [ + self metadata ifNil: [ self getMetadata ]. + ^ (self metadata at: 'files') select: [ :file | (file at: 'format') = 'JPEG Thumb' ] +] + +{ #category : #utilities } +ArchiveOrgItem >> imagesGalleryListAsDictionary [ + | galleryImages result | + self imagesGalleryList ifNil: [ ^ self ]. + galleryImages := OrderedCollection new. + self imagesGalleryList do: [ :imgMetadata | + galleryImages + add: (Dictionary new + at: 'imgOriginal' put: (imgMetadata at: 'original'); + at: 'imgThumb' put: (imgMetadata at: 'name'); + yourself) ]. + result := { 'archiveItemImages' -> galleryImages } asDictionary. + ^ result +] + +{ #category : #accessing } +ArchiveOrgItem >> metadata [ + ^ metadata +] + +{ #category : #accessing } +ArchiveOrgItem >> metadata: anObject [ + metadata := anObject +] + +{ #category : #utilities } +ArchiveOrgItem >> subjectTags [ + self id ifNil: [ ^ self ]. + self metadata ifNil: [ self getMetadata ]. + ^ (self metadata at: 'metadata') at: 'subject' +] + +{ #category : #utilities } +ArchiveOrgItem >> subjectTagsAsDictionary [ + | tagList result | + self imagesGalleryList ifNil: [ ^ self ]. + tagList := OrderedCollection new. + self subjectTags do: [ :tag | + tagList + add: (Dictionary new + at: 'tag' put: tag; + yourself) ]. + result := { 'tagList' -> tagList } asDictionary. + ^ result +] diff --git a/repository/Brea/BlockClosure.extension.st b/repository/Brea/BlockClosure.extension.st index ce06ce6..32b11da 100644 --- a/repository/Brea/BlockClosure.extension.st +++ b/repository/Brea/BlockClosure.extension.st @@ -1,20 +1,20 @@ -Extension { #name : #BlockClosure } - -{ #category : #'*Brea' } -BlockClosure class >> fromSton: stonReader [ - ^ self compilerClass new - source: stonReader parseListSingleton; - evaluate -] - -{ #category : #'*Brea' } -BlockClosure >> stonContainSubObjects [ - ^ false -] - -{ #category : #'*Brea' } -BlockClosure >> stonOn: stonWriter [ - self isClean - ifTrue: [ stonWriter writeObject: self listSingleton: self printString ] - ifFalse: [ stonWriter error: 'Only clean block can be serialized' ] -] +Extension { #name : #BlockClosure } + +{ #category : #'*Brea' } +BlockClosure class >> fromSton: stonReader [ + ^ self compilerClass new + source: stonReader parseListSingleton; + evaluate +] + +{ #category : #'*Brea' } +BlockClosure >> stonContainSubObjects [ + ^ false +] + +{ #category : #'*Brea' } +BlockClosure >> stonOn: stonWriter [ + self isClean + ifTrue: [ stonWriter writeObject: self listSingleton: self printString ] + ifFalse: [ stonWriter error: 'Only clean block can be serialized' ] +] diff --git a/repository/Brea/BreaFile.class.st b/repository/Brea/BreaFile.class.st index b2c8616..01b0625 100644 --- a/repository/Brea/BreaFile.class.st +++ b/repository/Brea/BreaFile.class.st @@ -1,71 +1,78 @@ -" -I model the file where contents (data and/or metadata) for the Brea CSM pages are stored. -" -Class { - #name : #BreaFile, - #superclass : #Object, - #instVars : [ - 'folder', - 'name' - ], - #category : #Brea -} - -{ #category : #'instance creation' } -BreaFile class >> fromShortName: nameString andFolder: aFileLocation [ - "I create a new BreaFile assigning priorities to the filename discovery according to - their extension currently present in a particular folder." - | extensions | - - extensions := #('md' 'json' 'yaml'). - extensions do: [ :ext | | markupFile filename | - filename := nameString, '.', ext. - markupFile := aFileLocation / filename. - markupFile exists ifTrue: [ ^ self new name: filename; folder: aFileLocation ]. - ]. - ^ nil. -] - -{ #category : #accessing } -BreaFile >> contentString [ - - self name ifNil: [ ^ nil ]. - (self name endsWith: '.md') ifTrue: [ ^ self contents contents ]. - (self name endsWith: '.json') ifTrue: [ ^ self contents asString ]. -] - -{ #category : #accessing } -BreaFile >> contents [ - | file | - self name ifNil: [ ^ nil ]. - file := self folder / self name. - (self name endsWith: '.md') ifTrue: [ ^ Markdown fromFile: file ]. - (self name endsWith: '.json') ifTrue: [ ^ NeoJSONObject fromString: file contents ] -] - -{ #category : #accessing } -BreaFile >> folder [ - ^ folder -] - -{ #category : #accessing } -BreaFile >> folder: anObject [ - folder := anObject -] - -{ #category : #accessing } -BreaFile >> metadata [ - self name ifNil: [ ^ nil ]. - (self name endsWith: '.md') ifTrue: [ ^ self contents metadata ]. - (self name endsWith: '.json') ifTrue: [ ^ self contents asDictionary ]. -] - -{ #category : #accessing } -BreaFile >> name [ - ^ name -] - -{ #category : #accessing } -BreaFile >> name: anObject [ - name := anObject -] +" +I model the file where contents (data and/or metadata) for the Brea CSM pages are stored. +" +Class { + #name : #BreaFile, + #superclass : #Object, + #instVars : [ + 'folder', + 'name' + ], + #category : #Brea +} + +{ #category : #'instance creation' } +BreaFile class >> fromShortName: nameString andFolder: aFileLocation [ + "I create a new BreaFile assigning priorities to the filename discovery according to + their extension currently present in a particular folder." + | extensions | + + extensions := #('md' 'json' 'yaml'). + extensions do: [ :ext | | markupFile filename | + filename := nameString, '.', ext. + markupFile := aFileLocation / filename. + markupFile exists ifTrue: [ ^ self new name: filename; folder: aFileLocation ]. + ]. + ^ nil. +] + +{ #category : #accessing } +BreaFile >> contentString [ + + self name ifNil: [ ^ nil ]. + (self name endsWith: '.md') ifTrue: [ ^ self contents contents ]. + (self name endsWith: '.json') ifTrue: [ ^ self contents asString ]. +] + +{ #category : #accessing } +BreaFile >> contents [ + | file | + self name ifNil: [ ^ nil ]. + file := self folder / self name. + (self name endsWith: '.md') ifTrue: [ ^ Markdown fromFile: file ]. + (self name endsWith: '.json') ifTrue: [ ^ NeoJSONObject fromString: file contents ] +] + +{ #category : #accessing } +BreaFile >> file [ + self folder ifNil: [ ^ self ]. + self name ifNil: [ ^ self ]. + ^ self folder / self name. +] + +{ #category : #accessing } +BreaFile >> folder [ + ^ folder +] + +{ #category : #accessing } +BreaFile >> folder: anObject [ + folder := anObject +] + +{ #category : #accessing } +BreaFile >> metadata [ + self name ifNil: [ ^ nil ]. + (self name endsWith: '.md') ifTrue: [ ^ self contents metadata ]. + (self name endsWith: '.json') ifTrue: [ ^ self contents asDictionary ]. +] + +{ #category : #accessing } +BreaFile >> name [ + ^ name +] + +{ #category : #accessing } +BreaFile >> name: anObject [ + name := anObject +] diff --git a/repository/Brea/BreaPage.class.st b/repository/Brea/BreaPage.class.st index 94a47ab..143b544 100644 --- a/repository/Brea/BreaPage.class.st +++ b/repository/Brea/BreaPage.class.st @@ -1,259 +1,262 @@ -" -I model a wiki page of a Brea site. -I am modelled after common wiki pages, where a document in a light markup laguage -is converted in HTML and is expected to access document history (I am helped by -FossilRepo for that). -I can be used for other types of publications, like blog post though. -" -Class { - #name : #BreaPage, - #superclass : #Object, - #instVars : [ - 'shortName', - 'template', - 'templateData', - 'bodyTag', - 'splitters', - 'subpages', - 'metadata', - 'folder', - 'file' - ], - #category : #Brea -} - -{ #category : #operation } -BreaPage >> bodyContentsAsHTML [ - | sourcePage | - self contentsFile ifNil: [ ^ self ]. - sourcePage := FileLocator temp / 'wikiPage.md'. - MarkupFile exportAsFileOn: sourcePage containing: self contents. - ^ Pandoc markdownToHtml: sourcePage -] - -{ #category : #accessing } -BreaPage >> bodyTag [ - ^ bodyTag -] - -{ #category : #accessing } -BreaPage >> bodyTag: aString [ - "I represent the Mustache Template tag used to denote the body part of a page. - While the metadata is self describing via YAML metadata blocks in Markddown, so - they map where ever they are needed in a template, the Markdown file that will be converted - in HTML via a template doesn't know which part should occupy once the conversion is done. - I provide such knowledge. So if a page template puts the body content under the mustache tag - {{content}}, I should use bodyTag: 'content'. - bodyTag: is template dependant." - bodyTag := aString -] - -{ #category : #accessing } -BreaPage >> contents [ - | result | - self contentsFile ifNil: [ ^ nil ]. - result := '' writeStream. - result nextPutAll: self contentsFile contentString. - self subpages ifNotNil: [ - self subpages do: [ :sp | | markdownTempFile | - markdownTempFile := self folder / (sp, '.md'). - result nextPutAll: (Markdown fromFile: markdownTempFile) contents. - ] - ]. - ^ result contents. -] - -{ #category : #operation } -BreaPage >> contentsFile [ - - self folder ifNil: [ ^ self ]. - self shortName ifNil: [ ^ self ]. - ^ BreaFile fromShortName: self shortName andFolder: self folder. -] - -{ #category : #'as yet unclassified' } -BreaPage >> exportAsHTML [ - | htmlContents allActions actionsArray semaphore result | - self shortName ifNil: [ ^ self ]. - self template ifNil: [ ^ self ]. - actionsArray := { [ self populateMetadata ] future. }. - self splitters ifNotEmpty: [ actionsArray := actionsArray copyWith: [ self split ] future ]. - self bodyTag ifNotNil: [ - actionsArray := actionsArray copyWith: [ self populateBodyAs: self bodyTag ] future ]. - allActions := TKTFuture all: actionsArray. - semaphore := Semaphore new. - allActions onSuccessDo: [ :values | - result := values last. - semaphore signal. - ]. - semaphore wait. - htmlContents := (MustacheTemplate on: result templateFile contents) value: result templateData. - ^ MarkupFile exportAsFileOn: self folder / (self shortName, '.html' ) containing: htmlContents -] - -{ #category : #accessing } -BreaPage >> file [ - (self shortName isNil or: [ self folder isNil ]) ifTrue: [ ^ nil ]. - ^ file ifNil: [ ^ BreaFile fromShortName: self shortName andFolder: self folder ] -] - -{ #category : #accessing } -BreaPage >> file: anObject [ - file := anObject -] - -{ #category : #accessing } -BreaPage >> folder [ - ^ folder -] - -{ #category : #accessing } -BreaPage >> folder: folderFileReference [ - folder := folderFileReference -] - -{ #category : #'as yet unclassified' } -BreaPage >> htmlContents [ - self shortName ifNil: [ ^ self ]. - self template ifNil: [ ^ self ]. - ^ (MustacheTemplate on: self templateFile contents) value: self templateData. -] - -{ #category : #accessing } -BreaPage >> metadata [ - ^ metadata ifNil: [ self contentsFile metadata ] -] - -{ #category : #accessing } -BreaPage >> metadata: aDictionary [ - "External place where page metadata is located (on Internet or the local file system) in JSON format. - If nil, is suposed that is placed in the Markdown file with the page contents." - metadata := aDictionary -] - -{ #category : #'as yet unclassified' } -BreaPage >> populateBodyAs: key [ - | allActions result semaphore | - - allActions := TKTFuture all: { - [ self bodyContentsAsHTML ] future. - }. - semaphore := Semaphore new. - allActions onSuccessDo: [ :values | - result := values last. - semaphore signal ]. - semaphore wait. - self templateData at: key put: result contents. - ^ self. -] - -{ #category : #'as yet unclassified' } -BreaPage >> populateExternalMetadata [ - self metadata ifNil: [ ^ self ]. - self -] - -{ #category : #operation } -BreaPage >> populateMetadata [ - | metadataTemp | - self metadata - ifNotNil: [ metadataTemp := self metadata ] - ifNil: [ metadataTemp := self contentsFile metadata]. - metadataTemp keysAndValuesDo: [ :key :value | - self templateData at: key put: value ]. - ^ templateData -] - -{ #category : #operation } -BreaPage >> populateTaggedBody [ - self bodyTag ifNil: [ ^ self ]. - ^ self populateBodyAs: self bodyTag. -] - -{ #category : #accessing } -BreaPage >> shortName [ - ^ shortName -] - -{ #category : #accessing } -BreaPage >> shortName: aString [ - "The name of the file tha contains the light markup to produce the web page, without file extension. - By default I work with Markdown files." - shortName := aString -] - -{ #category : #'as yet unclassified' } -BreaPage >> split [ - self splitters ifEmpty: [ ^ self ]. - self splitters keysAndValuesDo: [ :key :value | self split: key with: value ]. -] - -{ #category : #'as yet unclassified' } -BreaPage >> split: key with: subkey [ - "I split a comma separated collection of subkeys stored in the 'key' field and name each one as 'subkey' - to put it indiviudally in a Mustache template." - | allSubkeys cleaned data | - allSubkeys := (self populateMetadata at: key) splitOn: ','. - cleaned := allSubkeys collect: [ :item | item withBlanksCondensed ]. - data := OrderedCollection new. - cleaned do: [ :item | - data add: { subkey -> item } asDictionary ]. - self populateMetadata at: key put: data; yourself. -] - -{ #category : #'as yet unclassified' } -BreaPage >> splitterAt: key with: subkey [ - self splitters at: key put: subkey -] - -{ #category : #accessing } -BreaPage >> splitters [ - ^ splitters ifNil: [ splitters := Dictionary new ] -] - -{ #category : #accessing } -BreaPage >> splitters: aDictionary [ - "I model the pattern where a Mustache template contains something like - {{# key}} {{value}} {{/ key}} and has data that needs to be split before injecting it in the template." - splitters := aDictionary -] - -{ #category : #accessing } -BreaPage >> subpages [ - ^ subpages -] - -{ #category : #accessing } -BreaPage >> subpages: shortNamesList [ - "I am used when a page is composed of other subpages (for example with link aliases) that are shared - accross several pages." - subpages := shortNamesList -] - -{ #category : #accessing } -BreaPage >> template [ - ^ template -] - -{ #category : #accessing } -BreaPage >> template: mustacheFileName [ - "Usually templates and their pages are located in the same folder." - template := mustacheFileName -] - -{ #category : #accessing } -BreaPage >> templateData [ - ^ templateData ifNil: [ templateData := Dictionary new ] -] - -{ #category : #accessing } -BreaPage >> templateData: aDictionary [ - templateData := aDictionary -] - -{ #category : #'as yet unclassified' } -BreaPage >> templateFile [ - self folder ifNil: [ ^ self ]. - self template ifNil: [ ^ self ]. - ^ self folder / self template -] +" +I model a wiki page of a Brea site. +I am modelled after common wiki pages, where a document in a light markup laguage +is converted in HTML and is expected to access document history (I am helped by +FossilRepo for that). +I can be used for other types of publications, like blog post though. +" +Class { + #name : #BreaPage, + #superclass : #Object, + #instVars : [ + 'shortName', + 'template', + 'templateData', + 'bodyTag', + 'splitters', + 'subpages', + 'metadata', + 'folder', + 'file' + ], + #category : #Brea +} + +{ #category : #operation } +BreaPage >> bodyContentsAsHTML [ + | sourcePage | + self contentsFile ifNil: [ ^ self ]. + Smalltalk os isWindows ifTrue: [ + ^ Pandoc markdownToHtml: self file file + ]. + sourcePage := FileLocator temp / 'wikiPage.md'. + MarkupFile exportAsFileOn: sourcePage containing: self contents. + ^ Pandoc markdownToHtml: sourcePage +] + +{ #category : #accessing } +BreaPage >> bodyTag [ + ^ bodyTag +] + +{ #category : #accessing } +BreaPage >> bodyTag: aString [ + "I represent the Mustache Template tag used to denote the body part of a page. + While the metadata is self describing via YAML metadata blocks in Markddown, so + they map where ever they are needed in a template, the Markdown file that will be converted + in HTML via a template doesn't know which part should occupy once the conversion is done. + I provide such knowledge. So if a page template puts the body content under the mustache tag + {{content}}, I should use bodyTag: 'content'. + bodyTag: is template dependant." + bodyTag := aString +] + +{ #category : #accessing } +BreaPage >> contents [ + | result | + self contentsFile ifNil: [ ^ nil ]. + result := '' writeStream. + result nextPutAll: self contentsFile contentString. + self subpages ifNotNil: [ + self subpages do: [ :sp | | markdownTempFile | + markdownTempFile := self folder / (sp, '.md'). + result nextPutAll: (Markdown fromFile: markdownTempFile) contents. + ] + ]. + ^ result contents. +] + +{ #category : #operation } +BreaPage >> contentsFile [ + + self folder ifNil: [ ^ self ]. + self shortName ifNil: [ ^ self ]. + ^ BreaFile fromShortName: self shortName andFolder: self folder. +] + +{ #category : #'as yet unclassified' } +BreaPage >> exportAsHTML [ + | htmlContents allActions actionsArray semaphore result | + self shortName ifNil: [ ^ self ]. + self template ifNil: [ ^ self ]. + actionsArray := { [ self populateMetadata ] future. }. + self splitters ifNotEmpty: [ actionsArray := actionsArray copyWith: [ self split ] future ]. + self bodyTag ifNotNil: [ + actionsArray := actionsArray copyWith: [ self populateBodyAs: self bodyTag ] future ]. + allActions := TKTFuture all: actionsArray. + semaphore := Semaphore new. + allActions onSuccessDo: [ :values | + result := values last. + semaphore signal. + ]. + semaphore wait. + htmlContents := (MustacheTemplate on: result templateFile contents) value: result templateData. + ^ MarkupFile exportAsFileOn: self folder / (self shortName, '.html' ) containing: htmlContents +] + +{ #category : #accessing } +BreaPage >> file [ + (self shortName isNil or: [ self folder isNil ]) ifTrue: [ ^ nil ]. + ^ file ifNil: [ ^ BreaFile fromShortName: self shortName andFolder: self folder ] +] + +{ #category : #accessing } +BreaPage >> file: anObject [ + file := anObject +] + +{ #category : #accessing } +BreaPage >> folder [ + ^ folder +] + +{ #category : #accessing } +BreaPage >> folder: folderFileReference [ + folder := folderFileReference +] + +{ #category : #'as yet unclassified' } +BreaPage >> htmlContents [ + self shortName ifNil: [ ^ self ]. + self template ifNil: [ ^ self ]. + ^ (MustacheTemplate on: self templateFile contents) value: self templateData. +] + +{ #category : #accessing } +BreaPage >> metadata [ + ^ metadata ifNil: [ self contentsFile metadata ] +] + +{ #category : #accessing } +BreaPage >> metadata: aDictionary [ + "External place where page metadata is located (on Internet or the local file system) in JSON format. + If nil, is suposed that is placed in the Markdown file with the page contents." + metadata := aDictionary +] + +{ #category : #'as yet unclassified' } +BreaPage >> populateBodyAs: key [ + | allActions result semaphore | + + allActions := TKTFuture all: { + [ self bodyContentsAsHTML ] future. + }. + semaphore := Semaphore new. + allActions onSuccessDo: [ :values | + result := values last. + semaphore signal ]. + semaphore wait. + self templateData at: key put: result contents. + ^ self. +] + +{ #category : #'as yet unclassified' } +BreaPage >> populateExternalMetadata [ + self metadata ifNil: [ ^ self ]. + self +] + +{ #category : #operation } +BreaPage >> populateMetadata [ + | metadataTemp | + self metadata + ifNotNil: [ metadataTemp := self metadata ] + ifNil: [ metadataTemp := self contentsFile metadata]. + metadataTemp keysAndValuesDo: [ :key :value | + self templateData at: key put: value ]. + ^ templateData +] + +{ #category : #operation } +BreaPage >> populateTaggedBody [ + self bodyTag ifNil: [ ^ self ]. + ^ self populateBodyAs: self bodyTag. +] + +{ #category : #accessing } +BreaPage >> shortName [ + ^ shortName +] + +{ #category : #accessing } +BreaPage >> shortName: aString [ + "The name of the file tha contains the light markup to produce the web page, without file extension. + By default I work with Markdown files." + shortName := aString +] + +{ #category : #'as yet unclassified' } +BreaPage >> split [ + self splitters ifEmpty: [ ^ self ]. + self splitters keysAndValuesDo: [ :key :value | self split: key with: value ]. +] + +{ #category : #'as yet unclassified' } +BreaPage >> split: key with: subkey [ + "I split a comma separated collection of subkeys stored in the 'key' field and name each one as 'subkey' + to put it indiviudally in a Mustache template." + | allSubkeys cleaned data | + allSubkeys := (self populateMetadata at: key) splitOn: ','. + cleaned := allSubkeys collect: [ :item | item withBlanksCondensed ]. + data := OrderedCollection new. + cleaned do: [ :item | + data add: { subkey -> item } asDictionary ]. + self populateMetadata at: key put: data; yourself. +] + +{ #category : #'as yet unclassified' } +BreaPage >> splitterAt: key with: subkey [ + self splitters at: key put: subkey +] + +{ #category : #accessing } +BreaPage >> splitters [ + ^ splitters ifNil: [ splitters := Dictionary new ] +] + +{ #category : #accessing } +BreaPage >> splitters: aDictionary [ + "I model the pattern where a Mustache template contains something like + {{# key}} {{value}} {{/ key}} and has data that needs to be split before injecting it in the template." + splitters := aDictionary +] + +{ #category : #accessing } +BreaPage >> subpages [ + ^ subpages +] + +{ #category : #accessing } +BreaPage >> subpages: shortNamesList [ + "I am used when a page is composed of other subpages (for example with link aliases) that are shared + accross several pages." + subpages := shortNamesList +] + +{ #category : #accessing } +BreaPage >> template [ + ^ template +] + +{ #category : #accessing } +BreaPage >> template: mustacheFileName [ + "Usually templates and their pages are located in the same folder." + template := mustacheFileName +] + +{ #category : #accessing } +BreaPage >> templateData [ + ^ templateData ifNil: [ templateData := Dictionary new ] +] + +{ #category : #accessing } +BreaPage >> templateData: aDictionary [ + templateData := aDictionary +] + +{ #category : #'as yet unclassified' } +BreaPage >> templateFile [ + self folder ifNil: [ ^ self ]. + self template ifNil: [ ^ self ]. + ^ self folder / self template +] diff --git a/repository/Brea/BreaQuery.class.st b/repository/Brea/BreaQuery.class.st index 789f0d5..b60cfe5 100644 --- a/repository/Brea/BreaQuery.class.st +++ b/repository/Brea/BreaQuery.class.st @@ -1,95 +1,95 @@ -" -I represent a operation that can be done on data inputs to produce and output by executing -a code block. - -I can be used by BreaThemes to produce outpus reflected in a particular set of theme pages. - - -- (for bonus points) how to create instances. - - One simple example is simply gorgeous. - -Internal Representation and Key Implementation Points. - - Instance Variables - codeBlock: