Compare commits

..

No commits in common. "master" and "Windows" have entirely different histories.

17 changed files with 1140 additions and 1188 deletions

View File

@ -16,27 +16,42 @@ BaselineOfBrea >> baseline: spec [
for: #common for: #common
do: [ do: [
"Dependencies" "Dependencies"
self miniDocs: spec. self grafoscopioUtils: spec.
spec spec
baseline: 'TaskIt' with: [ spec repository: 'github://pharo-contributions/taskit:v1.0' ] baseline: 'NeoJSON' with: [ spec repository: 'github://svenvc/NeoJSON/repository' ];
"[ spec repository: 'github://noha/taskit:add-all-future' ]" baseline: 'Mustache' with: [ spec repository: 'github://noha/mustache/repository' ];
"Disabling Noha's Fork to make Brea installable.". baseline: 'TaskIt' with: [ spec repository: 'github://noha/taskit:add-all-future' ].
"Packages" "Packages"
spec package: 'Brea' with: [ spec requires: #('MiniDocs' 'TaskIt') ]. spec package: 'Brea' with: [ spec requires: #('NeoJSON' 'Mustache' 'TaskIt' 'Grafoscopio-Utils') ].
] ]
] ]
{ #category : #baselines } { #category : #baselines }
BaselineOfBrea >> miniDocs: spec [ BaselineOfBrea >> grafoscopioUtils: spec [
| repo | "I load the configuration of this package using a external Gitea repository."
repo := ExoRepo new "While more Git independient providers are implemented in Monticello, I will use Iceberg
repository: 'https://code.tupale.co/Offray/MiniDocs'. to download the repository and load it from a local directory"
repo
onConflict: [ :ex | ex useLoaded ]; | location localRepo |
onUpgrade: [ :ex | ex useLoaded ]; "Dependencies"
onDowngrade: [ :ex | ex useLoaded ];
onWarningLog; "Local and remote repo definition"
location := FileLocator localDirectory / 'iceberg' / 'Offray' / 'GrafoscopioUtils'.
location exists ifFalse: [
(IceRepositoryCreator new
location: location;
remote: (IceGitRemote url: 'https://code.tupale.co/Offray/GrafoscopioUtils.git');
createRepository)
register
].
"Package loading"
localRepo := 'gitlocal://', location fullName.
Metacello new
repository: localRepo;
baseline: 'GrafoscopioUtils';
load. load.
spec baseline: 'MiniDocs' with: [ spec repository: 'gitlocal://', repo local fullName ] spec baseline: 'GrafoscopioUtils' with: [ spec repository: localRepo ].
spec package: 'Grafoscopio-Utils' with: [ spec repository: localRepo ].
] ]

View File

@ -1,204 +1,203 @@
" "
A BreaPageTest is a test class for testing the behavior of BreaPage A BreaPageTest is a test class for testing the behavior of BreaPage
" "
Class { Class {
#name : #BreaPageTest, #name : #BreaPageTest,
#superclass : #TestCase, #superclass : #TestCase,
#category : #'Brea-Tests' #category : #'Brea-Tests'
} }
{ #category : #initialization } { #category : #initialization }
BreaPageTest >> createHTMLTemplateFile [ BreaPageTest >> createHTMLTemplateFile [
| testFile contents | | testFile contents |
testFile := FileLocator temp / 'template.mus.html'. testFile := FileLocator temp / 'template.mus.html'.
testFile ensureCreateFile. testFile ensureCreateFile.
contents := contents :=
'<!DOCTYPE html> '<!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title> <title>{{title}}</title>
</head> </head>
<body> <body>
<h1>{{title}}</h1> <h1>{{title}}</h1>
<p> <p>
{{#show}} You should see me. {{/show}} {{#show}} You should see me. {{/show}}
</p> </p>
<p> <p>
{{#unhide}} You should not see me. {{/unhide}} {{#unhide}} You should not see me. {{/unhide}}
</p> </p>
{{{ contents }}} {{{ contents }}}
</body> </body>
</html>'. </html>'.
MarkupFile exportAsFileOn: testFile containing: contents. MarkupFile exportAsFileOn: testFile containing: contents.
] ]
{ #category : #initialization } { #category : #initialization }
BreaPageTest >> createJSONFile [ BreaPageTest >> createJSONFile [
| testFile contents | | testFile contents |
testFile := self jsonTestFile. testFile := self jsonTestFile.
testFile ensureCreateFile. testFile ensureCreateFile.
contents := '{ "title": "This is a test", "show": true, "unhide": false }'. contents := '{ "title": "This is a test", "show": true, "unhide": false }'.
MarkupFile exportAsFileOn: testFile containing: contents. MarkupFile exportAsFileOn: testFile containing: contents.
] ]
{ #category : #initialization } { #category : #initialization }
BreaPageTest >> createMarkdownFile [ BreaPageTest >> createMarkdownFile [
| testFile contents | | testFile contents |
testFile := self markdownTestFile. testFile := self markdownTestFile.
testFile ensureCreateFile. testFile ensureCreateFile.
contents := contents :=
'--- '---
title: This is a test title: This is a test
show: true show: true
unhide: false unhide: false
--- ---
# Level one header # Level one header
And paragraph contents with _emphasis_ and **strong emphasis**.'. And paragraph contents with _emphasis_ and **strong emphasis**.'.
MarkupFile exportAsFileOn: testFile containing: contents. MarkupFile exportAsFileOn: testFile containing: contents.
] ]
{ #category : #'as yet unclassified' } { #category : #'as yet unclassified' }
BreaPageTest >> htmlBodyContents [ BreaPageTest >> htmlBodyContents [
^ '<h1 id="level-one-header">Level one header</h1> ^ '<h1 id="level-one-header">Level one header</h1>
<p>And paragraph contents with <em>emphasis</em> and <strong>strong emphasis</strong>.</p> <p>And paragraph contents with <em>emphasis</em> and <strong>strong emphasis</strong>.</p>
' '
] ]
{ #category : #'as yet unclassified' } { #category : #'as yet unclassified' }
BreaPageTest >> htmlOutput [ BreaPageTest >> htmlOutput [
^ '<!DOCTYPE html> ^ '<!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>This is a test</title> <title>This is a test</title>
</head> </head>
<body> <body>
<h1>This is a test</h1> <h1>This is a test</h1>
<p> <p>
You should see me. You should see me.
</p> </p>
<p> <p>
</p> </p>
', self htmlBodyContents, ', self htmlBodyContents,
' '
</body> </body>
</html>' </html>'
] ]
{ #category : #'as yet unclassified' } { #category : #'as yet unclassified' }
BreaPageTest >> jsonTestFile [ BreaPageTest >> jsonTestFile [
^ FileLocator temp / 'test1.json'. ^ FileLocator temp / 'test1.json'.
] ]
{ #category : #'as yet unclassified' } { #category : #'as yet unclassified' }
BreaPageTest >> markdownTestFile [ BreaPageTest >> markdownTestFile [
^ FileLocator temp / 'test.md'. ^ FileLocator temp / 'test.md'.
] ]
{ #category : #'as yet unclassified' } { #category : #'as yet unclassified' }
BreaPageTest >> setUp [ BreaPageTest >> setUp [
"I create disposable simple files for testing purposes." "I create disposable simple files for testing purposes."
super setUp. super setUp.
self createMarkdownFile. self createMarkdownFile.
self createHTMLTemplateFile. self createHTMLTemplateFile.
self createJSONFile ]
]
{ #category : #tests }
{ #category : #tests } BreaPageTest >> testJSONMetadataExtraction [
BreaPageTest >> testJSONMetadataExtraction [
| page testMetadata |
| page testMetadata | testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary.
testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. page := BreaPage new.
page := BreaPage new. page
page shortName: 'test1';
shortName: 'test1'; folder: FileLocator temp.
folder: FileLocator temp. self assert: page metadata equals: testMetadata
self assert: page metadata equals: testMetadata ]
]
{ #category : #tests }
{ #category : #tests } BreaPageTest >> testJSONPopulateMetadata [
BreaPageTest >> testJSONPopulateMetadata [
| page testMetadata |
| page testMetadata | testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary.
testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. page := BreaPage new.
page := BreaPage new. page
page shortName: 'test1';
shortName: 'test1'; folder: FileLocator temp.
folder: FileLocator temp. page templateData at: 'extra' put: 'value'.
page templateData at: 'extra' put: 'value'. self assert: page populateMetadata equals: (testMetadata at: 'extra' put: 'value'; yourself)
self assert: page populateMetadata equals: (testMetadata at: 'extra' put: 'value'; yourself) ]
]
{ #category : #tests }
{ #category : #tests } BreaPageTest >> testMarkdownContentExtraction [
BreaPageTest >> testMarkdownContentExtraction [
| page |
| page | page := BreaPage new.
page := BreaPage new. page
page shortName: 'test';
shortName: 'test'; folder: FileLocator temp.
folder: FileLocator temp. self assert: page contents equals: self markdownTestFile contents.
self assert: page contents equals: self markdownTestFile contents. ]
]
{ #category : #tests }
{ #category : #tests } BreaPageTest >> testMarkdownHTMLExport [
BreaPageTest >> testMarkdownHTMLExport [
| page |
| page | page := BreaPage new.
page := BreaPage new. page
page shortName: 'test';
shortName: 'test'; folder: FileLocator temp;
folder: FileLocator temp; template: 'template.mus.html';
template: 'template.mus.html'; bodyTag: 'contents'.
bodyTag: 'contents'. self assert: (page exportAsHTML contents) equals: self htmlOutput.
self assert: (page exportAsHTML contents) equals: self htmlOutput. ]
]
{ #category : #tests }
{ #category : #tests } BreaPageTest >> testMarkdownMetadataExtraction [
BreaPageTest >> testMarkdownMetadataExtraction [
| page testMetadata |
| page testMetadata | testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary.
testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. page := BreaPage new.
page := BreaPage new. page
page shortName: 'test';
shortName: 'test'; folder: FileLocator temp.
folder: FileLocator temp. self assert: page metadata equals: testMetadata
self assert: page metadata equals: testMetadata ]
]
{ #category : #tests }
{ #category : #tests } BreaPageTest >> testMarkdownPopulateBody [
BreaPageTest >> testMarkdownPopulateBody [
| page |
| page | page := BreaPage new.
page := BreaPage new. page
page shortName: 'test';
shortName: 'test'; folder: FileLocator temp;
folder: FileLocator temp; bodyTag: 'contents'.
bodyTag: 'contents'. page populateTaggedBody.
page populateTaggedBody. self assert: (page templateData at: 'contents') equals: self htmlBodyContents.
self assert: (page templateData at: 'contents') equals: self htmlBodyContents. ]
]
{ #category : #tests }
{ #category : #tests } BreaPageTest >> testMarkdownPopulateMetadata [
BreaPageTest >> testMarkdownPopulateMetadata [
| page testMetadata |
| page testMetadata | testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary.
testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. page := BreaPage new.
page := BreaPage new. page
page shortName: 'test';
shortName: 'test'; folder: FileLocator temp.
folder: FileLocator temp. page templateData at: 'extra' put: 'value'.
page templateData at: 'extra' put: 'value'. self assert: page populateMetadata equals: (testMetadata at: 'extra' put: 'value'; yourself)
self assert: page populateMetadata equals: (testMetadata at: 'extra' put: 'value'; yourself) ]
]

View File

@ -1,21 +1,21 @@
" "
A BreaQueryTest is a test class for testing the behavior of BreaQuery A BreaQueryTest is a test class for testing the behavior of BreaQuery
" "
Class { Class {
#name : #BreaOperatorTest, #name : #BreaQueryTest,
#superclass : #TestCase, #superclass : #TestCase,
#category : #'Brea-Tests' #category : #'Brea-Tests'
} }
{ #category : #tests } { #category : #tests }
BreaOperatorTest >> testSTONSerialization [ BreaQueryTest >> testSTONSerialization [
| original store deserialized | | original store deserialized |
original := BreaOperator new original := BreaQuery new
name: 'plus'; name: 'plus';
inputs: {'a' -> 3. 'b' -> 4} asDictionary; inputs: {'a' -> 3. 'b' -> 4} asDictionary;
codeBlock: [ :x :y | x + y ]. codeBlock: [ :x :y | x + y ].
store := STON toString: original. store := STON toString: original.
deserialized := (STONReader on: store readStream) next. deserialized := (STONReader on: store readStream) next.
self assert: original execute equals: deserialized execute self assert: original execute equals: deserialized execute
] ]

View File

@ -1 +1 @@
Package { #name : #'Brea-Tests' } Package { #name : #'Brea-Tests' }

View File

@ -0,0 +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 ]
]

View File

@ -1,118 +1,118 @@
" "
I model information of the items published on Internet Archive (https://archive.org/). I model information of the items published on Internet Archive (https://archive.org/).
" "
Class { Class {
#name : #ArchiveOrgItem, #name : #ArchiveOrgItem,
#superclass : #Object, #superclass : #Object,
#instVars : [ #instVars : [
'id', 'id',
'metadata' 'metadata'
], ],
#category : #Brea #category : #Brea
} }
{ #category : #utility } { #category : #utility }
ArchiveOrgItem >> archive [ ArchiveOrgItem >> archive [
^ 'https://archive.org' ^ 'https://archive.org'
] ]
{ #category : #utilities } { #category : #utilities }
ArchiveOrgItem >> createHtmlImageGalleryList [ ArchiveOrgItem >> createHtmlImageGalleryList [
"IMPORTANT: This is just a draft snipped. Should become a proper test o be deleted." "IMPORTANT: This is just a draft snipped. Should become a proper test o be deleted."
self metadata ifNil: [ self getMetadata ]. self metadata ifNil: [ self getMetadata ].
^ ' ^ '
<div id="nanogallery2" <div id="nanogallery2"
/* gallery settings */ /* gallery settings */
data-nanogallery2 = ''{ data-nanogallery2 = ''{
"thumbnailHeight": 150, "thumbnailHeight": 150,
"thumbnailWidth": 150, "thumbnailWidth": 150,
"itemsBaseURL": "', self galleryItemsBaseUrl ,'" "itemsBaseURL": "', self galleryItemsBaseUrl ,'"
}'' > }'' >
<!-- gallery content --> <!-- gallery content -->
<a href = "primera 3.jpg" data-ngThumb = "primera 3_thumb.jpg" > </a> <a href = "primera 3.jpg" data-ngThumb = "primera 3_thumb.jpg" > </a>
<a href = "segunda.jpg" data-ngThumb = "segunda_thumb.jpg" > </a> <a href = "segunda.jpg" data-ngThumb = "segunda_thumb.jpg" > </a>
</div>' </div>'
] ]
{ #category : #utilities } { #category : #utilities }
ArchiveOrgItem >> embeddedUrl [ ArchiveOrgItem >> embeddedUrl [
^ 'https://archive.org/embed/', self id. ^ 'https://archive.org/embed/', self id.
] ]
{ #category : #utilities } { #category : #utilities }
ArchiveOrgItem >> galleryItemsBaseUrl [ ArchiveOrgItem >> galleryItemsBaseUrl [
"I create the place where all image would be located for creating a custom image gallery, "I create the place where all image would be located for creating a custom image gallery,
according with the requirements for nanogallery2." according with the requirements for nanogallery2."
^ 'https://', (self metadata at: 'd2'), (self metadata at: 'dir'), '/'. ^ 'https://', (self metadata at: 'd2'), (self metadata at: 'dir'), '/'.
] ]
{ #category : #operation } { #category : #operation }
ArchiveOrgItem >> getMetadata [ ArchiveOrgItem >> getMetadata [
self id ifNil: [ ^ self ]. self id ifNil: [ ^ self ].
self metadata: (NeoJSONReader fromString: (self archive, '/metadata/', self id) asUrl retrieveContents) self metadata: (NeoJSONReader fromString: (self archive, '/metadata/', self id) asUrl retrieveContents)
] ]
{ #category : #accessing } { #category : #accessing }
ArchiveOrgItem >> id [ ArchiveOrgItem >> id [
^ id ^ id
] ]
{ #category : #accessing } { #category : #accessing }
ArchiveOrgItem >> id: anObject [ ArchiveOrgItem >> id: anObject [
id := anObject id := anObject
] ]
{ #category : #utilities } { #category : #utilities }
ArchiveOrgItem >> imagesGalleryList [ ArchiveOrgItem >> imagesGalleryList [
self metadata ifNil: [ self getMetadata ]. self metadata ifNil: [ self getMetadata ].
^ (self metadata at: 'files') select: [ :file | (file at: 'format') = 'JPEG Thumb' ] ^ (self metadata at: 'files') select: [ :file | (file at: 'format') = 'JPEG Thumb' ]
] ]
{ #category : #utilities } { #category : #utilities }
ArchiveOrgItem >> imagesGalleryListAsDictionary [ ArchiveOrgItem >> imagesGalleryListAsDictionary [
| galleryImages result | | galleryImages result |
self imagesGalleryList ifNil: [ ^ self ]. self imagesGalleryList ifNil: [ ^ self ].
galleryImages := OrderedCollection new. galleryImages := OrderedCollection new.
self imagesGalleryList do: [ :imgMetadata | self imagesGalleryList do: [ :imgMetadata |
galleryImages galleryImages
add: (Dictionary new add: (Dictionary new
at: 'imgOriginal' put: (imgMetadata at: 'original'); at: 'imgOriginal' put: (imgMetadata at: 'original');
at: 'imgThumb' put: (imgMetadata at: 'name'); at: 'imgThumb' put: (imgMetadata at: 'name');
yourself) ]. yourself) ].
result := { 'archiveItemImages' -> galleryImages } asDictionary. result := { 'archiveItemImages' -> galleryImages } asDictionary.
^ result ^ result
] ]
{ #category : #accessing } { #category : #accessing }
ArchiveOrgItem >> metadata [ ArchiveOrgItem >> metadata [
^ metadata ^ metadata
] ]
{ #category : #accessing } { #category : #accessing }
ArchiveOrgItem >> metadata: anObject [ ArchiveOrgItem >> metadata: anObject [
metadata := anObject metadata := anObject
] ]
{ #category : #utilities } { #category : #utilities }
ArchiveOrgItem >> subjectTags [ ArchiveOrgItem >> subjectTags [
self id ifNil: [ ^ self ]. self id ifNil: [ ^ self ].
self metadata ifNil: [ self getMetadata ]. self metadata ifNil: [ self getMetadata ].
^ (self metadata at: 'metadata') at: 'subject' ^ (self metadata at: 'metadata') at: 'subject'
] ]
{ #category : #utilities } { #category : #utilities }
ArchiveOrgItem >> subjectTagsAsDictionary [ ArchiveOrgItem >> subjectTagsAsDictionary [
| tagList result | | tagList result |
self imagesGalleryList ifNil: [ ^ self ]. self imagesGalleryList ifNil: [ ^ self ].
tagList := OrderedCollection new. tagList := OrderedCollection new.
self subjectTags do: [ :tag | self subjectTags do: [ :tag |
tagList tagList
add: (Dictionary new add: (Dictionary new
at: 'tag' put: tag; at: 'tag' put: tag;
yourself) ]. yourself) ].
result := { 'tagList' -> tagList } asDictionary. result := { 'tagList' -> tagList } asDictionary.
^ result ^ result
] ]

View File

@ -1,20 +1,20 @@
Extension { #name : #BlockClosure } Extension { #name : #BlockClosure }
{ #category : #'*Brea' } { #category : #'*Brea' }
BlockClosure class >> fromSton: stonReader [ BlockClosure class >> fromSton: stonReader [
^ self compilerClass new ^ self compilerClass new
source: stonReader parseListSingleton; source: stonReader parseListSingleton;
evaluate evaluate
] ]
{ #category : #'*Brea' } { #category : #'*Brea' }
BlockClosure >> stonContainSubObjects [ BlockClosure >> stonContainSubObjects [
^ false ^ false
] ]
{ #category : #'*Brea' } { #category : #'*Brea' }
BlockClosure >> stonOn: stonWriter [ BlockClosure >> stonOn: stonWriter [
self isClean self isClean
ifTrue: [ stonWriter writeObject: self listSingleton: self printString ] ifTrue: [ stonWriter writeObject: self listSingleton: self printString ]
ifFalse: [ stonWriter error: 'Only clean block can be serialized' ] ifFalse: [ stonWriter error: 'Only clean block can be serialized' ]
] ]

View File

@ -1,104 +0,0 @@
Class {
#name : #BreaApp,
#superclass : #Object,
#instVars : [
'name',
'folder',
'host',
'componets'
],
#category : #Brea
}
{ #category : #accessing }
BreaApp >> add: anObject [
anObject class = String ifFalse: [ ].
self body
nextPutAll: (Pandoc htmlStringToMarkdown: anObject); cr.
]
{ #category : #accessing }
BreaApp >> appName [
^ self name asCamelCase
]
{ #category : #accessing }
BreaApp >> at: key put: anObject [
self components at: key put: anObject.
]
{ #category : #accessing }
BreaApp >> components [
^ componets ifNil: [ componets := OrderedDictionary new]
]
{ #category : #accessing }
BreaApp >> componentsWebView [
| response |
response := '' writeStream.
self components ifEmpty: [ ^ response contents ].
self components valuesDo: [ :component |
response
nextPutAll: component webView; cr
].
^ response contents
]
{ #category : #accessing }
BreaApp >> defaultView [
^ '<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light dark" />
<link rel="stylesheet" href="css/pico.min.css">
<title>', self name, '</title>
</head>
<body>
<main class="container">
', self componentsWebView,'
</main>
</body>
</html>'
]
{ #category : #accessing }
BreaApp >> folder [
^ folder
]
{ #category : #accessing }
BreaApp >> folder: aFileDirectory [
folder := aFileDirectory
]
{ #category : #accessing }
BreaApp >> name [
^ name
]
{ #category : #accessing }
BreaApp >> name: aString [
name := aString
]
{ #category : #accessing }
BreaApp >> parentFolder: anObject [
self folder: anObject / self name asCamelCase
]
{ #category : #accessing }
BreaApp >> preview [
| defaultRoute |
defaultRoute := 'http://localhost:',self webHost server port asString, '/', self appName.
self webHost
GET: self appName -> [ self defaultView ].
GoogleChrome openWindowOn: defaultRoute
]
{ #category : #accessing }
BreaApp >> webHost [
^ host ifNil: [ host := Teapot allInstances detect: [ :each | each server isRunning ] ifNone: [ host := Teapot on. host server start ]]
]

View File

@ -1,78 +1,78 @@
" "
I model the file where contents (data and/or metadata) for the Brea CSM pages are stored. I model the file where contents (data and/or metadata) for the Brea CSM pages are stored.
" "
Class { Class {
#name : #BreaFile, #name : #BreaFile,
#superclass : #Object, #superclass : #Object,
#instVars : [ #instVars : [
'folder', 'folder',
'name' 'name'
], ],
#category : #Brea #category : #Brea
} }
{ #category : #'instance creation' } { #category : #'instance creation' }
BreaFile class >> fromShortName: nameString andFolder: aFileLocation [ BreaFile class >> fromShortName: nameString andFolder: aFileLocation [
"I create a new BreaFile assigning priorities to the filename discovery according to "I create a new BreaFile assigning priorities to the filename discovery according to
their extension currently present in a particular folder." their extension currently present in a particular folder."
| extensions | | extensions |
extensions := #('md' 'json' 'yaml'). extensions := #('md' 'json' 'yaml').
extensions do: [ :ext | | markupFile filename | extensions do: [ :ext | | markupFile filename |
filename := nameString, '.', ext. filename := nameString, '.', ext.
markupFile := aFileLocation / filename. markupFile := aFileLocation / filename.
markupFile exists ifTrue: [ ^ self new name: filename; folder: aFileLocation ]. markupFile exists ifTrue: [ ^ self new name: filename; folder: aFileLocation ].
]. ].
^ nil. ^ nil.
] ]
{ #category : #accessing } { #category : #accessing }
BreaFile >> contentString [ BreaFile >> contentString [
self name ifNil: [ ^ nil ]. self name ifNil: [ ^ nil ].
(self name endsWith: '.md') ifTrue: [ ^ self contents contents ]. (self name endsWith: '.md') ifTrue: [ ^ self contents contents ].
(self name endsWith: '.json') ifTrue: [ ^ self contents asString ]. (self name endsWith: '.json') ifTrue: [ ^ self contents asString ].
] ]
{ #category : #accessing } { #category : #accessing }
BreaFile >> contents [ BreaFile >> contents [
| file | | file |
self name ifNil: [ ^ nil ]. self name ifNil: [ ^ nil ].
file := self folder / self name. file := self folder / self name.
(self name endsWith: '.md') ifTrue: [ ^ Markdown fromFile: file ]. (self name endsWith: '.md') ifTrue: [ ^ Markdown fromFile: file ].
(self name endsWith: '.json') ifTrue: [ ^ NeoJSONObject fromString: file contents ] (self name endsWith: '.json') ifTrue: [ ^ NeoJSONObject fromString: file contents ]
] ]
{ #category : #accessing } { #category : #accessing }
BreaFile >> file [ BreaFile >> file [
self folder ifNil: [ ^ self ]. self folder ifNil: [ ^ self ].
self name ifNil: [ ^ self ]. self name ifNil: [ ^ self ].
^ self folder / self name. ^ self folder / self name.
] ]
{ #category : #accessing } { #category : #accessing }
BreaFile >> folder [ BreaFile >> folder [
^ folder ^ folder
] ]
{ #category : #accessing } { #category : #accessing }
BreaFile >> folder: anObject [ BreaFile >> folder: anObject [
folder := anObject folder := anObject
] ]
{ #category : #accessing } { #category : #accessing }
BreaFile >> metadata [ BreaFile >> metadata [
self name ifNil: [ ^ nil ]. self name ifNil: [ ^ nil ].
(self name endsWith: '.md') ifTrue: [ ^ self contents metadata ]. (self name endsWith: '.md') ifTrue: [ ^ self contents metadata ].
(self name endsWith: '.json') ifTrue: [ ^ self contents asDictionary ]. (self name endsWith: '.json') ifTrue: [ ^ self contents asDictionary ].
] ]
{ #category : #accessing } { #category : #accessing }
BreaFile >> name [ BreaFile >> name [
^ name ^ name
] ]
{ #category : #accessing } { #category : #accessing }
BreaFile >> name: anObject [ BreaFile >> name: anObject [
name := anObject name := anObject
] ]

View File

@ -1,255 +1,262 @@
" "
I model a wiki page of a Brea site. I model a wiki page of a Brea site.
I am modelled after common wiki pages, where a document in a light markup laguage 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 is converted in HTML and is expected to access document history (I am helped by
FossilRepo for that). FossilRepo for that).
I can be used for other types of publications, like blog post though. I can be used for other types of publications, like blog post though.
" "
Class { Class {
#name : #BreaPage, #name : #BreaPage,
#superclass : #Object, #superclass : #Object,
#instVars : [ #instVars : [
'shortName', 'shortName',
'template', 'template',
'templateData', 'templateData',
'bodyTag', 'bodyTag',
'splitters', 'splitters',
'subpages', 'subpages',
'metadata', 'metadata',
'folder', 'folder',
'file' 'file'
], ],
#category : #Brea #category : #Brea
} }
{ #category : #operation } { #category : #operation }
BreaPage >> bodyContentsAsHTML [ BreaPage >> bodyContentsAsHTML [
| sourcePage commandParameters | | sourcePage |
self contentsFile ifNil: [ ^ self ]. self contentsFile ifNil: [ ^ self ].
sourcePage := self file file. Smalltalk os isWindows ifTrue: [
Smalltalk os isWindows ifTrue: [ ^ Pandoc markdownToHtml: self file file
^ Pandoc markdownToHtml: sourcePage ].
]. sourcePage := FileLocator temp / 'wikiPage.md'.
commandParameters := ' -f markdown+startnum+task_lists -t html '. MarkupFile exportAsFileOn: sourcePage containing: self contents.
^ GtSubprocessWithInMemoryOutput new ^ Pandoc markdownToHtml: sourcePage
shellCommand: 'pandoc', commandParameters, sourcePage fullName; ]
runAndWait;
stdout. { #category : #accessing }
] BreaPage >> bodyTag [
^ bodyTag
{ #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.
{ #category : #accessing } While the metadata is self describing via YAML metadata blocks in Markddown, so
BreaPage >> bodyTag: aString [ they map where ever they are needed in a template, the Markdown file that will be converted
"I represent the Mustache Template tag used to denote the body part of a page. in HTML via a template doesn't know which part should occupy once the conversion is done.
While the metadata is self describing via YAML metadata blocks in Markddown, so I provide such knowledge. So if a page template puts the body content under the mustache tag
they map where ever they are needed in a template, the Markdown file that will be converted {{content}}, I should use bodyTag: 'content'.
in HTML via a template doesn't know which part should occupy once the conversion is done. bodyTag: is template dependant."
I provide such knowledge. So if a page template puts the body content under the mustache tag bodyTag := aString
{{content}}, I should use bodyTag: 'content'. ]
bodyTag: is template dependant."
bodyTag := aString { #category : #accessing }
] BreaPage >> contents [
| result |
{ #category : #accessing } self contentsFile ifNil: [ ^ nil ].
BreaPage >> contents [ result := '' writeStream.
| result | result nextPutAll: self contentsFile contentString.
self contentsFile ifNil: [ ^ nil ]. self subpages ifNotNil: [
result := '' writeStream. self subpages do: [ :sp | | markdownTempFile |
result nextPutAll: self contentsFile contentString. markdownTempFile := self folder / (sp, '.md').
self subpages ifNotNil: [ result nextPutAll: (Markdown fromFile: markdownTempFile) contents.
self subpages do: [ :sp | | markdownTempFile | ]
markdownTempFile := self folder / (sp, '.md'). ].
result nextPutAll: (Markdown fromFile: markdownTempFile) contents. ^ result contents.
] ]
].
^ result contents withInternetLineEndings. { #category : #operation }
] BreaPage >> contentsFile [
{ #category : #operation } self folder ifNil: [ ^ self ].
BreaPage >> contentsFile [ self shortName ifNil: [ ^ self ].
^ BreaFile fromShortName: self shortName andFolder: self folder.
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 |
{ #category : #'as yet unclassified' } self shortName ifNil: [ ^ self ].
BreaPage >> exportAsHTML [ self template ifNil: [ ^ self ].
| htmlContents allActions actionsArray semaphore result | actionsArray := { [ self populateMetadata ] future. }.
self shortName ifNil: [ ^ self ]. self splitters ifNotEmpty: [ actionsArray := actionsArray copyWith: [ self split ] future ].
self template ifNil: [ ^ self ]. self bodyTag ifNotNil: [
actionsArray := { [ self populateMetadata ] future. }. actionsArray := actionsArray copyWith: [ self populateBodyAs: self bodyTag ] future ].
self splitters ifNotEmpty: [ actionsArray := actionsArray copyWith: [ self split ] future ]. allActions := TKTFuture all: actionsArray.
self bodyTag ifNotNil: [ semaphore := Semaphore new.
actionsArray := actionsArray copyWith: [ self populateBodyAs: self bodyTag ] future ]. allActions onSuccessDo: [ :values |
allActions := TKTFuture fromCollectionOfFutures: actionsArray. result := values last.
semaphore := Semaphore new. semaphore signal.
allActions onSuccessDo: [ :values | ].
result := values last. semaphore wait.
semaphore signal. htmlContents := (MustacheTemplate on: result templateFile contents) value: result templateData.
]. ^ MarkupFile exportAsFileOn: self folder / (self shortName, '.html' ) containing: htmlContents
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 ].
{ #category : #accessing } ^ file ifNil: [ ^ BreaFile fromShortName: self shortName andFolder: self folder ]
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 >> file: anObject [
file := anObject { #category : #accessing }
] BreaPage >> folder [
^ folder
{ #category : #accessing } ]
BreaPage >> folder [
^ folder { #category : #accessing }
] BreaPage >> folder: folderFileReference [
folder := folderFileReference
{ #category : #accessing } ]
BreaPage >> folder: folderFileReference [
folder := folderFileReference { #category : #'as yet unclassified' }
] BreaPage >> htmlContents [
self shortName ifNil: [ ^ self ].
{ #category : #'as yet unclassified' } self template ifNil: [ ^ self ].
BreaPage >> htmlContents [ ^ (MustacheTemplate on: self templateFile contents) value: self templateData.
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 [
^ 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.
{ #category : #accessing } If nil, is suposed that is placed in the Markdown file with the page contents."
BreaPage >> metadata: aDictionary [ 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 |
{ #category : #'as yet unclassified' }
BreaPage >> populateBodyAs: key [ allActions := TKTFuture all: {
self templateData at: key put: self bodyContentsAsHTML. [ self bodyContentsAsHTML ] future.
^ self. }.
] semaphore := Semaphore new.
allActions onSuccessDo: [ :values |
{ #category : #'as yet unclassified' } result := values last.
BreaPage >> populateExternalMetadata [ semaphore signal ].
self metadata ifNil: [ ^ self ]. semaphore wait.
self self templateData at: key put: result contents.
] ^ self.
]
{ #category : #operation }
BreaPage >> populateMetadata [ { #category : #'as yet unclassified' }
| metadataTemp | BreaPage >> populateExternalMetadata [
self metadata self metadata ifNil: [ ^ self ].
ifNotNil: [ metadataTemp := self metadata ] self
ifNil: [ metadataTemp := self contentsFile metadata]. ]
metadataTemp keysAndValuesDo: [ :key :value |
self templateData at: key put: value ]. { #category : #operation }
^ self templateData BreaPage >> populateMetadata [
] | metadataTemp |
self metadata
{ #category : #operation } ifNotNil: [ metadataTemp := self metadata ]
BreaPage >> populateTaggedBody [ ifNil: [ metadataTemp := self contentsFile metadata].
self bodyTag ifNil: [ ^ self ]. metadataTemp keysAndValuesDo: [ :key :value |
^ self populateBodyAs: self bodyTag. self templateData at: key put: value ].
] ^ templateData
]
{ #category : #accessing }
BreaPage >> shortName [ { #category : #operation }
^ shortName BreaPage >> populateTaggedBody [
] self bodyTag ifNil: [ ^ self ].
^ self populateBodyAs: self bodyTag.
{ #category : #accessing } ]
BreaPage >> shortName: aString [
"The name of the file tha contains the light markup to produce the web page, without file extension. { #category : #accessing }
By default I work with Markdown files." BreaPage >> shortName [
shortName := aString ^ shortName
] ]
{ #category : #'as yet unclassified' } { #category : #accessing }
BreaPage >> split [ BreaPage >> shortName: aString [
self splitters ifEmpty: [ ^ self ]. "The name of the file tha contains the light markup to produce the web page, without file extension.
self splitters keysAndValuesDo: [ :key :value | self split: key with: value ]. By default I work with Markdown files."
] shortName := aString
]
{ #category : #'as yet unclassified' }
BreaPage >> split: key with: subkey [ { #category : #'as yet unclassified' }
"I split a comma separated collection of subkeys stored in the 'key' field and name each one as 'subkey' BreaPage >> split [
to put it indiviudally in a Mustache template." self splitters ifEmpty: [ ^ self ].
| allSubkeys cleaned data | self splitters keysAndValuesDo: [ :key :value | self split: key with: value ].
allSubkeys := (self populateMetadata at: key) splitOn: ','. ]
cleaned := allSubkeys collect: [ :item | item withBlanksCondensed ].
data := OrderedCollection new. { #category : #'as yet unclassified' }
cleaned do: [ :item | BreaPage >> split: key with: subkey [
data add: { subkey -> item } asDictionary ]. "I split a comma separated collection of subkeys stored in the 'key' field and name each one as 'subkey'
self populateMetadata at: key put: data; yourself. to put it indiviudally in a Mustache template."
] | allSubkeys cleaned data |
allSubkeys := (self populateMetadata at: key) splitOn: ','.
{ #category : #'as yet unclassified' } cleaned := allSubkeys collect: [ :item | item withBlanksCondensed ].
BreaPage >> splitterAt: key with: subkey [ data := OrderedCollection new.
self splitters at: key put: subkey cleaned do: [ :item |
] data add: { subkey -> item } asDictionary ].
self populateMetadata at: key put: data; yourself.
{ #category : #accessing } ]
BreaPage >> splitters [
^ splitters ifNil: [ splitters := Dictionary new ] { #category : #'as yet unclassified' }
] BreaPage >> splitterAt: key with: subkey [
self splitters at: key put: subkey
{ #category : #accessing } ]
BreaPage >> splitters: aDictionary [
"I model the pattern where a Mustache template contains something like { #category : #accessing }
{{# key}} {{value}} {{/ key}} and has data that needs to be split before injecting it in the template." BreaPage >> splitters [
splitters := aDictionary ^ splitters ifNil: [ splitters := Dictionary new ]
] ]
{ #category : #accessing } { #category : #accessing }
BreaPage >> subpages [ BreaPage >> splitters: aDictionary [
^ subpages "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: shortNamesList [
"I am used when a page is composed of other subpages (for example with link aliases) that are shared { #category : #accessing }
accross several pages." BreaPage >> subpages [
subpages := shortNamesList ^ subpages
] ]
{ #category : #accessing } { #category : #accessing }
BreaPage >> template [ BreaPage >> subpages: shortNamesList [
^ template "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: mustacheFileName [
"Usually templates and their pages are located in the same folder." { #category : #accessing }
template := mustacheFileName BreaPage >> template [
] ^ template
]
{ #category : #accessing }
BreaPage >> templateData [ { #category : #accessing }
^ templateData ifNil: [ templateData := Dictionary new ] BreaPage >> template: mustacheFileName [
] "Usually templates and their pages are located in the same folder."
template := mustacheFileName
{ #category : #accessing } ]
BreaPage >> templateData: aDictionary [
templateData := aDictionary { #category : #accessing }
] BreaPage >> templateData [
^ templateData ifNil: [ templateData := Dictionary new ]
{ #category : #'as yet unclassified' } ]
BreaPage >> templateFile [
self folder ifNil: [ ^ self ]. { #category : #accessing }
self template ifNil: [ ^ self ]. BreaPage >> templateData: aDictionary [
^ self folder / self template templateData := aDictionary
] ]
{ #category : #'as yet unclassified' }
BreaPage >> templateFile [
self folder ifNil: [ ^ self ].
self template ifNil: [ ^ self ].
^ self folder / self template
]

View File

@ -1,95 +1,95 @@
" "
I represent a operation that can be done on data inputs to produce and output by executing I represent a operation that can be done on data inputs to produce and output by executing
a code block. a code block.
I can be used by BreaThemes to produce outpus reflected in a particular set of theme pages. I can be used by BreaThemes to produce outpus reflected in a particular set of theme pages.
- (for bonus points) how to create instances. - (for bonus points) how to create instances.
One simple example is simply gorgeous. One simple example is simply gorgeous.
Internal Representation and Key Implementation Points. Internal Representation and Key Implementation Points.
Instance Variables Instance Variables
codeBlock: <Object> codeBlock: <Object>
inputs: <Object> inputs: <Object>
name: <Object> name: <Object>
Implementation Points Implementation Points
" "
Class { Class {
#name : #BreaOperator, #name : #BreaQuery,
#superclass : #Object, #superclass : #Object,
#instVars : [ #instVars : [
'name', 'name',
'inputs', 'inputs',
'codeBlock', 'codeBlock',
'cleanedInputs' 'cleanedInputs'
], ],
#category : #Brea #category : #Brea
} }
{ #category : #converting } { #category : #converting }
BreaOperator >> asSton [ BreaQuery >> asSton [
^ STON toStringPretty: self ^ STON toStringPretty: self
] ]
{ #category : #converting } { #category : #converting }
BreaOperator >> cleanInputs [ BreaQuery >> cleanInputs [
self cleanedInputs ifNil: [ ^ self ]. self cleanedInputs ifNil: [ ^ self ].
self cleanedInputs ifTrue: [ self cleanedInputs ifTrue: [
self inputs keysAndValuesDo: [ :k :v | | currentValue | self inputs keysAndValuesDo: [ :k :v | | currentValue |
currentValue := self inputs at: k. currentValue := self inputs at: k.
self inputs at: k put: currentValue class new self inputs at: k put: currentValue class new
] ]
]. ].
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> cleanedInputs [ BreaQuery >> cleanedInputs [
^ cleanedInputs ^ cleanedInputs
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> cleanedInputs: aBoolean [ BreaQuery >> cleanedInputs: aBoolean [
"I tell if the inputs should be cleaned when the query is serialized as STON, for "I tell if the inputs should be cleaned when the query is serialized as STON, for
example when they contain sensible information, like API keys or passwords" example when they contain sensible information, like API keys or passwords"
cleanedInputs := aBoolean cleanedInputs := aBoolean
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> codeBlock [ BreaQuery >> codeBlock [
^ codeBlock ^ codeBlock
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> codeBlock: anObject [ BreaQuery >> codeBlock: anObject [
codeBlock := anObject codeBlock := anObject
] ]
{ #category : #execution } { #category : #execution }
BreaOperator >> execute [ BreaQuery >> execute [
^ self codeBlock valueWithArguments: self inputs values. ^ self codeBlock valueWithArguments: self inputs values.
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> inputs [ BreaQuery >> inputs [
^ inputs ^ inputs
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> inputs: anOrderedDictionary [ BreaQuery >> inputs: anOrderedDictionary [
inputs := anOrderedDictionary inputs := anOrderedDictionary
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> name [ BreaQuery >> name [
^ name ^ name
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> name: anObject [ BreaQuery >> name: anObject [
name := anObject name := anObject
] ]

View File

@ -1,229 +1,225 @@
" "
I model a web theme. I model a web theme.
For the Collaborators Part: State my main collaborators and one line about how I interact with them. For the Collaborators Part: State my main collaborators and one line about how I interact with them.
Public API and Key Messages Public API and Key Messages
- message one - message one
- message two - message two
- (for bonus points) how to create instances. - (for bonus points) how to create instances.
One simple example is simply gorgeous. One simple example is simply gorgeous.
Internal Representation and Key Implementation Points. Internal Representation and Key Implementation Points.
Instance Variables Instance Variables
name: <Object> name: <Object>
preview: <Object> preview: <Object>
provider: <Object> provider: <Object>
url: <Object> url: <Object>
Implementation Points Implementation Points
" "
Class { Class {
#name : #BreaTheme, #name : #BreaTheme,
#superclass : #Object, #superclass : #Object,
#instVars : [ #instVars : [
'name', 'name',
'folder', 'folder',
'provider', 'provider',
'url', 'url',
'preview', 'preview',
'license', 'license',
'operators' 'queries',
], 'customizations'
#category : #Brea ],
} #category : #Brea
}
{ #category : #accessing }
BreaTheme class >> availablePacks [ { #category : #accessing }
^ self downloadLinks keys BreaTheme class >> availablePacks [
] ^ self downloadLinks keys
]
{ #category : #utilities }
BreaTheme class >> downloadLinks [ { #category : #utilities }
"Keys are the theme names and values are the url where it can be downloaded BreaTheme class >> downloadLinks [
as a zip file. "Keys are the theme names and values are the url where it can be downloaded
For the moment we work only with HTML5Up themes, but more could be added as a zip file.
and the code should be refactored accordingly." For the moment we work only with HTML5Up themes, but more could be added
| result providerUrl | and the code should be refactored accordingly."
result := Dictionary new. | result providerUrl |
providerUrl := 'https://html5up.net'. result := Dictionary new.
result providerUrl := 'https://html5up.net'.
at: 'Paradigm Shift' put: providerUrl, '/paradigm-shift/download'; result
at: 'Massively' put: providerUrl, '/massively/download'; at: 'Paradigm Shift' put: providerUrl, '/paradigm-shift/download';
at: 'Ethereal' put: providerUrl, '/ethereal/download'; at: 'Massively' put: providerUrl, '/massively/download';
at: 'Story' put: providerUrl, '/story/download'; at: 'Ethereal' put: providerUrl, '/ethereal/download';
at: 'Dimension' put: providerUrl, '/dimension/download'; at: 'Story' put: providerUrl, '/story/download';
at: 'Editorial' put: providerUrl, '/editorial/download'; at: 'Dimension' put: providerUrl, '/dimension/download';
at: 'Forty' put: providerUrl, '/forty/download'; at: 'Editorial' put: providerUrl, '/editorial/download';
at: 'Stellar' put: providerUrl, '/stellar/download'; at: 'Forty' put: providerUrl, '/forty/download';
at: 'Multiverse' put: providerUrl, '/multiverse/download'; at: 'Stellar' put: providerUrl, '/stellar/download';
at: 'Phantom' put: providerUrl, '/phantom/download'; at: 'Multiverse' put: providerUrl, '/multiverse/download';
at: 'Hyperspace' put: providerUrl, '/hyperspace/download'; at: 'Phantom' put: providerUrl, '/phantom/download';
at: 'Future Imperfect' put: providerUrl, '/future-imperfect/download'; at: 'Hyperspace' put: providerUrl, '/hyperspace/download';
at: 'Solid State' put: providerUrl, '/solid-state/download'; at: 'Future Imperfect' put: providerUrl, '/future-imperfect/download';
at: 'Identity' put: providerUrl, '/identity/download'; at: 'Solid State' put: providerUrl, '/solid-state/download';
at: 'Lens' put: providerUrl, '/lens/download'; at: 'Identity' put: providerUrl, '/identity/download';
at: 'Fractal' put: providerUrl, '/fractal/download'; at: 'Lens' put: providerUrl, '/lens/download';
at: 'Eventually' put: providerUrl, '/eventually/download'; at: 'Fractal' put: providerUrl, '/fractal/download';
at: 'Spectral' put: providerUrl, '/spectral/download'; at: 'Eventually' put: providerUrl, '/eventually/download';
at: 'Phonon' put: providerUrl, '/photon/download'; at: 'Spectral' put: providerUrl, '/spectral/download';
at: 'Highlights' put: providerUrl, '/highlights/download'; at: 'Phonon' put: providerUrl, '/photon/download';
at: 'Landed' put: providerUrl, '/landed/download'; at: 'Highlights' put: providerUrl, '/highlights/download';
at: 'Strata' put: providerUrl, '/strata/download'; at: 'Landed' put: providerUrl, '/landed/download';
at: 'Read Only' put: providerUrl, '/read-only/download'; at: 'Strata' put: providerUrl, '/strata/download';
at: 'Alpha' put: providerUrl, '/alpha/download'; at: 'Read Only' put: providerUrl, '/read-only/download';
at: 'Directive' put: providerUrl, '/directive/download'; at: 'Alpha' put: providerUrl, '/alpha/download';
at: 'Aerial' put: providerUrl, '/aerial/download'; at: 'Directive' put: providerUrl, '/directive/download';
at: 'Twenty' put: providerUrl, '/twenty/download'; at: 'Aerial' put: providerUrl, '/aerial/download';
at: 'Big Picture' put: providerUrl, '/big-picture/download'; at: 'Twenty' put: providerUrl, '/twenty/download';
at: 'Tessellate' put: providerUrl, '/tessellate/download'; at: 'Big Picture' put: providerUrl, '/big-picture/download';
at: 'Overflow' put: providerUrl, 'overflow/download'; at: 'Tessellate' put: providerUrl, '/tessellate/download';
at: 'Prologue' put: providerUrl, '/prologue/download'; at: 'Overflow' put: providerUrl, 'overflow/download';
at: 'Helios' put: providerUrl, '/helios/download'; at: 'Prologue' put: providerUrl, '/prologue/download';
at: 'Telephasic' put: providerUrl, '/telephasic/download'; at: 'Helios' put: providerUrl, '/helios/download';
at: 'Strongly Typed' put: providerUrl, '/strongly-typed/download'; at: 'Telephasic' put: providerUrl, '/telephasic/download';
at: 'Parallelism' put: providerUrl, '/parallelism/download'; at: 'Strongly Typed' put: providerUrl, '/strongly-typed/download';
at: 'Escape Velocity' put: providerUrl, '/escape-velocity/download'; at: 'Parallelism' put: providerUrl, '/parallelism/download';
at: 'Astral' put: providerUrl, '/astral/download'; at: 'Escape Velocity' put: providerUrl, '/escape-velocity/download';
at: 'Striped' put: providerUrl, '/striped/download'; at: 'Astral' put: providerUrl, '/astral/download';
at: 'Dopetrope' put: providerUrl, '/dopetrope/download'; at: 'Striped' put: providerUrl, '/striped/download';
at: 'Miniport' put: providerUrl, '/miniport/download'; at: 'Dopetrope' put: providerUrl, '/dopetrope/download';
at: 'TXT' put: providerUrl, '/txt/download'; at: 'Miniport' put: providerUrl, '/miniport/download';
at: 'Verti' put: providerUrl, '/verti/download'; at: 'TXT' put: providerUrl, '/txt/download';
at: 'Zerofour' put: providerUrl, '/zerofour/download'; at: 'Verti' put: providerUrl, '/verti/download';
at: 'Arcana' put: providerUrl, '/arcana/download'; at: 'Zerofour' put: providerUrl, '/zerofour/download';
at: 'Halcyonic' put: providerUrl, '/halcyonic/download'; at: 'Arcana' put: providerUrl, '/arcana/download';
at: 'Minimaxing' put: providerUrl, '/minimaxing/download'. at: 'Halcyonic' put: providerUrl, '/halcyonic/download';
^ result at: 'Minimaxing' put: providerUrl, '/minimaxing/download'.
] ^ result
]
{ #category : #operation }
BreaTheme >> addOperator: aBreaQuery [ { #category : #operation }
self operators add: aBreaQuery cleanInputs BreaTheme >> addQuery: aBreaQuery [
] self queries add: aBreaQuery cleanInputs
]
{ #category : #operation }
BreaTheme >> asSton [ { #category : #operation }
^ STON toStringPretty: self BreaTheme >> asSton [
] ^ STON toStringPretty: self
]
{ #category : #utilities }
BreaTheme >> dashedName [ { #category : #utilities }
^ self name asDashedLowercase BreaTheme >> dashedName [
] ^ self name asDashedLowercase
]
{ #category : #operation }
BreaTheme >> downloadInto: aFolder [ { #category : #operation }
| tempName zippedFile | BreaTheme >> downloadInto: aFolder [
self url ifNil: [ ^ self ]. | tempName zippedFile |
tempName := self name. self url ifNil: [ ^ self ].
zippedFile := aFolder / self dashedName , 'zip'. tempName := self name.
aFolder ensureCreateDirectory. zippedFile := aFolder / self dashedName , 'zip'.
GrafoscopioUtils aFolder ensureCreateDirectory.
downloadingFrom: self url withMessage: 'Downloading ', tempName, '...' into: zippedFile. GrafoscopioUtils
self folder: aFolder. downloadingFrom: self url withMessage: 'Downloading ', tempName, '...' into: zippedFile.
^ zippedFile self folder: aFolder.
] ^ zippedFile
]
{ #category : #accessing }
BreaTheme >> folder [ { #category : #accessing }
^ folder BreaTheme >> folder [
] ^ folder
]
{ #category : #accessing }
BreaTheme >> folder: anObject [ { #category : #accessing }
folder := anObject BreaTheme >> folder: anObject [
] folder := anObject
]
{ #category : #installation }
BreaTheme >> installInto: aFolder [ { #category : #installation }
| zippedFile | BreaTheme >> installInto: aFolder [
self url ifNil: [ ^ self ]. | zippedFile |
zippedFile := FileLocator temp / 'download'. self url ifNil: [ ^ self ].
zippedFile ensureDelete. zippedFile := self downloadInto: FileLocator temp.
ZnClient new (ZipArchive new readFrom: zippedFile) extractAllTo: aFolder.
url: self url; ^ aFolder
downloadTo: FileLocator temp. ]
(ZipArchive new readFrom: zippedFile) extractAllTo: aFolder.
self folder: aFolder. { #category : #accessing }
^ aFolder BreaTheme >> license [
] ^ license
]
{ #category : #accessing }
BreaTheme >> license [ { #category : #accessing }
^ license BreaTheme >> license: anObject [
] license := anObject
]
{ #category : #accessing }
BreaTheme >> license: anObject [ { #category : #operation }
license := anObject BreaTheme >> loadConfiguration [
] | config |
config := self folder / 'brea.yaml'.
{ #category : #operation } config exists
BreaTheme >> loadConfiguration [ ifTrue: [ ^ PPYAMLGrammar new parse: config contents ]
| config | ifFalse: [ self inform:
config := self folder / 'brea.yaml'. 'No configuration file found. A "brea.yaml" file should be located in the theme root folder.
config exists please run "#updateCustomizations" after defining a theme name from the
ifTrue: [ ^ PPYAMLGrammar new parse: config contents ] "BreaTheme availablePacks".
ifFalse: [ self inform: If no configuration is defined for such theme name you can create and empty configuration
'No configuration file found. A "brea.yaml" file should be located in the theme root folder. file by running "#createBaseConfiguration" and filing out the "brea.yaml" fields.
please run "#updateCustomizations" after defining a theme name from the For more information or help ask at https://t.me/grafoscopio .' ]
"BreaTheme availablePacks". ]
If no configuration is defined for such theme name you can create and empty configuration
file by running "#createBaseConfiguration" and filing out the "brea.yaml" fields. { #category : #accessing }
For more information or help ask at https://t.me/grafoscopio .' ] BreaTheme >> name [
] ^ name ifNil: [ name = 'unamed' ]
]
{ #category : #accessing }
BreaTheme >> name [ { #category : #accessing }
^ name ifNil: [ name = 'unamed' ] BreaTheme >> name: anObject [
] name := anObject
]
{ #category : #accessing }
BreaTheme >> name: anObject [ { #category : #accessing }
name := anObject BreaTheme >> preview [
] ^ preview
]
{ #category : #accessing }
BreaTheme >> operators [ { #category : #accessing }
^ operators ifNil: [ operators := OrderedCollection new ] BreaTheme >> preview: anObject [
] preview := anObject
]
{ #category : #accessing }
BreaTheme >> operators: cleanedBreaQueriesCollection [ { #category : #accessing }
operators := cleanedBreaQueriesCollection BreaTheme >> provider [
] ^ provider
]
{ #category : #accessing }
BreaTheme >> preview [ { #category : #accessing }
^ preview BreaTheme >> provider: anObject [
] provider := anObject
]
{ #category : #accessing }
BreaTheme >> preview: anObject [ { #category : #accessing }
preview := anObject BreaTheme >> queries [
] ^ queries ifNil: [ queries := OrderedCollection new ]
]
{ #category : #accessing }
BreaTheme >> provider [ { #category : #accessing }
^ provider BreaTheme >> queries: cleanedBreaQueriesCollection [
] queries := cleanedBreaQueriesCollection
]
{ #category : #accessing }
BreaTheme >> provider: anObject [ { #category : #accessing }
provider := anObject BreaTheme >> url [
] ^ url ifNil: [ url := self class downloadLinks at: self name. ]
]
{ #category : #accessing }
BreaTheme >> url [ { #category : #accessing }
^ url ifNil: [ url := self class downloadLinks at: self name. ] BreaTheme >> url: anObject [
] url := anObject
]
{ #category : #accessing }
BreaTheme >> url: anObject [
url := anObject
]

View File

@ -1,22 +1,22 @@
" "
I provide common utilities for the use with the Brea CMS. I provide common utilities for the use with the Brea CMS.
" "
Class { Class {
#name : #BreaUtils, #name : #BreaUtils,
#superclass : #Object, #superclass : #Object,
#category : #Brea #category : #Brea
} }
{ #category : #'as yet unclassified' } { #category : #'as yet unclassified' }
BreaUtils class >> installSkeleton [ BreaUtils class >> installSkeleton [
"I populate the folder and files structures for Brea documentation and customizations." "I populate the folder and files structures for Brea documentation and customizations."
| skeleton destination | | skeleton destination |
GrafoscopioUtils GrafoscopioUtils
downloadingFrom: 'https://mutabit.com/repos.fossil/brea/zip' downloadingFrom: 'https://mutabit.com/repos.fossil/brea/zip'
withMessage: 'Dowloading files skeleton' withMessage: 'Dowloading files skeleton'
into: FileLocator temp. into: FileLocator temp.
skeleton := ZipArchive new readFrom: FileLocator temp / 'zip'. skeleton := ZipArchive new readFrom: FileLocator temp / 'zip'.
destination := FileLocator home / '.local/share/Brea'. destination := FileLocator home / '.local/share/Brea'.
destination ensureCreateDirectory. destination ensureCreateDirectory.
skeleton extractAllTo: destination. skeleton extractAllTo: destination.
] ]

View File

@ -1,13 +1,13 @@
" "
I store metadata for this package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser I store metadata for this package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser
" "
Class { Class {
#name : #ManifestBrea, #name : #ManifestBrea,
#superclass : #PackageManifest, #superclass : #PackageManifest,
#category : #'Brea-Manifest' #category : #'Brea-Manifest'
} }
{ #category : #'code-critics' } { #category : #'code-critics' }
ManifestBrea class >> ruleRBStringConcatenationRuleV1FalsePositive [ ManifestBrea class >> ruleRBStringConcatenationRuleV1FalsePositive [
^ #(#(#(#RGMethodDefinition #(#BreaPage #contents #false)) #'2020-08-28T20:08:20.291489-05:00') #(#(#RGMethodDefinition #(#BreaFile #fromShortName:andFolder: #false)) #'2020-11-06T20:59:12.94748-05:00') #(#(#RGMethodDefinition #(#'BreaFile class' #fromShortName:andFolder: #true)) #'2020-11-06T21:02:25.564981-05:00') ) ^ #(#(#(#RGMethodDefinition #(#BreaPage #contents #false)) #'2020-08-28T20:08:20.291489-05:00') #(#(#RGMethodDefinition #(#BreaFile #fromShortName:andFolder: #false)) #'2020-11-06T20:59:12.94748-05:00') #(#(#RGMethodDefinition #(#'BreaFile class' #fromShortName:andFolder: #true)) #'2020-11-06T21:02:25.564981-05:00') )
] ]

View File

@ -1,6 +0,0 @@
Extension { #name : #String }
{ #category : #'*Brea' }
String >> webView [
^ (Pandoc htmlStringToMarkdown: self) accentedCharactersCorrection
]

View File

@ -1,6 +0,0 @@
Extension { #name : #Teapot }
{ #category : #'*Brea' }
Teapot >> dynamicRoutes [
^ dynamicRouter routes
]

View File

@ -1 +1 @@
Package { #name : #Brea } Package { #name : #Brea }