diff --git a/repository/TiddlyWiki/DateAndTime.extension.st b/repository/TiddlyWiki/DateAndTime.extension.st index a4c662a..72767d3 100644 --- a/repository/TiddlyWiki/DateAndTime.extension.st +++ b/repository/TiddlyWiki/DateAndTime.extension.st @@ -1,28 +1,28 @@ -Extension { #name : #DateAndTime } - -{ #category : #'*TiddlyWiki' } -DateAndTime >> asTiddlerFormat [ - - | hours minutes secondsTemp | - hours := self hours. - minutes := self minutes. - secondsTemp := self seconds. - ^ (self dayMonthYearDo: [ :d :m :y | - y asString, - (m < 10 - ifTrue: [ '0', m asString ] - ifFalse: [ m asString]), - (d < 10 - ifTrue: [ '0', d asString ] - ifFalse: [ d asString])]), - (hours < 10 - ifTrue: [ '0',hours asString ] - ifFalse: [ hours asString]), - (minutes < 10 - ifTrue: [ '0', minutes asString ] - ifFalse: [ minutes asString]), - (secondsTemp < 10 - ifTrue: [ '0', secondsTemp asString ] - ifFalse: [ secondsTemp asString]), - (self nanoSecond asString copyFrom: 1 to: 3) -] +Extension { #name : #DateAndTime } + +{ #category : #'*TiddlyWiki' } +DateAndTime >> asTiddlerFormat [ + + | hours minutes secondsTemp | + hours := self hours. + minutes := self minutes. + secondsTemp := self seconds. + ^ (self dayMonthYearDo: [ :d :m :y | + y asString, + (m < 10 + ifTrue: [ '0', m asString ] + ifFalse: [ m asString]), + (d < 10 + ifTrue: [ '0', d asString ] + ifFalse: [ d asString])]), + (hours < 10 + ifTrue: [ '0',hours asString ] + ifFalse: [ hours asString]), + (minutes < 10 + ifTrue: [ '0', minutes asString ] + ifFalse: [ minutes asString]), + (secondsTemp < 10 + ifTrue: [ '0', secondsTemp asString ] + ifFalse: [ secondsTemp asString]), + (self nanoSecond asString copyFrom: 1 to: 3) +] diff --git a/repository/TiddlyWiki/FedWikiItem.class.st b/repository/TiddlyWiki/FedWikiItem.class.st index 9818687..cc2cd15 100644 --- a/repository/TiddlyWiki/FedWikiItem.class.st +++ b/repository/TiddlyWiki/FedWikiItem.class.st @@ -1,34 +1,34 @@ -Class { - #name : #FedWikiItem, - #superclass : #Object, - #instVars : [ - 'text', - 'id', - 'type' - ], - #category : 'TiddlyWiki-Model' -} - -{ #category : #accessing } -FedWikiItem >> fromDictionary: aDictionary [ - text := aDictionary at: 'text'. - id := aDictionary at: 'id'. - type := aDictionary at: 'type'. -] - -{ #category : #accessing } -FedWikiItem >> printOn: aStream [ - super printOn: aStream. - aStream - nextPutAll: '( ',self type, ' | ', self text, ' )' -] - -{ #category : #accessing } -FedWikiItem >> text [ - ^ text -] - -{ #category : #accessing } -FedWikiItem >> type [ - ^ type -] +Class { + #name : #FedWikiItem, + #superclass : #Object, + #instVars : [ + 'text', + 'id', + 'type' + ], + #category : 'TiddlyWiki-Model' +} + +{ #category : #accessing } +FedWikiItem >> fromDictionary: aDictionary [ + text := aDictionary at: 'text'. + id := aDictionary at: 'id'. + type := aDictionary at: 'type'. +] + +{ #category : #accessing } +FedWikiItem >> printOn: aStream [ + super printOn: aStream. + aStream + nextPutAll: '( ',self type, ' | ', self text, ' )' +] + +{ #category : #accessing } +FedWikiItem >> text [ + ^ text +] + +{ #category : #accessing } +FedWikiItem >> type [ + ^ type +] diff --git a/repository/TiddlyWiki/FedWikiPage.class.st b/repository/TiddlyWiki/FedWikiPage.class.st index 90e0350..2389d75 100644 --- a/repository/TiddlyWiki/FedWikiPage.class.st +++ b/repository/TiddlyWiki/FedWikiPage.class.st @@ -1,98 +1,98 @@ -Class { - #name : #FedWikiPage, - #superclass : #Object, - #instVars : [ - 'url', - 'title', - 'story', - 'journal', - 'importJournal' - ], - #category : #'TiddlyWiki-Model' -} - -{ #category : #accessing } -FedWikiPage >> dataDictionary [ - | dataUrl | - self isView ifFalse: [ - self inform: 'Please provide a view url for the FedWiki page.'. - ^ self]. - dataUrl := self scheme , '://', self host, '/', self titleSegmentUrl, '.json'. - ^ STONJSON fromString: dataUrl asUrl retrieveContents -] - -{ #category : #accessing } -FedWikiPage >> fromDataDictionary [ - title := self title. - story := self story. - self importJournal ifTrue: [ journal := self dataDictionary at: 'journal']. -] - -{ #category : #accessing } -FedWikiPage >> host [ - ^ self url host -] - -{ #category : #accessing } -FedWikiPage >> importJournal [ - ^ importJournal ifNil: [ importJournal := false ] -] - -{ #category : #accessing } -FedWikiPage >> importJournal: aBoolean [ - importJournal := aBoolean -] - -{ #category : #accessing } -FedWikiPage >> isView [ - ^ self url firstPathSegment = 'view' -] - -{ #category : #accessing } -FedWikiPage >> jsonData [ - | dataUrl | - self isView ifFalse: [ - self inform: 'Please provide a view url for the FedWiki page.'. - ^ self]. - dataUrl := self scheme , '://', self host, self titleSegmentUrl, '.json' -] - -{ #category : #accessing } -FedWikiPage >> printOn: aStream [ - super printOn: aStream. - aStream - nextPutAll: '( ', self title, ' | ', self story size asString, ' items story )' -] - -{ #category : #accessing } -FedWikiPage >> scheme [ - ^ self url scheme -] - -{ #category : #accessing } -FedWikiPage >> story [ - ^ self dataDictionary at: 'story' -] - -{ #category : #accessing } -FedWikiPage >> title [ - ^ self dataDictionary at: 'title' -] - -{ #category : #accessing } -FedWikiPage >> titleSegmentUrl [ - self isView ifFalse: [ - self inform: 'Please provide a view url for the FedWiki page.'. - ^ self]. - ^ self url segments last. -] - -{ #category : #accessing } -FedWikiPage >> url [ - ^ url -] - -{ #category : #accessing } -FedWikiPage >> url: aString [ - url := aString asZnUrl -] +Class { + #name : #FedWikiPage, + #superclass : #Object, + #instVars : [ + 'url', + 'title', + 'story', + 'journal', + 'importJournal' + ], + #category : #'TiddlyWiki-Model' +} + +{ #category : #accessing } +FedWikiPage >> dataDictionary [ + | dataUrl | + self isView ifFalse: [ + self inform: 'Please provide a view url for the FedWiki page.'. + ^ self]. + dataUrl := self scheme , '://', self host, '/', self titleSegmentUrl, '.json'. + ^ STONJSON fromString: dataUrl asUrl retrieveContents +] + +{ #category : #accessing } +FedWikiPage >> fromDataDictionary [ + title := self title. + story := self story. + self importJournal ifTrue: [ journal := self dataDictionary at: 'journal']. +] + +{ #category : #accessing } +FedWikiPage >> host [ + ^ self url host +] + +{ #category : #accessing } +FedWikiPage >> importJournal [ + ^ importJournal ifNil: [ importJournal := false ] +] + +{ #category : #accessing } +FedWikiPage >> importJournal: aBoolean [ + importJournal := aBoolean +] + +{ #category : #accessing } +FedWikiPage >> isView [ + ^ self url firstPathSegment = 'view' +] + +{ #category : #accessing } +FedWikiPage >> jsonData [ + | dataUrl | + self isView ifFalse: [ + self inform: 'Please provide a view url for the FedWiki page.'. + ^ self]. + dataUrl := self scheme , '://', self host, self titleSegmentUrl, '.json' +] + +{ #category : #accessing } +FedWikiPage >> printOn: aStream [ + super printOn: aStream. + aStream + nextPutAll: '( ', self title, ' | ', self story size asString, ' items story )' +] + +{ #category : #accessing } +FedWikiPage >> scheme [ + ^ self url scheme +] + +{ #category : #accessing } +FedWikiPage >> story [ + ^ self dataDictionary at: 'story' +] + +{ #category : #accessing } +FedWikiPage >> title [ + ^ self dataDictionary at: 'title' +] + +{ #category : #accessing } +FedWikiPage >> titleSegmentUrl [ + self isView ifFalse: [ + self inform: 'Please provide a view url for the FedWiki page.'. + ^ self]. + ^ self url segments last. +] + +{ #category : #accessing } +FedWikiPage >> url [ + ^ url +] + +{ #category : #accessing } +FedWikiPage >> url: aString [ + url := aString asZnUrl +] diff --git a/repository/TiddlyWiki/ManifestTiddlyWiki.class.st b/repository/TiddlyWiki/ManifestTiddlyWiki.class.st index 4fdfbf7..1391df9 100644 --- a/repository/TiddlyWiki/ManifestTiddlyWiki.class.st +++ b/repository/TiddlyWiki/ManifestTiddlyWiki.class.st @@ -1,13 +1,13 @@ -" -Please describe the package using the class comment of the included manifest class. The manifest class also includes other additional metadata for the package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser -" -Class { - #name : #ManifestTiddlyWiki, - #superclass : #PackageManifest, - #category : #'TiddlyWiki-Manifest' -} - -{ #category : #'code-critics' } -ManifestTiddlyWiki class >> ruleLongMethodsRuleV1FalsePositive [ - ^ #(#(#(#RGMethodDefinition #(#Tiddler #fromDictionary: #false)) #'2022-09-01T15:34:03.846371-05:00') ) -] +" +Please describe the package using the class comment of the included manifest class. The manifest class also includes other additional metadata for the package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser +" +Class { + #name : #ManifestTiddlyWiki, + #superclass : #PackageManifest, + #category : #'TiddlyWiki-Manifest' +} + +{ #category : #'code-critics' } +ManifestTiddlyWiki class >> ruleLongMethodsRuleV1FalsePositive [ + ^ #(#(#(#RGMethodDefinition #(#Tiddler #fromDictionary: #false)) #'2022-09-01T15:34:03.846371-05:00') ) +] diff --git a/repository/TiddlyWiki/OrderedDictionary.extension.st b/repository/TiddlyWiki/OrderedDictionary.extension.st index e5ef9e9..5baab10 100644 --- a/repository/TiddlyWiki/OrderedDictionary.extension.st +++ b/repository/TiddlyWiki/OrderedDictionary.extension.st @@ -1,15 +1,15 @@ -Extension { #name : #OrderedDictionary } - -{ #category : #'*TiddlyWiki' } -OrderedDictionary >> asTiddler [ - | tiddlerFields response | - response := Tiddler new. - tiddlerFields := response class slotNames copyWithoutAll: #('wiki' 'customFields'). - self keysAndValuesDo: [ :key :value | - (tiddlerFields includes: key) - ifFalse: [ - response customFields at: key put: value ] - ifTrue: [ response writeSlotNamed: key value: value ] - ]. - ^ response -] +Extension { #name : #OrderedDictionary } + +{ #category : #'*TiddlyWiki' } +OrderedDictionary >> asTiddler [ + | tiddlerFields response | + response := Tiddler new. + tiddlerFields := response class slotNames copyWithoutAll: #('wiki' 'customFields'). + self keysAndValuesDo: [ :key :value | + (tiddlerFields includes: key) + ifFalse: [ + response customFields at: key put: value ] + ifTrue: [ response writeSlotNamed: key value: value ] + ]. + ^ response +] diff --git a/repository/TiddlyWiki/String.extension.st b/repository/TiddlyWiki/String.extension.st index 7d69f20..792f677 100644 --- a/repository/TiddlyWiki/String.extension.st +++ b/repository/TiddlyWiki/String.extension.st @@ -1,22 +1,22 @@ -Extension { #name : #String } - -{ #category : #'*TiddlyWiki' } -String >> asDateAndTimeForTiddler [ - - | date | - date := OrderedCollection new. - 1 to: 4 do: [ :i | date add: (self at: i) ]. - date add: '-'. - 5 to: 6 do: [ :i | date add: (self at: i) ]. - date add: '-'. - 7 to: 8 do: [ :i | date add: (self at: i) ]. - date add: 'T'. - 9 to: 10 do: [ :i | date add: (self at: i) ]. - date add: ':'. - 11 to: 12 do: [ :i | date add: (self at: i) ]. - date add: ':'. - 13 to: 14 do: [ :i | date add: (self at: i) ]. - date add: '.'. - 15 to: 17 do: [ :i | date add: (self at: i) ]. - ^ ((date joinUsing: ''), '+00:00') asDateAndTime -] +Extension { #name : #String } + +{ #category : #'*TiddlyWiki' } +String >> asDateAndTimeForTiddler [ + + | date | + date := OrderedCollection new. + 1 to: 4 do: [ :i | date add: (self at: i) ]. + date add: '-'. + 5 to: 6 do: [ :i | date add: (self at: i) ]. + date add: '-'. + 7 to: 8 do: [ :i | date add: (self at: i) ]. + date add: 'T'. + 9 to: 10 do: [ :i | date add: (self at: i) ]. + date add: ':'. + 11 to: 12 do: [ :i | date add: (self at: i) ]. + date add: ':'. + 13 to: 14 do: [ :i | date add: (self at: i) ]. + date add: '.'. + 15 to: 17 do: [ :i | date add: (self at: i) ]. + ^ ((date joinUsing: ''), '+00:00') asDateAndTime +] diff --git a/repository/TiddlyWiki/TWSeed.class.st b/repository/TiddlyWiki/TWSeed.class.st index bd4c1d7..0149124 100644 --- a/repository/TiddlyWiki/TWSeed.class.st +++ b/repository/TiddlyWiki/TWSeed.class.st @@ -1,139 +1,139 @@ -Class { - #name : #TWSeed, - #superclass : #Object, - #instVars : [ - 'name', - 'demo' - ], - #classVars : [ - 'list' - ], - #category : #'TiddlyWiki-Model' -} - -{ #category : #accessing } -TWSeed class >> default [ - - ^ self selectSeed: 'ProjectifyMod' -] - -{ #category : #accessing } -TWSeed class >> deleteWikiFileFromFolder: folder andSubfolder: shortName [ - - | file | - file := folder / shortName / 'index.html'. - file exists ifFalse: [^ self]. - ^ file ensureDelete. -] - -{ #category : #accessing } -TWSeed class >> initialize [ - - super initialize. - list := OrderedCollection new. - list - add: (self new - name: 'ProjectifyMod'; - demo: 'https://mutabit.com/repos.fossil/tiddlywiki/uv/seeds/projectify/projectify-mod.html'); - add: (self new - name: 'Wikilexias'; - demo: 'https://mutabit.com/repos.fossil/tiddlywiki/uv/seeds/wikilexias/wikilexias.html'); - add: (self new - name: 'NotebookMod'; - demo: 'https://mutabit.com/repos.fossil/tiddlywiki/uv/seeds/notebook/notebook-mod.html'); - add: (self new - name: 'Grafoscopedia'; - demo: 'https://mutabit.com/repos.fossil/grafoscopedia/uv/'); - add: (self new - name: 'Holonica'; - demo: 'https://mutabit.com/repos.fossil/holonica/uv/'); - add: (self new - name: 'Krystal Whitespace'; - demo: 'https://krytsal-whitespace.tiddlyhost.com/'). - ^ self - -] - -{ #category : #accessing } -TWSeed class >> install: seedName into: folder as: shortName [ - - | file url seedFile subfolder | - seedFile := self selectSeed: seedName. - subfolder := (folder / shortName) ensureCreateDirectory. - file := subfolder / 'index.html'. - file exists - ifTrue: [ self inform: 'Index file in the wiki subfolder already exists. Please choose: - 1 select another folder + shortName combination or - 2 run: - self deleteWikiFileFromFolder: folder andSubfolder: shortName.'. - ^ self - ]. - url := seedFile demo. - url asUrl saveContentsToFile: file. - ^ TiddlyWiki new - file: file; - name: shortName. -] - -{ #category : #accessing } -TWSeed class >> installDefaultInto: folder as: shortName [ - - ^ self install: 'ProjectifyMod' into: folder as: shortName -] - -{ #category : #accessing } -TWSeed class >> list [ - - ^ list - ifNil: [ self initialize. - ^ self list. - ] - -] - -{ #category : #accessing } -TWSeed class >> preview: wikiSeedName [ - - WebBrowser openOn: (self selectSeed: wikiSeedName) demo. -] - -{ #category : #accessing } -TWSeed class >> selectSeed: aSeedName [ - - ^ (self list select: [ :seed | seed name = aSeedName ]) first -] - -{ #category : #accessing } -TWSeed >> demo [ - - ^ demo -] - -{ #category : #accessing } -TWSeed >> demo: anUrl [ - - demo := anUrl asZnUrl -] - -{ #category : #accessing } -TWSeed >> name [ - ^ name -] - -{ #category : #accessing } -TWSeed >> name: aString [ - name := aString -] - -{ #category : #accessing } -TWSeed >> preview: anObject [ - - ^ demo := anObject -] - -{ #category : #accessing } -TWSeed >> printOn: aStream [ -super printOn: aStream. - aStream - nextPutAll: '( ', self name, ' )' -] +Class { + #name : #TWSeed, + #superclass : #Object, + #instVars : [ + 'name', + 'demo' + ], + #classVars : [ + 'list' + ], + #category : #'TiddlyWiki-Model' +} + +{ #category : #accessing } +TWSeed class >> default [ + + ^ self selectSeed: 'ProjectifyMod' +] + +{ #category : #accessing } +TWSeed class >> deleteWikiFileFromFolder: folder andSubfolder: shortName [ + + | file | + file := folder / shortName / 'index.html'. + file exists ifFalse: [^ self]. + ^ file ensureDelete. +] + +{ #category : #accessing } +TWSeed class >> initialize [ + + super initialize. + list := OrderedCollection new. + list + add: (self new + name: 'ProjectifyMod'; + demo: 'https://mutabit.com/repos.fossil/tiddlywiki/uv/seeds/projectify/projectify-mod.html'); + add: (self new + name: 'Wikilexias'; + demo: 'https://mutabit.com/repos.fossil/tiddlywiki/uv/seeds/wikilexias/wikilexias.html'); + add: (self new + name: 'NotebookMod'; + demo: 'https://mutabit.com/repos.fossil/tiddlywiki/uv/seeds/notebook/notebook-mod.html'); + add: (self new + name: 'Grafoscopedia'; + demo: 'https://mutabit.com/repos.fossil/grafoscopedia/uv/'); + add: (self new + name: 'Holonica'; + demo: 'https://mutabit.com/repos.fossil/holonica/uv/'); + add: (self new + name: 'Krystal Whitespace'; + demo: 'https://krytsal-whitespace.tiddlyhost.com/'). + ^ self + +] + +{ #category : #accessing } +TWSeed class >> install: seedName into: folder as: shortName [ + + | file url seedFile subfolder | + seedFile := self selectSeed: seedName. + subfolder := (folder / shortName) ensureCreateDirectory. + file := subfolder / 'index.html'. + file exists + ifTrue: [ self inform: 'Index file in the wiki subfolder already exists. Please choose: + 1 select another folder + shortName combination or + 2 run: + self deleteWikiFileFromFolder: folder andSubfolder: shortName.'. + ^ self + ]. + url := seedFile demo. + url asUrl saveContentsToFile: file. + ^ TiddlyWiki new + file: file; + name: shortName. +] + +{ #category : #accessing } +TWSeed class >> installDefaultInto: folder as: shortName [ + + ^ self install: 'ProjectifyMod' into: folder as: shortName +] + +{ #category : #accessing } +TWSeed class >> list [ + + ^ list + ifNil: [ self initialize. + ^ self list. + ] + +] + +{ #category : #accessing } +TWSeed class >> preview: wikiSeedName [ + + WebBrowser openOn: (self selectSeed: wikiSeedName) demo. +] + +{ #category : #accessing } +TWSeed class >> selectSeed: aSeedName [ + + ^ (self list select: [ :seed | seed name = aSeedName ]) first +] + +{ #category : #accessing } +TWSeed >> demo [ + + ^ demo +] + +{ #category : #accessing } +TWSeed >> demo: anUrl [ + + demo := anUrl asZnUrl +] + +{ #category : #accessing } +TWSeed >> name [ + ^ name +] + +{ #category : #accessing } +TWSeed >> name: aString [ + name := aString +] + +{ #category : #accessing } +TWSeed >> preview: anObject [ + + ^ demo := anObject +] + +{ #category : #accessing } +TWSeed >> printOn: aStream [ +super printOn: aStream. + aStream + nextPutAll: '( ', self name, ' )' +] diff --git a/repository/TiddlyWiki/TWSeedTest.class.st b/repository/TiddlyWiki/TWSeedTest.class.st index 21113d7..1a2d018 100644 --- a/repository/TiddlyWiki/TWSeedTest.class.st +++ b/repository/TiddlyWiki/TWSeedTest.class.st @@ -1,31 +1,31 @@ -Class { - #name : #TWSeedTest, - #superclass : #TestCase, - #category : #'TiddlyWiki-TiddlyWiki' -} - -{ #category : #accessing } -TWSeedTest >> testCreateAlternativeSeed [ - - | seed folder | - folder := FileLocator temp / 'Wikilexias'. - folder ensureDeleteAll. - seed := TWSeed install: 'Wikilexias' into: FileLocator temp as: 'Wikilexias'. - self assert: seed file equals: (FileLocator temp / 'Wikilexias' / 'index.html') -] - -{ #category : #accessing } -TWSeedTest >> testDefaultIsSeed [ - - | seed | - seed := TWSeed default. - self assert: seed class equals: TWSeed -] - -{ #category : #accessing } -TWSeedTest >> testListIsNotEmpty [ - - | seed | - seed := TWSeed list. - self assert: seed size >= 1 -] +Class { + #name : #TWSeedTest, + #superclass : #TestCase, + #category : #'TiddlyWiki-TiddlyWiki' +} + +{ #category : #accessing } +TWSeedTest >> testCreateAlternativeSeed [ + + | seed folder | + folder := FileLocator temp / 'Wikilexias'. + folder ensureDeleteAll. + seed := TWSeed install: 'Wikilexias' into: FileLocator temp as: 'Wikilexias'. + self assert: seed file equals: (FileLocator temp / 'Wikilexias' / 'index.html') +] + +{ #category : #accessing } +TWSeedTest >> testDefaultIsSeed [ + + | seed | + seed := TWSeed default. + self assert: seed class equals: TWSeed +] + +{ #category : #accessing } +TWSeedTest >> testListIsNotEmpty [ + + | seed | + seed := TWSeed list. + self assert: seed size >= 1 +] diff --git a/repository/TiddlyWiki/TWServer.class.st b/repository/TiddlyWiki/TWServer.class.st index 213cd59..39572d4 100644 --- a/repository/TiddlyWiki/TWServer.class.st +++ b/repository/TiddlyWiki/TWServer.class.st @@ -1,77 +1,77 @@ -Class { - #name : #TWServer, - #superclass : #Object, - #instVars : [ - 'wikis', - 'webServer' - ], - #category : #TiddlyWiki -} - -{ #category : #'instance creation' } -TWServer class >> new [ - - | instance | - instance := super new. - ^ instance - wikis: Dictionary new; - webServer: TLWebserver new - -] - -{ #category : #'export - json' } -TWServer >> exportTiddlersFrom: aWikiName tagged: aTag into: aFolder [ - - | wiki | - wiki := wikis at: aWikiName. - ^ wiki exportJSONTiddlersTagged: aTag in: aFolder -] - -{ #category : #accessing } -TWServer >> initWikiTagDynamicRoute [ - - webServer teapot - GET: '//' -> [ :req | (self exportTiddlersFrom: (req at: #wiki) tagged: (req at: #tag) into: FileLocator temp) contents ]; - output: #text -] - -{ #category : #accessing } -TWServer >> port: aPortInteger [ - - webServer configuration: { #port -> aPortInteger }; - refreshTeapot -] - -{ #category : #accessing } -TWServer >> removeAllDynamicRoutes [ - - webServer teapot removeAllDynamicRoutes -] - -{ #category : #accessing } -TWServer >> startAndBrowse [ - - webServer start. - webServer teapot browse -] - -{ #category : #accessing } -TWServer >> webServer: aTealightWebServer [ - - webServer := aTealightWebServer -] - -{ #category : #accessing } -TWServer >> wikiNames [ - - | return | - return := OrderedCollection new. - wikis keysDo: [ :key | return add: key ]. - ^ return -] - -{ #category : #accessing } -TWServer >> wikis: aTiddlyWikisDictionary [ - - wikis := aTiddlyWikisDictionary -] +Class { + #name : #TWServer, + #superclass : #Object, + #instVars : [ + 'wikis', + 'webServer' + ], + #category : #TiddlyWiki +} + +{ #category : #'instance creation' } +TWServer class >> new [ + + | instance | + instance := super new. + ^ instance + wikis: Dictionary new; + webServer: TLWebserver new + +] + +{ #category : #'export - json' } +TWServer >> exportTiddlersFrom: aWikiName tagged: aTag into: aFolder [ + + | wiki | + wiki := wikis at: aWikiName. + ^ wiki exportJSONTiddlersTagged: aTag in: aFolder +] + +{ #category : #accessing } +TWServer >> initWikiTagDynamicRoute [ + + webServer teapot + GET: '//' -> [ :req | (self exportTiddlersFrom: (req at: #wiki) tagged: (req at: #tag) into: FileLocator temp) contents ]; + output: #text +] + +{ #category : #accessing } +TWServer >> port: aPortInteger [ + + webServer configuration: { #port -> aPortInteger }; + refreshTeapot +] + +{ #category : #accessing } +TWServer >> removeAllDynamicRoutes [ + + webServer teapot removeAllDynamicRoutes +] + +{ #category : #accessing } +TWServer >> startAndBrowse [ + + webServer start. + webServer teapot browse +] + +{ #category : #accessing } +TWServer >> webServer: aTealightWebServer [ + + webServer := aTealightWebServer +] + +{ #category : #accessing } +TWServer >> wikiNames [ + + | return | + return := OrderedCollection new. + wikis keysDo: [ :key | return add: key ]. + ^ return +] + +{ #category : #accessing } +TWServer >> wikis: aTiddlyWikisDictionary [ + + wikis := aTiddlyWikisDictionary +] diff --git a/repository/TiddlyWiki/Tiddler.class.st b/repository/TiddlyWiki/Tiddler.class.st index 98f9646..0ce89a9 100644 --- a/repository/TiddlyWiki/Tiddler.class.st +++ b/repository/TiddlyWiki/Tiddler.class.st @@ -1,604 +1,604 @@ -" -I model a Tiddler object in [TiddlyWiki](https://tiddlywiki.com/). - -I implement the standard fields as described in the standard documentation at: - -" -Class { - #name : #Tiddler, - #superclass : #Object, - #instVars : [ - 'title', - 'text', - 'modified', - 'created', - 'creator', - 'tags', - 'type', - 'list', - 'caption', - 'modifier', - 'wiki', - 'customFields', - 'bag', - 'revision' - ], - #category : #'TiddlyWiki-Model' -} - -{ #category : #'instance creation' } -Tiddler class >> nowLocal [ - ^ ((ZTimestampFormat fromString: '20010203160506700') - format: (ZTimestamp fromString: Time nowLocal asDateAndTime asString)) copyFrom: 1 to: 17 -] - -{ #category : #accessing } -Tiddler >> appendPrefixToText: prefix [ - - | textPre | - textPre := self text. - self text: prefix, textPre. - ^ self -] - -{ #category : #accessing } -Tiddler >> asDictionary [ - | response | - response := Dictionary new - at: 'title' put: self title; - at: 'text' put: self text; - at: 'created' put: self created; - at: 'tags' put: self tagsAsString; - at: 'type' put: self type; - at: 'creator' put: self creator; - at: 'modifier' put: self modifier; - at: 'modified' put: self modified; - at: 'bag' put: self bag; - at: 'revision' put: self revision; - at: 'caption' put: self caption; - yourself. - self customFields ifNotEmpty: [ - self customFields keysAndValuesDo: [:k :v | - response at: k put: v - ] - ]. - ^ response -] - -{ #category : #converting } -Tiddler >> asJson [ - ^ STONJSON toStringPretty: { self asDictionary } -] - -{ #category : #converting } -Tiddler >> asJsonString [ - ^ STONJSON toStringPretty: self asDictionary -] - -{ #category : #accessing } -Tiddler >> asJsonTempFile [ - ^ MarkupFile exportAsFileOn: FileLocator temp / self title, 'json' containing:self asJson - -] - -{ #category : #accessing } -Tiddler >> asStonStringPretty [ - | output temp | - temp := self copy. - temp wiki: nil. - output := '' writeStream. - (STON writer on: output) - newLine: String lf; - prettyPrint: true; - keepNewLines: true; - nextPut: temp. - ^ output contents -] - -{ #category : #accessing } -Tiddler >> bag [ - ^ bag -] - -{ #category : #accessing } -Tiddler >> bag: aString [ - bag := aString -] - -{ #category : #accessing } -Tiddler >> caption [ - - ^ caption -] - -{ #category : #accessing } -Tiddler >> caption: anObject [ - - caption := anObject -] - -{ #category : #accessing } -Tiddler >> created [ - - ^ created ifNil: [ created := self class nowLocal ] -] - -{ #category : #accessing } -Tiddler >> created: anObject [ - - created := anObject -] - -{ #category : #accessing } -Tiddler >> createdAsTWFormat [ - (self created beginsWith: 'NaN') ifTrue: [ self created: self class nowLocal]. - ^ ((ZTimestampFormat fromString: '20010203160506700') - format: (ZTimestamp fromString: self created)) copyFrom: 1 to: 17 -] - -{ #category : #accessing } -Tiddler >> createdReversableEncoded [ - "I encode the tiddler creation date with miliseconds precision in a shorter reversable way - (from 17 characters to 10). - But when tiddlers are created with the same exact date (for example programmatically) - I produce the same encoding (because of reversability). - I recommend to use nanoID instead to get unique visible different identifiers " - | output longDate | - longDate := self createdAsTWFormat. - output := WriteStream on: ''. - 1 to: 14 by: 2 do: [ :i | - output nextPutAll: (longDate copyFrom: i to: i +1) greaseInteger asCharacterDigit greaseString - ]. - output nextPutAll: (longDate copyFrom: 15 to: 17). - ^ output contents -] - -{ #category : #accessing } -Tiddler >> creator [ - - ^ creator -] - -{ #category : #accessing } -Tiddler >> creator: anObject [ - - creator := anObject -] - -{ #category : #accessing } -Tiddler >> customFields [ - ^ customFields ifNil: [ customFields := Dictionary new] -] - -{ #category : #accessing } -Tiddler >> customFieldsWithMediaLinks [ - | response | - response := OrderedDictionary new. - self customFields keysAndValuesDo: [:k :v | - (v endsWithAnyOf: #('mp4' 'jpg' 'jpeg' 'png')) - ifTrue: [response at: k put: v ] - ]. - ^ response -] - -{ #category : #accessing } -Tiddler >> deleteUid [ - self customFields deleteKey: 'uid'. -] - -{ #category : #accessing } -Tiddler >> downloadAndIndexMediaLinksInto: aFolder [ - ^ self customFieldsWithMediaLinks -] - -{ #category : #accessing } -Tiddler >> exportJSONFile [ - - | jsonFile folder | - folder := self wiki folder. - jsonFile := folder / 'tiddlers' / ((self fileName removeSuffix: '.ston'), '.json'). - ^ MarkupFile exportAsFileOn: jsonFile containing:self asJson -] - -{ #category : #accessing } -Tiddler >> exportSTONFile [ - - ^ self exportSTONFileInto: 'tiddlers' -] - -{ #category : #accessing } -Tiddler >> exportSTONFileInto: subfolder [ - - | stonFile | - stonFile := self wiki folder / subfolder / self fileName. - ^ MarkupFile exportAsFileOn: stonFile containing: self asStonStringPretty -] - -{ #category : #accessing } -Tiddler >> exportSTONFileOptimized [ - - | exporter wikiFolder tiddlersFolder | - wikiFolder := self wiki folder. - exporter := MiniDocs appFolder / 'scripts' / 'stringAsFileInto'. - exporter exists ifFalse: [ self installNimFileExporter ]. - tiddlersFolder := wikiFolder / 'tiddlers'. - tiddlersFolder exists ifFalse: [ tiddlersFolder ensureCreateDirectory ]. - - OSSUnixSubprocess new - command: exporter fullName; - arguments: { self asStonStringPretty . self fileName }; - workingDirectory: tiddlersFolder fullName; - runAndWaitOnExitDo: [ :process :outString | ^ tiddlersFolder / self fileName ] -] - -{ #category : #accessing } -Tiddler >> exportWithTemplate: aTemplate [ - ^ aTemplate asMustacheTemplate value: self asDictionary -] - -{ #category : #accessing } -Tiddler >> fileName [ - | dashedTitle sanitized | - dashedTitle := '-' join: (self title substrings collect: [ :each | each ]). - sanitized := dashedTitle copyWithoutAll: #($¿ $? $! $¡ $/). - ^ sanitized , '--', (self uid copyFrom: 1 to: 12), '.ston'. -] - -{ #category : #accessing } -Tiddler >> fromDictionary: aDictionary [ - | customKeys | - self - title: (aDictionary at: 'title'); - text: (aDictionary at: 'text' ifAbsentPut: [ nil ]); - tags: (aDictionary at: 'tags' ifAbsentPut: [ nil ]); - created: (aDictionary at: 'created' ifAbsentPut: [ self class nowLocal ]); - creator: (aDictionary at: 'creator' ifAbsentPut: [ nil ]); - modified: (aDictionary at: 'modified' ifAbsentPut: [ nil ]); - modifier: (aDictionary at: 'modifier' ifAbsentPut: [ nil ]); - type: (aDictionary at: 'type' ifAbsentPut: [ nil ]); - caption: (aDictionary at: 'caption' ifAbsentPut: [ nil ]); - bag: (aDictionary at: 'bag' ifAbsentPut: [ nil ]); - list: (aDictionary at: 'list' ifAbsentPut: [ nil ]); - revision: (aDictionary at: 'revision' ifAbsentPut: [ nil ]). - customKeys := aDictionary keys - copyWithoutAll: (self class instanceVariables collect: [ :each | each name ]). - "(customKeys includes: 'uid') ifFalse: [ self uidGenerator ]." - customKeys do: [:key | | valueTemp | - valueTemp := aDictionary at: key. - valueTemp class = Array - ifTrue: [ self customFields at: key put: (self tiddlersListFrom: valueTemp) ] - ifFalse: [ self customFields at: key put: valueTemp ]. - valueTemp class - ]. -] - -{ #category : #'instance creation' } -Tiddler >> fromMarkdownParsedItems: aCollection [ - | outputStream | - outputStream := '' writeStream. - aCollection children do: [ :each | - each children - ifEmpty: [ self itemContentsStringFor: each into: outputStream ] - ifNotEmpty: [ - each children do: [ :child | - self itemContentsStringFor: child into: outputStream ] ] - ] -] - -{ #category : #accessing } -Tiddler >> gtTextFor: aView [ - - ^ aView textEditor - title: 'Text'; - text: [ text ] -] - -{ #category : #testing } -Tiddler >> hasUID [ - - ^ self customFields includesKey: 'uid' -] - -{ #category : #accessing } -Tiddler >> importFedWikiPage: pageViewUrlString [ - | pageTitle pageViewUrl pageData | - pageViewUrl := pageViewUrlString asZnUrl. - pageTitle := pageViewUrl segments second. - pageData := (pageViewUrl scheme, '://', pageViewUrl host, '/', pageTitle, '.json') asZnUrl. - ^ STONJSON fromString: pageData retrieveContents -] - -{ #category : #testing } -Tiddler >> isImage [ - - ^ self type ifNil: [ ^ false ]; - beginsWith: 'image/' -] - -{ #category : #testing } -Tiddler >> isJavascript [ - - ^ self type = 'application/javascript' -] - -{ #category : #testing } -Tiddler >> isMarkdown [ - - ^ self type = 'text/x-markdown' -] - -{ #category : #testing } -Tiddler >> isNilType [ - - ^ self type = nil -] - -{ #category : #testing } -Tiddler >> isPDF [ - - ^ self type = 'application/pdf' -] - -{ #category : #testing } -Tiddler >> isShadow [ - - ^ self title beginsWith: '$:/' -] - -{ #category : #testing } -Tiddler >> isTW5Type [ - - ^ self type = 'text/vnd.tiddlywiki' -] - -{ #category : #testing } -Tiddler >> isTextPlain [ - - ^ self type = 'text/plain' -] - -{ #category : #testing } -Tiddler >> isXTiddlerDictionary [ - - ^ self type = 'application/x-tiddler-dictionary' -] - -{ #category : #utilities } -Tiddler >> itemContentsStringFor: item into: stream [ - stream - nextPutAll: item text; - nextPut: Character cr; - nextPut: Character cr -] - -{ #category : #accessing } -Tiddler >> linkedTiddlers [ - "At the begining we are going to introduce 'pureTiddlers' as thos included in the wiki which are not linked - via aliases. Future versions of this method sould included internal aliased tiddlers." - | pureTiddlersTitles | - self rawLinks ifNil: [ ^nil ]. - pureTiddlersTitles := self rawLinks difference: self rawAliasedLinks. - ^ self wiki tiddlers select: [:tiddler | pureTiddlersTitles includes: tiddler title ]. -] - -{ #category : #accessing } -Tiddler >> list [ - - ^ list -] - -{ #category : #accessing } -Tiddler >> list: anObject [ - - list := anObject -] - -{ #category : #accessing } -Tiddler >> listedTiddlers [ - "I export all tiddlers in the list field as an alphabetic collection. - Future versions should preserve the order in the list. - Notice that while '#list' only gives the titles of the listed tiddlers, - I return them as proper tiddler objects." - | remainList remainListArray listedTiddlers | - self list ifNil: [^ nil ]. - remainList := self list copy. - self manualLinksList do: [:manualLink | - remainList := remainList copyReplaceAll: manualLink with: '' - ]. - remainListArray := (remainList copyReplaceAll: '[[]]' with: '') withBlanksCondensed splitOn: Character space. - listedTiddlers := self manualLinksList, remainListArray. - ^ self wiki tiddlers select: [:tiddler | listedTiddlers includes: tiddler title ]. - -] - -{ #category : #accessing } -Tiddler >> manualLinksList [ - self list ifNil: [^ nil]. - ^ WikiTextGrammar new linkSea star parse: self list. -] - -{ #category : #utilities } -Tiddler >> markdownLinksAsWikiText [ - "I'm useful to convert _internal_ links between formats, as is a common pattern - found when migrating content from Markdown to TiddlyWiki's WikiText. - I DON'T work on external links. A better regex could be used for that. - See: - - https://davidwells.io/snippets/regex-match-markdown-links - - http://blog.michaelperrin.fr/2019/02/04/advanced-regular-expressions/" - | markdownLinks | - markdownLinks := (self text splitOn: Character space) select: [:each | each matchesRegex: '\[(.+)\)']. - markdownLinks ifEmpty: [^ self]. - ^ markdownLinks -] - -{ #category : #accessing } -Tiddler >> modified [ - - ^ modified -] - -{ #category : #accessing } -Tiddler >> modified: anObject [ - - modified := anObject -] - -{ #category : #accessing } -Tiddler >> modifier [ - - ^ modifier -] - -{ #category : #accessing } -Tiddler >> modifier: anObject [ - - modifier := anObject -] - -{ #category : #accessing } -Tiddler >> printOn: aStream [ - super printOn: aStream. - aStream - nextPutAll: '( ', self title, ' )' -] - -{ #category : #accessing } -Tiddler >> rawAliasedLinks [ - ^ self rawLinks select: [ :each | each includesSubstring: '|' ] -] - -{ #category : #accessing } -Tiddler >> rawLinks [ - self text ifNil: [ ^ Set new ]. - ^ (WikiTextGrammar new linkSea star parse: self text) asSet -] - -{ #category : #accessing } -Tiddler >> removeTag: aTag [ - - | tagsPre | - tagsPre := self tags. - self tags: ('' join: (tagsPre splitOn: aTag)). - ^ self -] - -{ #category : #accessing } -Tiddler >> renameExternalMediaLinksInto: relativePath [ - "This first implementation only renames external media links in custom fields. - Further development should offer the possibility to rename also the external media - appearing in the tiddler's text." - self customFieldsWithMediaLinks keysAndValuesDo: [:customField :oldLink | | link name | - link := oldLink asUrl. - link hasScheme ifFalse: [^ self ]. - name := link segments last copyWithoutAll: '-'. - name := name asDashedLowercase. - name := (relativePath, '/', NanoID generate, '--', name). - self customFields - at: customField, '--original' put: oldLink; - at: customField put: name -]. -] - -{ #category : #accessing } -Tiddler >> revision [ - ^ revision -] - -{ #category : #accessing } -Tiddler >> revision: aNumberString [ - revision := aNumberString -] - -{ #category : #accessing } -Tiddler >> tags [ - - ^ tags ifNil: [tags := Set new] -] - -{ #category : #accessing } -Tiddler >> tags: anObject [ - - tags := anObject -] - -{ #category : #accessing } -Tiddler >> tagsAsString [ - | response | - self tags ifEmpty: [^ '' ]. - response := '' writeStream. - self tags do: [:tag | - response nextPutAll: '[[', tag, ']]' - ]. - ^ response contents -] - -{ #category : #accessing } -Tiddler >> text [ - - ^ text -] - -{ #category : #accessing } -Tiddler >> text: anObject [ - - text := anObject -] - -{ #category : #accessing } -Tiddler >> tiddlersListFrom: anArray [ - | output | - output := '' writeStream. - - anArray doWithIndex: [:each :i | - output nextPutAll: '[[', each asString, ']]'. - i = anArray size ifFalse: [ output nextPutAll: Character space asString ]. - ]. - ^ output contents. -] - -{ #category : #accessing } -Tiddler >> title [ - - ^ title -] - -{ #category : #accessing } -Tiddler >> title: anObject [ - - title := anObject -] - -{ #category : #accessing } -Tiddler >> type [ - - ^ type -] - -{ #category : #accessing } -Tiddler >> type: anObject [ - - type := anObject -] - -{ #category : #accessing } -Tiddler >> uid [ - ^ self customFields at: 'uid' ifAbsentPut: [ self uidGenerator ]. - -] - -{ #category : #accessing } -Tiddler >> uidGenerator [ - - ^ self customFields at: 'uid' put: NanoID generate. - -] - -{ #category : #accessing } -Tiddler >> wiki [ - ^ wiki -] - -{ #category : #accessing } -Tiddler >> wiki: aTiddlyWiki [ - wiki := aTiddlyWiki -] +" +I model a Tiddler object in [TiddlyWiki](https://tiddlywiki.com/). + +I implement the standard fields as described in the standard documentation at: + +" +Class { + #name : #Tiddler, + #superclass : #Object, + #instVars : [ + 'title', + 'text', + 'modified', + 'created', + 'creator', + 'tags', + 'type', + 'list', + 'caption', + 'modifier', + 'wiki', + 'customFields', + 'bag', + 'revision' + ], + #category : #'TiddlyWiki-Model' +} + +{ #category : #'instance creation' } +Tiddler class >> nowLocal [ + ^ ((ZTimestampFormat fromString: '20010203160506700') + format: (ZTimestamp fromString: Time nowLocal asDateAndTime asString)) copyFrom: 1 to: 17 +] + +{ #category : #accessing } +Tiddler >> appendPrefixToText: prefix [ + + | textPre | + textPre := self text. + self text: prefix, textPre. + ^ self +] + +{ #category : #accessing } +Tiddler >> asDictionary [ + | response | + response := Dictionary new + at: 'title' put: self title; + at: 'text' put: self text; + at: 'created' put: self created; + at: 'tags' put: self tagsAsString; + at: 'type' put: self type; + at: 'creator' put: self creator; + at: 'modifier' put: self modifier; + at: 'modified' put: self modified; + at: 'bag' put: self bag; + at: 'revision' put: self revision; + at: 'caption' put: self caption; + yourself. + self customFields ifNotEmpty: [ + self customFields keysAndValuesDo: [:k :v | + response at: k put: v + ] + ]. + ^ response +] + +{ #category : #converting } +Tiddler >> asJson [ + ^ STONJSON toStringPretty: { self asDictionary } +] + +{ #category : #converting } +Tiddler >> asJsonString [ + ^ STONJSON toStringPretty: self asDictionary +] + +{ #category : #accessing } +Tiddler >> asJsonTempFile [ + ^ MarkupFile exportAsFileOn: FileLocator temp / self title, 'json' containing:self asJson + +] + +{ #category : #accessing } +Tiddler >> asStonStringPretty [ + | output temp | + temp := self copy. + temp wiki: nil. + output := '' writeStream. + (STON writer on: output) + newLine: String lf; + prettyPrint: true; + keepNewLines: true; + nextPut: temp. + ^ output contents +] + +{ #category : #accessing } +Tiddler >> bag [ + ^ bag +] + +{ #category : #accessing } +Tiddler >> bag: aString [ + bag := aString +] + +{ #category : #accessing } +Tiddler >> caption [ + + ^ caption +] + +{ #category : #accessing } +Tiddler >> caption: anObject [ + + caption := anObject +] + +{ #category : #accessing } +Tiddler >> created [ + + ^ created ifNil: [ created := self class nowLocal ] +] + +{ #category : #accessing } +Tiddler >> created: anObject [ + + created := anObject +] + +{ #category : #accessing } +Tiddler >> createdAsTWFormat [ + (self created beginsWith: 'NaN') ifTrue: [ self created: self class nowLocal]. + ^ ((ZTimestampFormat fromString: '20010203160506700') + format: (ZTimestamp fromString: self created)) copyFrom: 1 to: 17 +] + +{ #category : #accessing } +Tiddler >> createdReversableEncoded [ + "I encode the tiddler creation date with miliseconds precision in a shorter reversable way + (from 17 characters to 10). + But when tiddlers are created with the same exact date (for example programmatically) + I produce the same encoding (because of reversability). + I recommend to use nanoID instead to get unique visible different identifiers " + | output longDate | + longDate := self createdAsTWFormat. + output := WriteStream on: ''. + 1 to: 14 by: 2 do: [ :i | + output nextPutAll: (longDate copyFrom: i to: i +1) greaseInteger asCharacterDigit greaseString + ]. + output nextPutAll: (longDate copyFrom: 15 to: 17). + ^ output contents +] + +{ #category : #accessing } +Tiddler >> creator [ + + ^ creator +] + +{ #category : #accessing } +Tiddler >> creator: anObject [ + + creator := anObject +] + +{ #category : #accessing } +Tiddler >> customFields [ + ^ customFields ifNil: [ customFields := Dictionary new] +] + +{ #category : #accessing } +Tiddler >> customFieldsWithMediaLinks [ + | response | + response := OrderedDictionary new. + self customFields keysAndValuesDo: [:k :v | + (v endsWithAnyOf: #('mp4' 'jpg' 'jpeg' 'png')) + ifTrue: [response at: k put: v ] + ]. + ^ response +] + +{ #category : #accessing } +Tiddler >> deleteUid [ + self customFields deleteKey: 'uid'. +] + +{ #category : #accessing } +Tiddler >> downloadAndIndexMediaLinksInto: aFolder [ + ^ self customFieldsWithMediaLinks +] + +{ #category : #accessing } +Tiddler >> exportJSONFile [ + + | jsonFile folder | + folder := self wiki folder. + jsonFile := folder / 'tiddlers' / ((self fileName removeSuffix: '.ston'), '.json'). + ^ MarkupFile exportAsFileOn: jsonFile containing:self asJson +] + +{ #category : #accessing } +Tiddler >> exportSTONFile [ + + ^ self exportSTONFileInto: 'tiddlers' +] + +{ #category : #accessing } +Tiddler >> exportSTONFileInto: subfolder [ + + | stonFile | + stonFile := self wiki folder / subfolder / self fileName. + ^ MarkupFile exportAsFileOn: stonFile containing: self asStonStringPretty +] + +{ #category : #accessing } +Tiddler >> exportSTONFileOptimized [ + + | exporter wikiFolder tiddlersFolder | + wikiFolder := self wiki folder. + exporter := MiniDocs appFolder / 'scripts' / 'stringAsFileInto'. + exporter exists ifFalse: [ self installNimFileExporter ]. + tiddlersFolder := wikiFolder / 'tiddlers'. + tiddlersFolder exists ifFalse: [ tiddlersFolder ensureCreateDirectory ]. + + OSSUnixSubprocess new + command: exporter fullName; + arguments: { self asStonStringPretty . self fileName }; + workingDirectory: tiddlersFolder fullName; + runAndWaitOnExitDo: [ :process :outString | ^ tiddlersFolder / self fileName ] +] + +{ #category : #accessing } +Tiddler >> exportWithTemplate: aTemplate [ + ^ aTemplate asMustacheTemplate value: self asDictionary +] + +{ #category : #accessing } +Tiddler >> fileName [ + | dashedTitle sanitized | + dashedTitle := '-' join: (self title substrings collect: [ :each | each ]). + sanitized := dashedTitle copyWithoutAll: #($¿ $? $! $¡ $/). + ^ sanitized , '--', (self uid copyFrom: 1 to: 12), '.ston'. +] + +{ #category : #accessing } +Tiddler >> fromDictionary: aDictionary [ + | customKeys | + self + title: (aDictionary at: 'title'); + text: (aDictionary at: 'text' ifAbsentPut: [ nil ]); + tags: (aDictionary at: 'tags' ifAbsentPut: [ nil ]); + created: (aDictionary at: 'created' ifAbsentPut: [ self class nowLocal ]); + creator: (aDictionary at: 'creator' ifAbsentPut: [ nil ]); + modified: (aDictionary at: 'modified' ifAbsentPut: [ nil ]); + modifier: (aDictionary at: 'modifier' ifAbsentPut: [ nil ]); + type: (aDictionary at: 'type' ifAbsentPut: [ nil ]); + caption: (aDictionary at: 'caption' ifAbsentPut: [ nil ]); + bag: (aDictionary at: 'bag' ifAbsentPut: [ nil ]); + list: (aDictionary at: 'list' ifAbsentPut: [ nil ]); + revision: (aDictionary at: 'revision' ifAbsentPut: [ nil ]). + customKeys := aDictionary keys + copyWithoutAll: (self class instanceVariables collect: [ :each | each name ]). + "(customKeys includes: 'uid') ifFalse: [ self uidGenerator ]." + customKeys do: [:key | | valueTemp | + valueTemp := aDictionary at: key. + valueTemp class = Array + ifTrue: [ self customFields at: key put: (self tiddlersListFrom: valueTemp) ] + ifFalse: [ self customFields at: key put: valueTemp ]. + valueTemp class + ]. +] + +{ #category : #'instance creation' } +Tiddler >> fromMarkdownParsedItems: aCollection [ + | outputStream | + outputStream := '' writeStream. + aCollection children do: [ :each | + each children + ifEmpty: [ self itemContentsStringFor: each into: outputStream ] + ifNotEmpty: [ + each children do: [ :child | + self itemContentsStringFor: child into: outputStream ] ] + ] +] + +{ #category : #accessing } +Tiddler >> gtTextFor: aView [ + + ^ aView textEditor + title: 'Text'; + text: [ text ] +] + +{ #category : #testing } +Tiddler >> hasUID [ + + ^ self customFields includesKey: 'uid' +] + +{ #category : #accessing } +Tiddler >> importFedWikiPage: pageViewUrlString [ + | pageTitle pageViewUrl pageData | + pageViewUrl := pageViewUrlString asZnUrl. + pageTitle := pageViewUrl segments second. + pageData := (pageViewUrl scheme, '://', pageViewUrl host, '/', pageTitle, '.json') asZnUrl. + ^ STONJSON fromString: pageData retrieveContents +] + +{ #category : #testing } +Tiddler >> isImage [ + + ^ self type ifNil: [ ^ false ]; + beginsWith: 'image/' +] + +{ #category : #testing } +Tiddler >> isJavascript [ + + ^ self type = 'application/javascript' +] + +{ #category : #testing } +Tiddler >> isMarkdown [ + + ^ self type = 'text/x-markdown' +] + +{ #category : #testing } +Tiddler >> isNilType [ + + ^ self type = nil +] + +{ #category : #testing } +Tiddler >> isPDF [ + + ^ self type = 'application/pdf' +] + +{ #category : #testing } +Tiddler >> isShadow [ + + ^ self title beginsWith: '$:/' +] + +{ #category : #testing } +Tiddler >> isTW5Type [ + + ^ self type = 'text/vnd.tiddlywiki' +] + +{ #category : #testing } +Tiddler >> isTextPlain [ + + ^ self type = 'text/plain' +] + +{ #category : #testing } +Tiddler >> isXTiddlerDictionary [ + + ^ self type = 'application/x-tiddler-dictionary' +] + +{ #category : #utilities } +Tiddler >> itemContentsStringFor: item into: stream [ + stream + nextPutAll: item text; + nextPut: Character cr; + nextPut: Character cr +] + +{ #category : #accessing } +Tiddler >> linkedTiddlers [ + "At the begining we are going to introduce 'pureTiddlers' as thos included in the wiki which are not linked + via aliases. Future versions of this method sould included internal aliased tiddlers." + | pureTiddlersTitles | + self rawLinks ifNil: [ ^nil ]. + pureTiddlersTitles := self rawLinks difference: self rawAliasedLinks. + ^ self wiki tiddlers select: [:tiddler | pureTiddlersTitles includes: tiddler title ]. +] + +{ #category : #accessing } +Tiddler >> list [ + + ^ list +] + +{ #category : #accessing } +Tiddler >> list: anObject [ + + list := anObject +] + +{ #category : #accessing } +Tiddler >> listedTiddlers [ + "I export all tiddlers in the list field as an alphabetic collection. + Future versions should preserve the order in the list. + Notice that while '#list' only gives the titles of the listed tiddlers, + I return them as proper tiddler objects." + | remainList remainListArray listedTiddlers | + self list ifNil: [^ nil ]. + remainList := self list copy. + self manualLinksList do: [:manualLink | + remainList := remainList copyReplaceAll: manualLink with: '' + ]. + remainListArray := (remainList copyReplaceAll: '[[]]' with: '') withBlanksCondensed splitOn: Character space. + listedTiddlers := self manualLinksList, remainListArray. + ^ self wiki tiddlers select: [:tiddler | listedTiddlers includes: tiddler title ]. + +] + +{ #category : #accessing } +Tiddler >> manualLinksList [ + self list ifNil: [^ nil]. + ^ WikiTextGrammar new linkSea star parse: self list. +] + +{ #category : #utilities } +Tiddler >> markdownLinksAsWikiText [ + "I'm useful to convert _internal_ links between formats, as is a common pattern + found when migrating content from Markdown to TiddlyWiki's WikiText. + I DON'T work on external links. A better regex could be used for that. + See: + - https://davidwells.io/snippets/regex-match-markdown-links + - http://blog.michaelperrin.fr/2019/02/04/advanced-regular-expressions/" + | markdownLinks | + markdownLinks := (self text splitOn: Character space) select: [:each | each matchesRegex: '\[(.+)\)']. + markdownLinks ifEmpty: [^ self]. + ^ markdownLinks +] + +{ #category : #accessing } +Tiddler >> modified [ + + ^ modified +] + +{ #category : #accessing } +Tiddler >> modified: anObject [ + + modified := anObject +] + +{ #category : #accessing } +Tiddler >> modifier [ + + ^ modifier +] + +{ #category : #accessing } +Tiddler >> modifier: anObject [ + + modifier := anObject +] + +{ #category : #accessing } +Tiddler >> printOn: aStream [ + super printOn: aStream. + aStream + nextPutAll: '( ', self title, ' )' +] + +{ #category : #accessing } +Tiddler >> rawAliasedLinks [ + ^ self rawLinks select: [ :each | each includesSubstring: '|' ] +] + +{ #category : #accessing } +Tiddler >> rawLinks [ + self text ifNil: [ ^ Set new ]. + ^ (WikiTextGrammar new linkSea star parse: self text) asSet +] + +{ #category : #accessing } +Tiddler >> removeTag: aTag [ + + | tagsPre | + tagsPre := self tags. + self tags: ('' join: (tagsPre splitOn: aTag)). + ^ self +] + +{ #category : #accessing } +Tiddler >> renameExternalMediaLinksInto: relativePath [ + "This first implementation only renames external media links in custom fields. + Further development should offer the possibility to rename also the external media + appearing in the tiddler's text." + self customFieldsWithMediaLinks keysAndValuesDo: [:customField :oldLink | | link name | + link := oldLink asUrl. + link hasScheme ifFalse: [^ self ]. + name := link segments last copyWithoutAll: '-'. + name := name asDashedLowercase. + name := (relativePath, '/', NanoID generate, '--', name). + self customFields + at: customField, '--original' put: oldLink; + at: customField put: name +]. +] + +{ #category : #accessing } +Tiddler >> revision [ + ^ revision +] + +{ #category : #accessing } +Tiddler >> revision: aNumberString [ + revision := aNumberString +] + +{ #category : #accessing } +Tiddler >> tags [ + + ^ tags ifNil: [tags := Set new] +] + +{ #category : #accessing } +Tiddler >> tags: anObject [ + + tags := anObject +] + +{ #category : #accessing } +Tiddler >> tagsAsString [ + | response | + self tags ifEmpty: [^ '' ]. + response := '' writeStream. + self tags do: [:tag | + response nextPutAll: '[[', tag, ']]' + ]. + ^ response contents +] + +{ #category : #accessing } +Tiddler >> text [ + + ^ text +] + +{ #category : #accessing } +Tiddler >> text: anObject [ + + text := anObject +] + +{ #category : #accessing } +Tiddler >> tiddlersListFrom: anArray [ + | output | + output := '' writeStream. + + anArray doWithIndex: [:each :i | + output nextPutAll: '[[', each asString, ']]'. + i = anArray size ifFalse: [ output nextPutAll: Character space asString ]. + ]. + ^ output contents. +] + +{ #category : #accessing } +Tiddler >> title [ + + ^ title +] + +{ #category : #accessing } +Tiddler >> title: anObject [ + + title := anObject +] + +{ #category : #accessing } +Tiddler >> type [ + + ^ type +] + +{ #category : #accessing } +Tiddler >> type: anObject [ + + type := anObject +] + +{ #category : #accessing } +Tiddler >> uid [ + ^ self customFields at: 'uid' ifAbsentPut: [ self uidGenerator ]. + +] + +{ #category : #accessing } +Tiddler >> uidGenerator [ + + ^ self customFields at: 'uid' put: NanoID generate. + +] + +{ #category : #accessing } +Tiddler >> wiki [ + ^ wiki +] + +{ #category : #accessing } +Tiddler >> wiki: aTiddlyWiki [ + wiki := aTiddlyWiki +] diff --git a/repository/TiddlyWiki/TiddlerTest.class.st b/repository/TiddlyWiki/TiddlerTest.class.st index 149ac53..7128900 100644 --- a/repository/TiddlyWiki/TiddlerTest.class.st +++ b/repository/TiddlyWiki/TiddlerTest.class.st @@ -1,13 +1,13 @@ -Class { - #name : #TiddlerTest, - #superclass : #TestCase, - #category : #'TiddlyWiki-TiddlyWiki' -} - -{ #category : #accessing } -TiddlerTest >> testTiddlerTimeFormatTrasnformation [ - - | tiddlerTemp | - tiddlerTemp := Tiddler new created: '20220101010101123'. - self assert: tiddlerTemp created equals: tiddlerTemp created asDateAndTimeForTiddler asTiddlerFormat -] +Class { + #name : #TiddlerTest, + #superclass : #TestCase, + #category : #'TiddlyWiki-TiddlyWiki' +} + +{ #category : #accessing } +TiddlerTest >> testTiddlerTimeFormatTrasnformation [ + + | tiddlerTemp | + tiddlerTemp := Tiddler new created: '20220101010101123'. + self assert: tiddlerTemp created equals: tiddlerTemp created asDateAndTimeForTiddler asTiddlerFormat +] diff --git a/repository/TiddlyWiki/TiddlyWiki.class.st b/repository/TiddlyWiki/TiddlyWiki.class.st index c6b56d7..eaad2a5 100644 --- a/repository/TiddlyWiki/TiddlyWiki.class.st +++ b/repository/TiddlyWiki/TiddlyWiki.class.st @@ -1,958 +1,971 @@ -" -I model a TiddlyWiki. -More information: - -https://tiddlywiki.com/ -" -Class { - #name : #TiddlyWiki, - #superclass : #Object, - #instVars : [ - 'name', - 'file', - 'remote', - 'jsonFile', - 'tiddlers', - 'folder', - 'template' - ], - #category : #'TiddlyWiki-Model' -} - -{ #category : #'instance - creation' } -TiddlyWiki class >> createFromRemote: aRemoteTWUrl in: aFolder [ - - | wiki | - aFolder hasChildren ifTrue: [ ^ nil ]. - wiki := TiddlyWiki new - remote: aRemoteTWUrl; - folder: (aFolder ensureCreateDirectory). - ^ wiki downloadHTML; - file: (aFolder / 'index.html'); - tiddlers. -] - -{ #category : #'instance - creation' } -TiddlyWiki class >> createFromRemote: aRemoteTWUrl in: aFolder named: aNameString [ - - | wiki | - wiki := self createFromRemote: aRemoteTWUrl in: aFolder. - ^ wiki ifNotNil: [ ^ wiki name: aNameString ] -] - -{ #category : #accessing } -TiddlyWiki class >> fromJSONUrl: anUrlString [ - | rawContents contentsString | - rawContents := anUrlString asUrl retrieveContents. - rawContents class = ByteArray - ifTrue: [ contentsString := rawContents utf8Decoded ] - ifFalse: [ contentsString := rawContents ]. - ^ self new - fromDictionary: (STONJSON fromString: contentsString); - remote: anUrlString; - name: anUrlString -] - -{ #category : #accessing } -TiddlyWiki class >> loadFromLocalFolder: aFolder [ - - | wiki | - wiki := TiddlyWiki new - folder: aFolder; - file: aFolder / 'index.html'; - jsonFile: aFolder / 'tiddlers.json'. - ^ wiki fromString: wiki jsonFile. -] - -{ #category : #accessing } -TiddlyWiki class >> loadFromLocalFolder: aFolder named: aName [ - - | wiki | - wiki := TiddlyWiki loadFromLocalFolder: aFolder. - ^ wiki name: aName -] - -{ #category : #accessing } -TiddlyWiki class >> loadFromLocalFolder: aFolder named: aName withRemote: aRemoteURL [ - - | wiki | - wiki := self loadFromLocalFolder: aFolder named: aName. - ^ wiki remote: aRemoteURL -] - -{ #category : #accessing } -TiddlyWiki >> addRecentChangesToRepo [ - - | docsSton docsStonSanitized recentTiddlers repository | - repository := self repository. - self updateFromHtml. - recentTiddlers := self changesAfter: repository checkoutDateAndTime. - docsSton := recentTiddlers collect: [:each | each exportSTONFileOptimized ]. - "Collecting tiddlers file reference as string and adding to the repo" - docsStonSanitized := docsSton collect: [ :each | - (each fullName removePrefix: repository localRoot) allButFirst ]. - docsStonSanitized do: [ :each | repository add: each ]. - ^ repository status -] - -{ #category : #accessing } -TiddlyWiki >> addToConfigFile [ - | cleaned newConfig | - cleaned := self copy. - cleaned tiddlers: nil. - newConfig := self configDictionary - at: cleaned name put: cleaned; - yourself. - ^ MarkupFile exportAsFileOn: self configFile containing:(STON toStringPretty: newConfig) -] - -{ #category : #accessing } -TiddlyWiki >> addUnversionedLargeTiddlersToRepo [ - - | stonfiles largeTiddlersFileReference repository | - repository := self repository. - stonfiles := (self file parent / 'largeTiddlers') files - select: [ :each | each fullName endsWith: '.ston' ]. - largeTiddlersFileReference := stonfiles collect: [ :each | - each fullName withoutPrefix: - repository local fullName , '/' ]. - largeTiddlersFileReference do: [ :each | repository addUnversioned: each ]. - ^ largeTiddlersFileReference -] - -{ #category : #testing } -TiddlyWiki >> belongsToLocalRepository [ - - | localFolder tempRepo relativeName | - localFolder := self detectRepositoryLocal ifNil: [ ^ false ]. - tempRepo := FossilRepo new - local: localFolder. - relativeName := self file fullName withoutPrefix: (tempRepo local fullName, '/'). - ^ tempRepo listUnversioned hasLiteral: relativeName -] - -{ #category : #accessing } -TiddlyWiki >> changesAfter: aDateString [ - - | recent created modified wiki aDate | - aDate := aDateString asZTimestamp. - wiki := self commonTiddlers. - created := wiki select: [ :tiddler | tiddler created asZTimestamp > aDate ]. - modified := wiki select: [ :tiddler | tiddler modified isNotNil - and: [ tiddler modified asZTimestamp > aDate ] ]. - - recent := OrderedCollection new. - recent - addAll: created; - addAll: modified. - ^ recent asSet. -] - -{ #category : #accessing } -TiddlyWiki >> commonTiddlers [ - - | content | - content := OrderedCollection new. - content - addAll: (self contentTiddlers - select: [ :each | each isTW5Type or: [ each isNilType ]]); - "addAll: (self contentTiddlers select: [ :each | each isJavascript ]);" - addAll: (self contentTiddlers select: [ :each | each isXTiddlerDictionary ]); - addAll: (self contentTiddlers select: [ :each | each isTextPlain ]); - addAll: (self contentTiddlers select: [ :each | each isMarkdown ]). - ^ content. -] - -{ #category : #accessing } -TiddlyWiki >> configDictionary [ - ^ STONJSON fromString: self configFile contents. -] - -{ #category : #accessing } -TiddlyWiki >> configFile [ - | tempFile | - tempFile := FileLocator home / '.config' / 'TiddlyWikiPharo' / 'tiddlywiki.conf.ston'. - tempFile ensureCreateFile. - tempFile contents isEmpty ifTrue: [ - MarkupFile exportAsFileOn: tempFile containing: ( STON toStringPretty: Dictionary new) - ]. - ^ tempFile - -] - -{ #category : #accessing } -TiddlyWiki >> contentTiddlers [ - ^ self tiddlers copyWithoutAll: self shadow -] - -{ #category : #accessing } -TiddlyWiki >> core [ - - ^ STONJSON fromString:(self shadow select: [ :tid | tid title = '$:/core']) first text -] - -{ #category : #accessing } -TiddlyWiki >> detectRepositoryLocal [ - - | wikiFolder folderItems | - wikiFolder := self folder. - folderItems := wikiFolder children. - [(folderItems select: [ :path | (path basename beginsWith: '.fslckout') or: - [ path basename beginsWith: '.fossil']]) isEmpty - and:[ (wikiFolder = FileLocator root) not ]] - whileTrue: [wikiFolder := wikiFolder parent. - folderItems := wikiFolder children.]. - wikiFolder = FileLocator root ifTrue: [ ^ nil ]. - ^ wikiFolder -] - -{ #category : #accessing } -TiddlyWiki >> downloadHTML [ - | htmlLink localCopy | - self isInTiddlyHost ifTrue: [ - htmlLink := self remote asString - ]. - localCopy := self folder / 'index.html'. - localCopy exists ifTrue: [ | timestamp | - timestamp := (DateAndTime now asString) copyReplaceAll: ':' with: '_'. - localCopy renameTo: 'index-', timestamp, '.html']. - ZnClient new - url: htmlLink; - downloadTo: self folder / 'index.html'. - ^ self folder -] - -{ #category : #accessing } -TiddlyWiki >> exportCommonTiddlers [ - - | content | - content := self commonTiddlers. - content do: [ :each | - each exportSTONFile ]. - ^ self tiddlersFolder -] - -{ #category : #accessing } -TiddlyWiki >> exportContentShadowAndLargeTiddlersSTONFiles [ - - self exportSTONFiles; exportLargeTiddlers -] - -{ #category : #accessing } -TiddlyWiki >> exportContentType: aMimeType [ - - | filteredTiddlers tempWiki | - filteredTiddlers := self selectContentType: aMimeType. - filteredTiddlers do: [ :each | each exportSTONFileInto: self largeTiddlersFolderName ]. - ^ self largeTiddlersFolder -] - -{ #category : #accessing } -TiddlyWiki >> exportJSONFile [ - | docTree rawJsonTiddlers | - self htmlFileExists. - docTree := XMLHTMLParser parse: self file contents. - rawJsonTiddlers := (docTree xpath: '//script[@class="tiddlywiki-tiddler-store"]') stringValue. - ^ MarkupFile exportAsFileOn: self jsonFile containing: rawJsonTiddlers -] - -{ #category : #accessing } -TiddlyWiki >> exportJSONFileOptimized [ - - | exporter wikiFolder | - wikiFolder := self file parent. - exporter := wikiFolder / 'scripts' / 'exportJsonFile'. - exporter exists ifFalse: [ self installJsonExporter ]. - - OSSUnixSubprocess new - command: exporter fullName; - workingDirectory: exporter parent fullName; - runAndWaitOnExitDo: [ :process :outString | ^ self jsonFile ] -] - -{ #category : #accessing } -TiddlyWiki >> exportJSONFromRebuildedCommonTiddlers [ - - | rebuildedTiddlersJSON dateNowString wikiFolder| - wikiFolder := self folder. - dateNowString := (DateAndTime now asLocalStringYMDHM copyReplaceAll: ':' with: '-') copyReplaceAll: ' ' with: '-'. - rebuildedTiddlersJSON := '[', (',' join: (self rebuildWithoutLargeTiddlers collect: [ :each | each asJsonString ])), ']'. - ^ MarkupFile exportAsFileOn: wikiFolder / 'rebuildedCommonTiddlers', dateNowString, 'json' containing: rebuildedTiddlersJSON - -] - -{ #category : #accessing } -TiddlyWiki >> exportJSONFromTiddlersInSubfolder: subfolder [ - - | rebuildedTiddlersJSON dateNowString | - dateNowString := (DateAndTime now asLocalStringYMDHM copyReplaceAll: ':' with: '-') copyReplaceAll: ' ' with: '-'. - rebuildedTiddlersJSON := '[', (',' join: ((self rebuildTiddlersFromSubfolder: subfolder) collect: [ :each | each asJsonString ])), ']'. - ^ MarkupFile exportAsFileOn: subfolder / 'rebuildedTiddlers', dateNowString, 'json' containing: rebuildedTiddlersJSON - -] - -{ #category : #accessing } -TiddlyWiki >> exportJSONSubtiddlers: subtiddlersCollection [ - - ^ self exportJSONSubtiddlers: subtiddlersCollection as: 'subtiddlers' -] - -{ #category : #accessing } -TiddlyWiki >> exportJSONSubtiddlers: subtiddlersCollection as: aName [ - - ^ MarkupFile exportAsFileOn: self folder / aName, 'json' containing: (self jsonSubtiddlers: subtiddlersCollection) -] - -{ #category : #'export - json' } -TiddlyWiki >> exportJSONTiddlersTagged: aTag in: aFolder [ - - | dateNowString | - dateNowString := (DateAndTime now asLocalStringYMDHM copyReplaceAll: ':' with: '-') copyReplaceAll: ' ' with: '-'. - ^ self exportJSONTiddlersTagged: aTag in: aFolder named: (self name, '-tagged-', aTag, '-', dateNowString) -] - -{ #category : #'export - json' } -TiddlyWiki >> exportJSONTiddlersTagged: aTag in: aFolder named: aFileName [ - - | taggedTiddlers jsonString | - self tiddlers. - taggedTiddlers := self taggedWith: aTag. - jsonString := '[', (',' join: (taggedTiddlers collect: [ :each | each asJsonString ])), ']'. - ^ MarkupFile exportAsFileOn: aFolder / (aFileName, '.json') containing: jsonString -] - -{ #category : #accessing } -TiddlyWiki >> exportJSTiddlers [ - - | jsTiddlers jsNotShadow | - jsTiddlers := self tiddlers select: [ :each | each isJavascript ]. - jsNotShadow := jsTiddlers reject: [ :each | each isShadow ]. - ^ jsNotShadow do: [ :each | each exportSTONFileInto: 'tiddlers' ] -] - -{ #category : #accessing } -TiddlyWiki >> exportLargeTiddlers [ - - ^ self largeTiddlers do: [ :each | - each exportSTONFileInto: self largeTiddlersFolderName ]. -] - -{ #category : #accessing } -TiddlyWiki >> exportSTONFiles [ - - | stonFile wikiTemp shadowFile | - self tiddlers. - self tiddlersJSONFile - ifNil: [ - self inform: - 'No JSON Tiddlers file found. If you have one, please provide its location'. - stonFile := FileLocator temp / 'tiddlers.ston' ] - ifNotNil: [ - stonFile := self tiddlersJSONFile withoutExtension , 'ston' ]. - shadowFile := self largeTiddlersFolder / '_shadow.ston'. - wikiTemp := self copy. - wikiTemp tiddlers: self commonTiddlers. - MiniDocs exportAsSton: self shadow on: shadowFile. - MiniDocs exportAsSton: wikiTemp on: stonFile. - ^ self folder -] - -{ #category : #accessing } -TiddlyWiki >> exportSTONTiddlers: aCollection [ - aCollection do: [:each | each exportSTONFile ] -] - -{ #category : #accessing } -TiddlyWiki >> exportTW5Tiddlers [ - - | tw5Tiddlers tw5ExplicitTiddlers notShadowTiddlers | - tw5Tiddlers := self tiddlers select: [ :each | each isNilType ]. - tw5ExplicitTiddlers := self tiddlers select: [ :each | each isTW5Type ]. - - notShadowTiddlers := OrderedCollection new. - notShadowTiddlers addAll: (tw5ExplicitTiddlers reject: [ :each | each isShadow ]). - notShadowTiddlers addAll: (tw5Tiddlers reject: [ :each | each isShadow ]). - ^ notShadowTiddlers do: [ :each | each exportSTONFileInto: 'tiddlers' ] -] - -{ #category : #accessing } -TiddlyWiki >> file [ - - ^ file -] - -{ #category : #accessing } -TiddlyWiki >> file: anObject [ - file := anObject -] - -{ #category : #accessing } -TiddlyWiki >> folder [ - folder ifNotNil: [ ^ folder ]. - self file ifNotNil: [ file parent ]. - ^ folder := FileLocator temp - -] - -{ #category : #accessing } -TiddlyWiki >> folder: anObject [ - folder := anObject -] - -{ #category : #accessing } -TiddlyWiki >> fromDictionary: tiddlersDict [ - - self tiddlers: (tiddlersDict collect: [ :each | - Tiddler new - fromDictionary: each; - wiki: self ]) -] - -{ #category : #accessing } -TiddlyWiki >> fromString: aJSONString [ - - | tiddlersDict | - tiddlersDict := STONJSON fromString: aJSONString. - self fromDictionary: tiddlersDict -] - -{ #category : #accessing } -TiddlyWiki >> fromUrl: anUrlString [ - | docTree rawJsonTiddlers tiddlersDictionary | - self remote: anUrlString. - docTree := XMLHTMLParser parse: (self remote retrieveContents). - rawJsonTiddlers := (docTree xpath: '//script[@class="tiddlywiki-tiddler-store"]') stringValue. - tiddlersDictionary := STONJSON fromString: rawJsonTiddlers. - self fromDictionary: tiddlersDictionary -] - -{ #category : #accessing } -TiddlyWiki >> getRemoteTiddlers [ - | remoteTiddlers localTiddlers | - remoteTiddlers := self importJSONLink tiddlers. - localTiddlers := self rebuildWithoutLargeTiddlers asArray. - "^ self recentCommonTiddlersChanged" - localTiddlers do: [ :each | | remoteTiddler | - remoteTiddler := remoteTiddlers detect: [:tiddler | tiddler title = each title]. - remoteTiddler customFields at: 'uid' put: (each customFields at: 'uid'). - ]. - self tiddlers: remoteTiddlers. - ^ self recentCommonTiddlersChanged -] - -{ #category : #accessing } -TiddlyWiki >> hasTemplateInTiddlyHost [ - - self template ifNil: [ ^ false ]. - ^ self template asZnUrl host endsWith: 'tiddlyhost.com' -] - -{ #category : #accessing } -TiddlyWiki >> htmlFileExists [ - self file ifNil: [ - self inform: 'No TiddlyWiki HTML file found. If you have one, please provide its location.'. - ^ nil - ]. -] - -{ #category : #accessing } -TiddlyWiki >> importJSONFile [ - - "I import a JSON representation of my tiddlers data, - that has been previosly exported by - #exportJSONFileOptimized or #exportJSONFile" - - self tiddlersJSONFile ifNil: [ ^ self ]. - self fromString: self tiddlersJSONFile contents. - -] - -{ #category : #accessing } -TiddlyWiki >> importJSONLink [ - - | localCopy | - self jsonFile ifNil: [ self jsonFile: self folder / 'tiddlers.json' ]. - localCopy := self folder / 'tiddlers.json'. - localCopy exists ifTrue: [ | timestamp | - timestamp := (DateAndTime now asString) copyReplaceAll: ':' with: '_'. - localCopy renameTo: 'tiddlers-', timestamp, '.json']. - MarkupFile exportAsFileOn: jsonFile containing: self remoteTiddlersContentsString. - ^ self fromString: self remoteTiddlersContentsString -] - -{ #category : #accessing } -TiddlyWiki >> installJsonExporter [ - - | folder | - folder := (self file parent / 'scripts') ensureCreateDirectory. - ZnClient new - url: 'https://mutabit.com/repos.fossil/mutabit/uv/wiki/scripts/exportJsonFile'; - downloadTo: folder / 'exportJsonFile'. - ZnClient new - url: 'https://mutabit.com/repos.fossil/mutabit/doc/trunk/wiki/scripts/exportJsonFile.nim'; - downloadTo: folder / 'exportJsonFile.nim'. - - OSSUnixSubprocess new - command: 'chmod'; - arguments: { '+x' . (folder / 'exportJsonFile') fullName }; - workingDirectory: folder fullName; - redirectStdout; - redirectStderr; - runAndWaitOnExitDo: [ :process :outString | ^ outString ] -] - -{ #category : #accessing } -TiddlyWiki >> isInTiddlyHost [ - - self remote ifNil: [ ^ false ]. - ^ self remote host endsWith: 'tiddlyhost.com' -] - -{ #category : #accessing } -TiddlyWiki >> jsonFile [ - ^ jsonFile ifNil: [ - self htmlFileExists ifNotNil: - [ jsonFile := self folder / 'tiddlers.json' ] - ] -] - -{ #category : #accessing } -TiddlyWiki >> jsonFile: aFileLocator [ - "I contain the tiddlers representation of the wiki data in JSON format." - jsonFile := aFileLocator -] - -{ #category : #accessing } -TiddlyWiki >> jsonSubtiddlers: subtiddlersCollection [ - | subtiddlersDict | - subtiddlersDict := subtiddlersCollection asArray collect: [:tiddler | tiddler asDictionary ]. - ^ STONJSON toStringPretty: subtiddlersDict -] - -{ #category : #accessing } -TiddlyWiki >> largeTiddlers [ - - | wikiImages wikiPDFs wikiLargeTiddlers | - wikiImages := self selectContentType: 'image/'. - wikiPDFs := self selectContentType: 'application/pdf'. - wikiLargeTiddlers := OrderedCollection new. - wikiLargeTiddlers - addAll: wikiImages; - addAll: wikiPDFs. - ^ wikiLargeTiddlers -] - -{ #category : #accessing } -TiddlyWiki >> largeTiddlersFolder [ - "I store all shadow tiddlers, i.e. tiddlers that provide functionality to TiddlyWiki, - for example the ones that come in the plugins or in system tiddlers. - For more information about shadow tiddlers, see #shadow method." - - | largeFilesFolder | - largeFilesFolder := self folder / self largeTiddlersFolderName. - largeFilesFolder ensureCreateDirectory. - ^ largeFilesFolder -] - -{ #category : #accessing } -TiddlyWiki >> largeTiddlersFolderName [ - - ^ 'largeTiddlers' -] - -{ #category : #accessing } -TiddlyWiki >> loadFromConfig: wikiname [ - ^ (self configDictionary at: wikiname) importJSONFile. - -] - -{ #category : #accessing } -TiddlyWiki >> local [ - ^ self file -] - -{ #category : #accessing } -TiddlyWiki >> local: aFileRefence [ - ^ self file:aFileRefence -] - -{ #category : #accessing } -TiddlyWiki >> name [ - | tempName suffix | - name ifNotNil: [ ^ name ]. - self remote ifNil: [ ^ name := nil ]. - (self remote host endsWith: 'tiddlyhost.com') - ifTrue: [ ^ name := (self remote host splitOn: '.') first ]. - self file ifNotNil: [ ^ name := self file basenameWithoutExtension ]. - tempName := self remote file. - (tempName endsWithAnyOf: #('.html' '.htm')) - ifTrue: [ - suffix := (tempName splitOn: '.') last. - tempName := tempName removeSuffix: '.', suffix. - ]. - name := tempName -] - -{ #category : #accessing } -TiddlyWiki >> name: aString [ - - name := aString -] - -{ #category : #accessing } -TiddlyWiki >> networkView [ - | view | - view := GtMondrian new. - view nodes - with: self tiddlers. - view edges - connectFromAll: #linkedTiddlers. - view layout force. - ^ view -] - -{ #category : #accessing } -TiddlyWiki >> networkViewBackground [ - ^ self configDictionary at: 'networkView' at: 'background' ifAbsentPut: [Color lightGray] -] - -{ #category : #accessing } -TiddlyWiki >> networkViewBackground: aColor [ - self configDictionary at: 'networkView' at: 'background' put: aColor -] - -{ #category : #accessing } -TiddlyWiki >> networkViewForeground [ - ^ self configDictionary at: 'networkView' at: 'foreground' ifAbsentPut: [Color blue] -] - -{ #category : #accessing } -TiddlyWiki >> networkViewHighlightingCreator: creatorName [ - | view | - view := GtMondrian new. - view nodes - stencil: [ :each | - | color size | - color := (each creator = creatorName) - ifTrue: [ self networkViewForeground ] - ifFalse: [ self networkViewBackground ]. - size := 5 @ 5. - BlElement new background: color; size: size ]; - with: self tiddlers. - view edges - connectToAll: #linkedTiddlers. - view layout force. - ^ view -] - -{ #category : #accessing } -TiddlyWiki >> oldestCreatedTiddler [ - - | tiddlersTemp oldestDate | - tiddlersTemp := self tiddlers. - oldestDate := (tiddlersTemp collect: [ :tiddler | tiddler created asDateAndTimeForTiddler ]) asSortedCollection first. - ^ (tiddlersTemp select:[ :tiddler | tiddler created asDateAndTimeForTiddler = oldestDate ]) first. -] - -{ #category : #accessing } -TiddlyWiki >> printOn: aStream [ - super printOn: aStream. - aStream - nextPutAll: '( ', self name ,' )' -] - -{ #category : #accessing } -TiddlyWiki >> rebuildTiddlers [ - - | stonTiddlers shadowTiddlersFile | - shadowTiddlersFile := self largeTiddlersFolder asFileReference children - select: [ :each | each basename beginsWith: '_shadow.ston' ]. - - stonTiddlers := OrderedCollection new. - stonTiddlers - addAll: self rebuildWithoutShadows ; - addAll: (STON fromString:shadowTiddlersFile first contents). - ^ stonTiddlers -] - -{ #category : #accessing } -TiddlyWiki >> rebuildTiddlersFromSubfolder: subfolder [ - - | stonTiddlers contentTiddlersFiles | - contentTiddlersFiles := subfolder children - select: [ :each | each basename endsWith: 'ston' ]. - - stonTiddlers := OrderedCollection new. - stonTiddlers - addAll: (contentTiddlersFiles - collect:[ :each | STONJSON fromString: each contents ]). - stonTiddlers collect: [ :tiddler | tiddler wiki: self ]. - ^ stonTiddlers -] - -{ #category : #accessing } -TiddlyWiki >> rebuildTiddlersJSON [ - - self tiddlers: self rebuildWithoutShadows. - ^ self exportJSONSubtiddlers: - (self rebuildWithoutShadows) as: 'rebuildedTiddlers'. -] - -{ #category : #accessing } -TiddlyWiki >> rebuildWithoutLargeTiddlers [ - - | stonTiddlers contentTiddlersFiles | - contentTiddlersFiles := self tiddlersFolder files - select: [ :each | each basename endsWith: 'ston' ]. - - stonTiddlers := OrderedCollection new. - stonTiddlers - addAll: (contentTiddlersFiles - collect:[ :each | STONJSON fromString: each contents ]). - stonTiddlers collect: [ :tiddler | tiddler wiki: self ]. - ^ stonTiddlers -] - -{ #category : #accessing } -TiddlyWiki >> rebuildWithoutShadows [ - - | stonTiddlers largeTiddlersRebuild | - largeTiddlersRebuild := (((self largeTiddlersFolder files) - reject: [ :each | each basename beginsWith: '_shadow' ]) - collect: [ :each | STONJSON fromString: each contents ]). - - stonTiddlers := OrderedCollection new. - stonTiddlers - addAll: largeTiddlersRebuild; - addAll: self rebuildWithoutLargeTiddlers. - ^ stonTiddlers -] - -{ #category : #accessing } -TiddlyWiki >> recentCommonTiddlersChanged [ - - ^ self commonTiddlers sort: [ :tiddler1 :tiddler2 | - (tiddler1 modified isNil - ifTrue: [ tiddler1 created asDateAndTimeForTiddler ] - ifFalse: [ tiddler1 modified asDateAndTimeForTiddler ]) - > - (tiddler2 modified isNil - ifTrue: [ tiddler2 created asDateAndTimeForTiddler ] - ifFalse: [ tiddler2 modified asDateAndTimeForTiddler ]) ] -] - -{ #category : #accessing } -TiddlyWiki >> remote [ - - ^ remote -] - -{ #category : #accessing } -TiddlyWiki >> remote: aUrlString [ - - remote := aUrlString asZnUrl -] - -{ #category : #accessing } -TiddlyWiki >> remoteTiddlersContentsString [ - self isInTiddlyHost ifFalse: [ ^ self ]. - ^ (self remote asString, '/tiddlers.json') asZnUrl retrieveContents. -] - -{ #category : #accessing } -TiddlyWiki >> repository [ - - | repo | - self belongsToLocalRepository ifFalse: [ ^ self ]. - repo := FossilRepo new - local: self detectRepositoryLocal. - repo repository. - ^ repo -] - -{ #category : #accessing } -TiddlyWiki >> resynchronizeWithRepository [ - - | repository return | - repository := self repository. - repository update. - repository syncUnversioned. - return := Dictionary new - at: 'status' put: self addRecentChangesToRepo. - self exportSTONFiles; - exportCommonTiddlers; - exportLargeTiddlers. - ^ return - at: 'file' put: self rebuildTiddlersJSON; - yourself. -] - -{ #category : #accessing } -TiddlyWiki >> selectByTagsIncludes: string [ - - ^ (self tiddlers select: [ :tiddler | tiddler tags notNil ]) - select: [ :tiddler | tiddler tags includesSubstring: string ] -] - -{ #category : #accessing } -TiddlyWiki >> selectContentType: mimeType [ - - ^ self tiddlers select: [ :tiddler | tiddler type isNotNil and: [tiddler type beginsWith: mimeType ]] -] - -{ #category : #accessing } -TiddlyWiki >> selectTitleIncludes: string [ - - ^ self tiddlers select: [ :tiddler | tiddler title includesSubstring: string ] -] - -{ #category : #accessing } -TiddlyWiki >> shadow [ - "Shadow tiddlers are tiddlers that are loaded from plugins. - For more information about them, see: - - - https://tiddlywiki.com/static/ShadowTiddlers.html - - https://groups.google.com/g/TiddlyWiki/c/HuyZmaRJTxI" - ^ self tiddlers select: [:tiddler | tiddler title beginsWith: '$:/'] -] - -{ #category : #accessing } -TiddlyWiki >> syncRemoteLocalDestructive [ - - | repository | - repository := self repository. - repository update. - repository revertRemoteUnversioned. - repository exportHTMLUnversioned. - self - exportJSONFile; - importJSONFile. - self exportSTONFiles. - self exportCommonTiddlers. - self exportLargeTiddlers. - ^ Dictionary new - at: 'status' put: repository status; - at: 'tiddlers from STON' put: self rebuildTiddlers; - yourself. -] - -{ #category : #accessing } -TiddlyWiki >> taggedWith: aTag [ - ^ self tiddlers select: [:tiddler | - tiddler tags isNotNil and: [tiddler tags includesSubstring: aTag ] - ] -] - -{ #category : #accessing } -TiddlyWiki >> template [ - ^ template -] - -{ #category : #accessing } -TiddlyWiki >> template: anUrl [ - template := anUrl -] - -{ #category : #accessing } -TiddlyWiki >> templateTiddlersContentsString [ - self hasTemplateInTiddlyHost ifFalse: [ ^ self ]. - ^ (self template asString, '/tiddlers.json') asZnUrl retrieveContents. -] - -{ #category : #accessing } -TiddlyWiki >> templateWiki [ - ^ (TiddlyWiki new fromString: self templateTiddlersContentsString) - name: 'Template Wiki'; - remote: self template -] - -{ #category : #accessing } -TiddlyWiki >> tiddlers [ - tiddlers ifNotNil: [ ^ tiddlers ]. - self isInTiddlyHost ifTrue: [ ^ self importJSONLink]. - ^ tiddlers ifNil: [ tiddlers := OrderedCollection new ] -] - -{ #category : #accessing } -TiddlyWiki >> tiddlers: anOrderedCollection [ - - tiddlers := anOrderedCollection -] - -{ #category : #accessing } -TiddlyWiki >> tiddlersFolder [ - - ^ self folder / 'tiddlers' -] - -{ #category : #accessing } -TiddlyWiki >> tiddlersFromHTMLFile [ -"I process and set the tiddlers from de HTML wiki file." - | html tiddlerStore tiddlerDict | - - self file isNil - ifTrue: [ ^ self inform: 'This wiki HTML file is nil.', - (Character cr asString), 'Please provide an HTML file to the TW.' ]. - - html := XMLHTMLParser parse: self file. - tiddlerStore := (html xpath: '//script[@class="tiddlywiki-tiddler-store"]') stringValue. - tiddlerDict := STONJSON fromString: tiddlerStore. - ^ self tiddlers: (tiddlerDict collect: [ :dic | Tiddler new fromDictionary: dic ]) -] - -{ #category : #accessing } -TiddlyWiki >> tiddlersJSONFile [ - - self jsonFile exists ifFalse: [ - self inform: 'You need to export tiddlers as JSON from TiddlyWiki and locate it in the same folder as the HTML file'. - ^ nil - ]. - ^ jsonFile -] - -{ #category : #accessing } -TiddlyWiki >> tiddlersJSONUrl [ - self remote ifNil: [^ nil]. -] - -{ #category : #accessing } -TiddlyWiki >> tiddlersMissingUID [ - - ^ self tiddlers reject: [ :tiddler | (tiddler customFields includesKey: 'uid') or: [ (tiddler title beginsWith:'$') ] ]. -] - -{ #category : #accessing } -TiddlyWiki >> updateFilesFromRemote [ - - self remote ifNil: [ self inform: 'No remote found. If you have one, please provide its URL.'. - ^ self ]. - ^ self downloadHTML; - importJSONLink -] - -{ #category : #accessing } -TiddlyWiki >> updateFromHtml [ - self - exportJSONFileOptimized; - importJSONFile. -] - -{ #category : #accessing } -TiddlyWiki >> withoutContentType: application [ - | filteredTiddlers tempWiki | - filteredTiddlers := self tiddlers reject: [:tiddler | tiddler type isNotNil and: [tiddler type beginsWith: application ]]. - tempWiki := self copy - tiddlers: filteredTiddlers. - tempWiki tiddlers do: [:tiddler | tiddler wiki: tempWiki ]. - ^ tempWiki -] - -{ #category : #accessing } -TiddlyWiki >> withoutImages [ - ^ self withoutContentType: 'image/' -] - -{ #category : #accessing } -TiddlyWiki >> withoutPDFs [ - ^ self withoutContentType: 'application/pdf' -] +" +I model a TiddlyWiki. +More information: + +https://tiddlywiki.com/ +" +Class { + #name : #TiddlyWiki, + #superclass : #Object, + #instVars : [ + 'name', + 'file', + 'remote', + 'jsonFile', + 'tiddlers', + 'folder', + 'template', + 'config' + ], + #category : #'TiddlyWiki-Model' +} + +{ #category : #'instance - creation' } +TiddlyWiki class >> createFromRemote: aRemoteTWUrl in: aFolder [ + + | wiki | + aFolder hasChildren ifTrue: [ ^ nil ]. + wiki := TiddlyWiki new + remote: aRemoteTWUrl; + folder: (aFolder ensureCreateDirectory). + ^ wiki downloadHTML; + file: (aFolder / 'index.html'); + tiddlers. +] + +{ #category : #'instance - creation' } +TiddlyWiki class >> createFromRemote: aRemoteTWUrl in: aFolder named: aNameString [ + + | wiki | + wiki := self createFromRemote: aRemoteTWUrl in: aFolder. + ^ wiki ifNotNil: [ ^ wiki name: aNameString ] +] + +{ #category : #accessing } +TiddlyWiki class >> fromJSONUrl: anUrlString [ + | rawContents contentsString | + rawContents := anUrlString asUrl retrieveContents. + rawContents class = ByteArray + ifTrue: [ contentsString := rawContents utf8Decoded ] + ifFalse: [ contentsString := rawContents ]. + ^ self new + fromDictionary: (STONJSON fromString: contentsString); + remote: anUrlString; + name: anUrlString +] + +{ #category : #accessing } +TiddlyWiki class >> loadFromLocalFolder: aFolder [ + + | wiki | + wiki := TiddlyWiki new + folder: aFolder; + file: aFolder / 'index.html'; + jsonFile: aFolder / 'tiddlers.json'. + ^ wiki fromString: wiki jsonFile. +] + +{ #category : #accessing } +TiddlyWiki class >> loadFromLocalFolder: aFolder named: aName [ + + | wiki | + wiki := TiddlyWiki loadFromLocalFolder: aFolder. + ^ wiki name: aName +] + +{ #category : #accessing } +TiddlyWiki class >> loadFromLocalFolder: aFolder named: aName withRemote: aRemoteURL [ + + | wiki | + wiki := self loadFromLocalFolder: aFolder named: aName. + ^ wiki remote: aRemoteURL +] + +{ #category : #accessing } +TiddlyWiki >> addRecentChangesToRepo [ + + | docsSton docsStonSanitized recentTiddlers repository | + repository := self repository. + self updateFromHtml. + recentTiddlers := self changesAfter: repository checkoutDateAndTime. + docsSton := recentTiddlers collect: [:each | each exportSTONFileOptimized ]. + "Collecting tiddlers file reference as string and adding to the repo" + docsStonSanitized := docsSton collect: [ :each | + (each fullName removePrefix: repository localRoot) allButFirst ]. + docsStonSanitized do: [ :each | repository add: each ]. + ^ repository status +] + +{ #category : #accessing } +TiddlyWiki >> addToConfigFile [ + | cleaned newConfig | + cleaned := self copy. + cleaned tiddlers: nil. + newConfig := self configDictionary + at: cleaned name put: cleaned; + yourself. + ^ self exportToConfigFile: newConfig +] + +{ #category : #accessing } +TiddlyWiki >> addUnversionedLargeTiddlersToRepo [ + + | stonfiles largeTiddlersFileReference repository | + repository := self repository. + stonfiles := (self file parent / 'largeTiddlers') files + select: [ :each | each fullName endsWith: '.ston' ]. + largeTiddlersFileReference := stonfiles collect: [ :each | + each fullName withoutPrefix: + repository local fullName , '/' ]. + largeTiddlersFileReference do: [ :each | repository addUnversioned: each ]. + ^ largeTiddlersFileReference +] + +{ #category : #testing } +TiddlyWiki >> belongsToLocalRepository [ + + | localFolder tempRepo relativeName | + localFolder := self detectRepositoryLocal ifNil: [ ^ false ]. + tempRepo := FossilRepo new + local: localFolder. + relativeName := self file fullName withoutPrefix: (tempRepo local fullName, '/'). + ^ tempRepo listUnversioned hasLiteral: relativeName +] + +{ #category : #accessing } +TiddlyWiki >> changesAfter: aDateString [ + + | recent created modified wiki aDate | + aDate := aDateString asZTimestamp. + wiki := self commonTiddlers. + created := wiki select: [ :tiddler | tiddler created asZTimestamp > aDate ]. + modified := wiki select: [ :tiddler | tiddler modified isNotNil + and: [ tiddler modified asZTimestamp > aDate ] ]. + + recent := OrderedCollection new. + recent + addAll: created; + addAll: modified. + ^ recent asSet. +] + +{ #category : #accessing } +TiddlyWiki >> commonTiddlers [ + + | content | + content := OrderedCollection new. + content + addAll: (self contentTiddlers + select: [ :each | each isTW5Type or: [ each isNilType ]]); + "addAll: (self contentTiddlers select: [ :each | each isJavascript ]);" + addAll: (self contentTiddlers select: [ :each | each isXTiddlerDictionary ]); + addAll: (self contentTiddlers select: [ :each | each isTextPlain ]); + addAll: (self contentTiddlers select: [ :each | each isMarkdown ]). + ^ content. +] + +{ #category : #accessing } +TiddlyWiki >> config [ + ^ config ifNil: [ config := Dictionary new] +] + +{ #category : #accessing } +TiddlyWiki >> configDictionary [ + ^ STONJSON fromString: self configFile contents. +] + +{ #category : #accessing } +TiddlyWiki >> configFile [ + | tempFile | + tempFile := FileLocator home / '.config' / 'TiddlyWikiPharo' / 'tiddlywiki.conf.ston'. + tempFile ensureCreateFile. + tempFile contents isEmpty ifTrue: [ + MarkupFile exportAsFileOn: tempFile containing: ( STON toStringPretty: Dictionary new) + ]. + ^ tempFile + +] + +{ #category : #accessing } +TiddlyWiki >> contentTiddlers [ + ^ self tiddlers copyWithoutAll: self shadow +] + +{ #category : #accessing } +TiddlyWiki >> core [ + + ^ STONJSON fromString:(self shadow select: [ :tid | tid title = '$:/core']) first text +] + +{ #category : #accessing } +TiddlyWiki >> detectRepositoryLocal [ + + | wikiFolder folderItems | + wikiFolder := self folder. + folderItems := wikiFolder children. + [(folderItems select: [ :path | (path basename beginsWith: '.fslckout') or: + [ path basename beginsWith: '.fossil']]) isEmpty + and:[ (wikiFolder = FileLocator root) not ]] + whileTrue: [wikiFolder := wikiFolder parent. + folderItems := wikiFolder children.]. + wikiFolder = FileLocator root ifTrue: [ ^ nil ]. + ^ wikiFolder +] + +{ #category : #accessing } +TiddlyWiki >> downloadHTML [ + | htmlLink localCopy | + self isInTiddlyHost ifTrue: [ + htmlLink := self remote asString + ]. + localCopy := self folder / 'index.html'. + localCopy exists ifTrue: [ | timestamp | + timestamp := (DateAndTime now asString) copyReplaceAll: ':' with: '_'. + localCopy renameTo: 'index-', timestamp, '.html']. + ZnClient new + url: htmlLink; + downloadTo: self folder / 'index.html'. + ^ self folder +] + +{ #category : #accessing } +TiddlyWiki >> exportCommonTiddlers [ + + | content | + content := self commonTiddlers. + content do: [ :each | + each exportSTONFile ]. + ^ self tiddlersFolder +] + +{ #category : #accessing } +TiddlyWiki >> exportContentShadowAndLargeTiddlersSTONFiles [ + + self exportSTONFiles; exportLargeTiddlers +] + +{ #category : #accessing } +TiddlyWiki >> exportContentType: aMimeType [ + + | filteredTiddlers tempWiki | + filteredTiddlers := self selectContentType: aMimeType. + filteredTiddlers do: [ :each | each exportSTONFileInto: self largeTiddlersFolderName ]. + ^ self largeTiddlersFolder +] + +{ #category : #accessing } +TiddlyWiki >> exportJSONFile [ + | docTree rawJsonTiddlers | + self htmlFileExists. + docTree := XMLHTMLParser parse: self file contents. + rawJsonTiddlers := (docTree xpath: '//script[@class="tiddlywiki-tiddler-store"]') stringValue. + ^ MarkupFile exportAsFileOn: self jsonFile containing: rawJsonTiddlers +] + +{ #category : #accessing } +TiddlyWiki >> exportJSONFileOptimized [ + + | exporter wikiFolder | + wikiFolder := self file parent. + exporter := wikiFolder / 'scripts' / 'exportJsonFile'. + exporter exists ifFalse: [ self installJsonExporter ]. + + OSSUnixSubprocess new + command: exporter fullName; + workingDirectory: exporter parent fullName; + runAndWaitOnExitDo: [ :process :outString | ^ self jsonFile ] +] + +{ #category : #accessing } +TiddlyWiki >> exportJSONFromRebuildedCommonTiddlers [ + + | rebuildedTiddlersJSON dateNowString wikiFolder| + wikiFolder := self folder. + dateNowString := (DateAndTime now asLocalStringYMDHM copyReplaceAll: ':' with: '-') copyReplaceAll: ' ' with: '-'. + rebuildedTiddlersJSON := '[', (',' join: (self rebuildWithoutLargeTiddlers collect: [ :each | each asJsonString ])), ']'. + ^ MarkupFile exportAsFileOn: wikiFolder / 'rebuildedCommonTiddlers', dateNowString, 'json' containing: rebuildedTiddlersJSON + +] + +{ #category : #accessing } +TiddlyWiki >> exportJSONFromTiddlersInSubfolder: subfolder [ + + | rebuildedTiddlersJSON dateNowString | + dateNowString := (DateAndTime now asLocalStringYMDHM copyReplaceAll: ':' with: '-') copyReplaceAll: ' ' with: '-'. + rebuildedTiddlersJSON := '[', (',' join: ((self rebuildTiddlersFromSubfolder: subfolder) collect: [ :each | each asJsonString ])), ']'. + ^ MarkupFile exportAsFileOn: subfolder / 'rebuildedTiddlers', dateNowString, 'json' containing: rebuildedTiddlersJSON + +] + +{ #category : #accessing } +TiddlyWiki >> exportJSONSubtiddlers: subtiddlersCollection [ + + ^ self exportJSONSubtiddlers: subtiddlersCollection as: 'subtiddlers' +] + +{ #category : #accessing } +TiddlyWiki >> exportJSONSubtiddlers: subtiddlersCollection as: aName [ + + ^ MarkupFile exportAsFileOn: self folder / aName, 'json' containing: (self jsonSubtiddlers: subtiddlersCollection) +] + +{ #category : #'export - json' } +TiddlyWiki >> exportJSONTiddlersTagged: aTag in: aFolder [ + + | dateNowString | + dateNowString := (DateAndTime now asLocalStringYMDHM copyReplaceAll: ':' with: '-') copyReplaceAll: ' ' with: '-'. + ^ self exportJSONTiddlersTagged: aTag in: aFolder named: (self name, '-tagged-', aTag, '-', dateNowString) +] + +{ #category : #'export - json' } +TiddlyWiki >> exportJSONTiddlersTagged: aTag in: aFolder named: aFileName [ + + | taggedTiddlers jsonString | + self tiddlers. + taggedTiddlers := self taggedWith: aTag. + jsonString := '[', (',' join: (taggedTiddlers collect: [ :each | each asJsonString ])), ']'. + ^ MarkupFile exportAsFileOn: aFolder / (aFileName, '.json') containing: jsonString +] + +{ #category : #accessing } +TiddlyWiki >> exportJSTiddlers [ + + | jsTiddlers jsNotShadow | + jsTiddlers := self tiddlers select: [ :each | each isJavascript ]. + jsNotShadow := jsTiddlers reject: [ :each | each isShadow ]. + ^ jsNotShadow do: [ :each | each exportSTONFileInto: 'tiddlers' ] +] + +{ #category : #accessing } +TiddlyWiki >> exportLargeTiddlers [ + + ^ self largeTiddlers do: [ :each | + each exportSTONFileInto: self largeTiddlersFolderName ]. +] + +{ #category : #accessing } +TiddlyWiki >> exportSTONFiles [ + + | stonFile wikiTemp shadowFile | + self tiddlers. + self tiddlersJSONFile + ifNil: [ + self inform: + 'No JSON Tiddlers file found. If you have one, please provide its location'. + stonFile := FileLocator temp / 'tiddlers.ston' ] + ifNotNil: [ + stonFile := self tiddlersJSONFile withoutExtension , 'ston' ]. + shadowFile := self largeTiddlersFolder / '_shadow.ston'. + wikiTemp := self copy. + wikiTemp tiddlers: self commonTiddlers. + MiniDocs exportAsSton: self shadow on: shadowFile. + MiniDocs exportAsSton: wikiTemp on: stonFile. + ^ self folder +] + +{ #category : #accessing } +TiddlyWiki >> exportSTONTiddlers: aCollection [ + aCollection do: [:each | each exportSTONFile ] +] + +{ #category : #accessing } +TiddlyWiki >> exportTW5Tiddlers [ + + | tw5Tiddlers tw5ExplicitTiddlers notShadowTiddlers | + tw5Tiddlers := self tiddlers select: [ :each | each isNilType ]. + tw5ExplicitTiddlers := self tiddlers select: [ :each | each isTW5Type ]. + + notShadowTiddlers := OrderedCollection new. + notShadowTiddlers addAll: (tw5ExplicitTiddlers reject: [ :each | each isShadow ]). + notShadowTiddlers addAll: (tw5Tiddlers reject: [ :each | each isShadow ]). + ^ notShadowTiddlers do: [ :each | each exportSTONFileInto: 'tiddlers' ] +] + +{ #category : #accessing } +TiddlyWiki >> exportToConfigFile: newConfig [ + ^ MarkupFile + exportAsFileOn: self configFile + containing: (STON toStringPretty: newConfig) +] + +{ #category : #accessing } +TiddlyWiki >> file [ + + ^ file +] + +{ #category : #accessing } +TiddlyWiki >> file: anObject [ + file := anObject +] + +{ #category : #accessing } +TiddlyWiki >> folder [ + folder ifNotNil: [ ^ folder ]. + self file ifNotNil: [ file parent ]. + ^ folder := FileLocator temp + +] + +{ #category : #accessing } +TiddlyWiki >> folder: anObject [ + folder := anObject +] + +{ #category : #accessing } +TiddlyWiki >> fromDictionary: tiddlersDict [ + + self tiddlers: (tiddlersDict collect: [ :each | + Tiddler new + fromDictionary: each; + wiki: self ]) +] + +{ #category : #accessing } +TiddlyWiki >> fromString: aJSONString [ + + | tiddlersDict | + tiddlersDict := STONJSON fromString: aJSONString. + self fromDictionary: tiddlersDict +] + +{ #category : #accessing } +TiddlyWiki >> fromUrl: anUrlString [ + | docTree rawJsonTiddlers tiddlersDictionary | + self remote: anUrlString. + docTree := XMLHTMLParser parse: (self remote retrieveContents). + rawJsonTiddlers := (docTree xpath: '//script[@class="tiddlywiki-tiddler-store"]') stringValue. + tiddlersDictionary := STONJSON fromString: rawJsonTiddlers. + self fromDictionary: tiddlersDictionary +] + +{ #category : #accessing } +TiddlyWiki >> getRemoteTiddlers [ + | remoteTiddlers localTiddlers | + remoteTiddlers := self importJSONLink tiddlers. + localTiddlers := self rebuildWithoutLargeTiddlers asArray. + "^ self recentCommonTiddlersChanged" + localTiddlers do: [ :each | | remoteTiddler | + remoteTiddler := remoteTiddlers detect: [:tiddler | tiddler title = each title]. + remoteTiddler customFields at: 'uid' put: (each customFields at: 'uid'). + ]. + self tiddlers: remoteTiddlers. + ^ self recentCommonTiddlersChanged +] + +{ #category : #accessing } +TiddlyWiki >> hasTemplateInTiddlyHost [ + + self template ifNil: [ ^ false ]. + ^ self template asZnUrl host endsWith: 'tiddlyhost.com' +] + +{ #category : #accessing } +TiddlyWiki >> htmlFileExists [ + self file ifNil: [ + self inform: 'No TiddlyWiki HTML file found. If you have one, please provide its location.'. + ^ nil + ]. +] + +{ #category : #accessing } +TiddlyWiki >> importJSONFile [ + + "I import a JSON representation of my tiddlers data, + that has been previosly exported by + #exportJSONFileOptimized or #exportJSONFile" + + self tiddlersJSONFile ifNil: [ ^ self ]. + self fromString: self tiddlersJSONFile contents. + +] + +{ #category : #accessing } +TiddlyWiki >> importJSONLink [ + + | localCopy | + self jsonFile ifNil: [ self jsonFile: self folder / 'tiddlers.json' ]. + localCopy := self folder / 'tiddlers.json'. + localCopy exists ifTrue: [ | timestamp | + timestamp := (DateAndTime now asString) copyReplaceAll: ':' with: '_'. + localCopy renameTo: 'tiddlers-', timestamp, '.json']. + MarkupFile exportAsFileOn: jsonFile containing: self remoteTiddlersContentsString. + ^ self fromString: self remoteTiddlersContentsString +] + +{ #category : #accessing } +TiddlyWiki >> installJsonExporter [ + + | folder | + folder := (self file parent / 'scripts') ensureCreateDirectory. + ZnClient new + url: 'https://mutabit.com/repos.fossil/mutabit/uv/wiki/scripts/exportJsonFile'; + downloadTo: folder / 'exportJsonFile'. + ZnClient new + url: 'https://mutabit.com/repos.fossil/mutabit/doc/trunk/wiki/scripts/exportJsonFile.nim'; + downloadTo: folder / 'exportJsonFile.nim'. + + OSSUnixSubprocess new + command: 'chmod'; + arguments: { '+x' . (folder / 'exportJsonFile') fullName }; + workingDirectory: folder fullName; + redirectStdout; + redirectStderr; + runAndWaitOnExitDo: [ :process :outString | ^ outString ] +] + +{ #category : #accessing } +TiddlyWiki >> isInTiddlyHost [ + + self remote ifNil: [ ^ false ]. + ^ self remote host endsWith: 'tiddlyhost.com' +] + +{ #category : #accessing } +TiddlyWiki >> jsonFile [ + ^ jsonFile ifNil: [ + self htmlFileExists ifNotNil: + [ jsonFile := self folder / 'tiddlers.json' ] + ] +] + +{ #category : #accessing } +TiddlyWiki >> jsonFile: aFileLocator [ + "I contain the tiddlers representation of the wiki data in JSON format." + jsonFile := aFileLocator +] + +{ #category : #accessing } +TiddlyWiki >> jsonSubtiddlers: subtiddlersCollection [ + | subtiddlersDict | + subtiddlersDict := subtiddlersCollection asArray collect: [:tiddler | tiddler asDictionary ]. + ^ STONJSON toStringPretty: subtiddlersDict +] + +{ #category : #accessing } +TiddlyWiki >> largeTiddlers [ + + | wikiImages wikiPDFs wikiLargeTiddlers | + wikiImages := self selectContentType: 'image/'. + wikiPDFs := self selectContentType: 'application/pdf'. + wikiLargeTiddlers := OrderedCollection new. + wikiLargeTiddlers + addAll: wikiImages; + addAll: wikiPDFs. + ^ wikiLargeTiddlers +] + +{ #category : #accessing } +TiddlyWiki >> largeTiddlersFolder [ + "I store all shadow tiddlers, i.e. tiddlers that provide functionality to TiddlyWiki, + for example the ones that come in the plugins or in system tiddlers. + For more information about shadow tiddlers, see #shadow method." + + | largeFilesFolder | + largeFilesFolder := self folder / self largeTiddlersFolderName. + largeFilesFolder ensureCreateDirectory. + ^ largeFilesFolder +] + +{ #category : #accessing } +TiddlyWiki >> largeTiddlersFolderName [ + + ^ 'largeTiddlers' +] + +{ #category : #accessing } +TiddlyWiki >> loadFromConfig: wikiname [ + ^ (self configDictionary at: wikiname) importJSONFile. + +] + +{ #category : #accessing } +TiddlyWiki >> local [ + ^ self file +] + +{ #category : #accessing } +TiddlyWiki >> local: aFileRefence [ + ^ self file:aFileRefence +] + +{ #category : #accessing } +TiddlyWiki >> name [ + | tempName suffix | + name ifNotNil: [ ^ name ]. + self remote ifNil: [ ^ name := nil ]. + (self remote host endsWith: 'tiddlyhost.com') + ifTrue: [ ^ name := (self remote host splitOn: '.') first ]. + self file ifNotNil: [ ^ name := self file basenameWithoutExtension ]. + tempName := self remote file. + (tempName endsWithAnyOf: #('.html' '.htm')) + ifTrue: [ + suffix := (tempName splitOn: '.') last. + tempName := tempName removeSuffix: '.', suffix. + ]. + name := tempName +] + +{ #category : #accessing } +TiddlyWiki >> name: aString [ + + name := aString +] + +{ #category : #accessing } +TiddlyWiki >> networkView [ + | view | + view := GtMondrian new. + view nodes + with: self tiddlers. + view edges + connectFromAll: #linkedTiddlers. + view layout force. + ^ view +] + +{ #category : #accessing } +TiddlyWiki >> networkViewBackground [ + ^ self configDictionary at: 'networkView' at: 'background' ifAbsentPut: [Color lightGray] +] + +{ #category : #accessing } +TiddlyWiki >> networkViewBackground: aColor [ + self config at: 'networkView' at: 'background' put: aColor. +] + +{ #category : #accessing } +TiddlyWiki >> networkViewForeground [ + ^ self configDictionary at: 'networkView' at: 'foreground' ifAbsentPut: [Color blue] +] + +{ #category : #accessing } +TiddlyWiki >> networkViewHighlightingCreator: creatorName [ + | view | + view := GtMondrian new. + view nodes + stencil: [ :each | + | color size | + color := (each creator = creatorName) + ifTrue: [ self networkViewForeground ] + ifFalse: [ self networkViewBackground ]. + size := 5 @ 5. + BlElement new background: color; size: size ]; + with: self tiddlers. + view edges + connectToAll: #linkedTiddlers. + view layout force. + ^ view +] + +{ #category : #accessing } +TiddlyWiki >> oldestCreatedTiddler [ + + | tiddlersTemp oldestDate | + tiddlersTemp := self tiddlers. + oldestDate := (tiddlersTemp collect: [ :tiddler | tiddler created asDateAndTimeForTiddler ]) asSortedCollection first. + ^ (tiddlersTemp select:[ :tiddler | tiddler created asDateAndTimeForTiddler = oldestDate ]) first. +] + +{ #category : #accessing } +TiddlyWiki >> printOn: aStream [ + super printOn: aStream. + aStream + nextPutAll: '( ', self name ,' )' +] + +{ #category : #accessing } +TiddlyWiki >> rebuildTiddlers [ + + | stonTiddlers shadowTiddlersFile | + shadowTiddlersFile := self largeTiddlersFolder asFileReference children + select: [ :each | each basename beginsWith: '_shadow.ston' ]. + + stonTiddlers := OrderedCollection new. + stonTiddlers + addAll: self rebuildWithoutShadows ; + addAll: (STON fromString:shadowTiddlersFile first contents). + ^ stonTiddlers +] + +{ #category : #accessing } +TiddlyWiki >> rebuildTiddlersFromSubfolder: subfolder [ + + | stonTiddlers contentTiddlersFiles | + contentTiddlersFiles := subfolder children + select: [ :each | each basename endsWith: 'ston' ]. + + stonTiddlers := OrderedCollection new. + stonTiddlers + addAll: (contentTiddlersFiles + collect:[ :each | STONJSON fromString: each contents ]). + stonTiddlers collect: [ :tiddler | tiddler wiki: self ]. + ^ stonTiddlers +] + +{ #category : #accessing } +TiddlyWiki >> rebuildTiddlersJSON [ + + self tiddlers: self rebuildWithoutShadows. + ^ self exportJSONSubtiddlers: + (self rebuildWithoutShadows) as: 'rebuildedTiddlers'. +] + +{ #category : #accessing } +TiddlyWiki >> rebuildWithoutLargeTiddlers [ + + | stonTiddlers contentTiddlersFiles | + contentTiddlersFiles := self tiddlersFolder files + select: [ :each | each basename endsWith: 'ston' ]. + + stonTiddlers := OrderedCollection new. + stonTiddlers + addAll: (contentTiddlersFiles + collect:[ :each | STONJSON fromString: each contents ]). + stonTiddlers collect: [ :tiddler | tiddler wiki: self ]. + ^ stonTiddlers +] + +{ #category : #accessing } +TiddlyWiki >> rebuildWithoutShadows [ + + | stonTiddlers largeTiddlersRebuild | + largeTiddlersRebuild := (((self largeTiddlersFolder files) + reject: [ :each | each basename beginsWith: '_shadow' ]) + collect: [ :each | STONJSON fromString: each contents ]). + + stonTiddlers := OrderedCollection new. + stonTiddlers + addAll: largeTiddlersRebuild; + addAll: self rebuildWithoutLargeTiddlers. + ^ stonTiddlers +] + +{ #category : #accessing } +TiddlyWiki >> recentCommonTiddlersChanged [ + + ^ self commonTiddlers sort: [ :tiddler1 :tiddler2 | + (tiddler1 modified isNil + ifTrue: [ tiddler1 created asDateAndTimeForTiddler ] + ifFalse: [ tiddler1 modified asDateAndTimeForTiddler ]) + > + (tiddler2 modified isNil + ifTrue: [ tiddler2 created asDateAndTimeForTiddler ] + ifFalse: [ tiddler2 modified asDateAndTimeForTiddler ]) ] +] + +{ #category : #accessing } +TiddlyWiki >> remote [ + + ^ remote +] + +{ #category : #accessing } +TiddlyWiki >> remote: aUrlString [ + + remote := aUrlString asZnUrl +] + +{ #category : #accessing } +TiddlyWiki >> remoteTiddlersContentsString [ + self isInTiddlyHost ifFalse: [ ^ self ]. + ^ (self remote asString, '/tiddlers.json') asZnUrl retrieveContents. +] + +{ #category : #accessing } +TiddlyWiki >> repository [ + + | repo | + self belongsToLocalRepository ifFalse: [ ^ self ]. + repo := FossilRepo new + local: self detectRepositoryLocal. + repo repository. + ^ repo +] + +{ #category : #accessing } +TiddlyWiki >> resynchronizeWithRepository [ + + | repository return | + repository := self repository. + repository update. + repository syncUnversioned. + return := Dictionary new + at: 'status' put: self addRecentChangesToRepo. + self exportSTONFiles; + exportCommonTiddlers; + exportLargeTiddlers. + ^ return + at: 'file' put: self rebuildTiddlersJSON; + yourself. +] + +{ #category : #accessing } +TiddlyWiki >> selectByTagsIncludes: string [ + + ^ (self tiddlers select: [ :tiddler | tiddler tags notNil ]) + select: [ :tiddler | tiddler tags includesSubstring: string ] +] + +{ #category : #accessing } +TiddlyWiki >> selectContentType: mimeType [ + + ^ self tiddlers select: [ :tiddler | tiddler type isNotNil and: [tiddler type beginsWith: mimeType ]] +] + +{ #category : #accessing } +TiddlyWiki >> selectTitleIncludes: string [ + + ^ self tiddlers select: [ :tiddler | tiddler title includesSubstring: string ] +] + +{ #category : #accessing } +TiddlyWiki >> shadow [ + "Shadow tiddlers are tiddlers that are loaded from plugins. + For more information about them, see: + + - https://tiddlywiki.com/static/ShadowTiddlers.html + - https://groups.google.com/g/TiddlyWiki/c/HuyZmaRJTxI" + ^ self tiddlers select: [:tiddler | tiddler title beginsWith: '$:/'] +] + +{ #category : #accessing } +TiddlyWiki >> syncRemoteLocalDestructive [ + + | repository | + repository := self repository. + repository update. + repository revertRemoteUnversioned. + repository exportHTMLUnversioned. + self + exportJSONFile; + importJSONFile. + self exportSTONFiles. + self exportCommonTiddlers. + self exportLargeTiddlers. + ^ Dictionary new + at: 'status' put: repository status; + at: 'tiddlers from STON' put: self rebuildTiddlers; + yourself. +] + +{ #category : #accessing } +TiddlyWiki >> taggedWith: aTag [ + ^ self tiddlers select: [:tiddler | + tiddler tags isNotNil and: [tiddler tags includesSubstring: aTag ] + ] +] + +{ #category : #accessing } +TiddlyWiki >> template [ + ^ template +] + +{ #category : #accessing } +TiddlyWiki >> template: anUrl [ + template := anUrl +] + +{ #category : #accessing } +TiddlyWiki >> templateTiddlersContentsString [ + self hasTemplateInTiddlyHost ifFalse: [ ^ self ]. + ^ (self template asString, '/tiddlers.json') asZnUrl retrieveContents. +] + +{ #category : #accessing } +TiddlyWiki >> templateWiki [ + ^ (TiddlyWiki new fromString: self templateTiddlersContentsString) + name: 'Template Wiki'; + remote: self template +] + +{ #category : #accessing } +TiddlyWiki >> tiddlers [ + tiddlers ifNotNil: [ ^ tiddlers ]. + self isInTiddlyHost ifTrue: [ ^ self importJSONLink]. + ^ tiddlers ifNil: [ tiddlers := OrderedCollection new ] +] + +{ #category : #accessing } +TiddlyWiki >> tiddlers: anOrderedCollection [ + + tiddlers := anOrderedCollection +] + +{ #category : #accessing } +TiddlyWiki >> tiddlersFolder [ + + ^ self folder / 'tiddlers' +] + +{ #category : #accessing } +TiddlyWiki >> tiddlersFromHTMLFile [ +"I process and set the tiddlers from de HTML wiki file." + | html tiddlerStore tiddlerDict | + + self file isNil + ifTrue: [ ^ self inform: 'This wiki HTML file is nil.', + (Character cr asString), 'Please provide an HTML file to the TW.' ]. + + html := XMLHTMLParser parse: self file. + tiddlerStore := (html xpath: '//script[@class="tiddlywiki-tiddler-store"]') stringValue. + tiddlerDict := STONJSON fromString: tiddlerStore. + ^ self tiddlers: (tiddlerDict collect: [ :dic | Tiddler new fromDictionary: dic ]) +] + +{ #category : #accessing } +TiddlyWiki >> tiddlersJSONFile [ + + self jsonFile exists ifFalse: [ + self inform: 'You need to export tiddlers as JSON from TiddlyWiki and locate it in the same folder as the HTML file'. + ^ nil + ]. + ^ jsonFile +] + +{ #category : #accessing } +TiddlyWiki >> tiddlersJSONUrl [ + self remote ifNil: [^ nil]. +] + +{ #category : #accessing } +TiddlyWiki >> tiddlersMissingUID [ + + ^ self tiddlers reject: [ :tiddler | (tiddler customFields includesKey: 'uid') or: [ (tiddler title beginsWith:'$') ] ]. +] + +{ #category : #accessing } +TiddlyWiki >> updateFilesFromRemote [ + + self remote ifNil: [ self inform: 'No remote found. If you have one, please provide its URL.'. + ^ self ]. + ^ self downloadHTML; + importJSONLink +] + +{ #category : #accessing } +TiddlyWiki >> updateFromHtml [ + self + exportJSONFileOptimized; + importJSONFile. +] + +{ #category : #accessing } +TiddlyWiki >> withoutContentType: application [ + | filteredTiddlers tempWiki | + filteredTiddlers := self tiddlers reject: [:tiddler | tiddler type isNotNil and: [tiddler type beginsWith: application ]]. + tempWiki := self copy + tiddlers: filteredTiddlers. + tempWiki tiddlers do: [:tiddler | tiddler wiki: tempWiki ]. + ^ tempWiki +] + +{ #category : #accessing } +TiddlyWiki >> withoutImages [ + ^ self withoutContentType: 'image/' +] + +{ #category : #accessing } +TiddlyWiki >> withoutPDFs [ + ^ self withoutContentType: 'application/pdf' +] diff --git a/repository/TiddlyWiki/TiddlyWikiExamples.class.st b/repository/TiddlyWiki/TiddlyWikiExamples.class.st index 2c1037a..4294b8a 100644 --- a/repository/TiddlyWiki/TiddlyWikiExamples.class.st +++ b/repository/TiddlyWiki/TiddlyWikiExamples.class.st @@ -1,14 +1,14 @@ -Class { - #name : #TiddlyWikiExamples, - #superclass : #Object, - #category : #'TiddlyWiki-Model' -} - -{ #category : #accessing } -TiddlyWikiExamples >> createDefaultWiki [ - - - - TWSeed deleteWikiFileFromFolder: FileLocator temp andSubfolder: 'test'. - ^ TWSeed installDefaultInto: FileLocator temp as: 'test' -] +Class { + #name : #TiddlyWikiExamples, + #superclass : #Object, + #category : #'TiddlyWiki-Model' +} + +{ #category : #accessing } +TiddlyWikiExamples >> createDefaultWiki [ + + + + TWSeed deleteWikiFileFromFolder: FileLocator temp andSubfolder: 'test'. + ^ TWSeed installDefaultInto: FileLocator temp as: 'test' +] diff --git a/repository/TiddlyWiki/WebVideo.extension.st b/repository/TiddlyWiki/WebVideo.extension.st index ca26e45..2f67b94 100644 --- a/repository/TiddlyWiki/WebVideo.extension.st +++ b/repository/TiddlyWiki/WebVideo.extension.st @@ -1,23 +1,23 @@ -Extension { #name : #WebVideo } - -{ #category : #'*TiddlyWiki' } -WebVideo >> asTiddler [ - | tiddler body | - tiddler := Tiddler new - title: self title. - tiddler customFields - at: 'uid' put: self videoId; - at: 'author' put: self author; - at: 'authorId' put: self authorId; - at: 'duration' put: self duration. - body := '' writeStream. - body - nextPutAll: '<>'; - nextPutAll: ' - -* ''''Duración:'''' {{!!duration}} -* ''''Autor/a:'''' {{!!author}}'. - tiddler text: body contents withInternetLineEndings. - - ^ tiddler -] +Extension { #name : #WebVideo } + +{ #category : #'*TiddlyWiki' } +WebVideo >> asTiddler [ + | tiddler body | + tiddler := Tiddler new + title: self title. + tiddler customFields + at: 'uid' put: self videoId; + at: 'author' put: self author; + at: 'authorId' put: self authorId; + at: 'duration' put: self duration. + body := '' writeStream. + body + nextPutAll: '<>'; + nextPutAll: ' + +* ''''Duración:'''' {{!!duration}} +* ''''Autor/a:'''' {{!!author}}'. + tiddler text: body contents withInternetLineEndings. + + ^ tiddler +] diff --git a/repository/TiddlyWiki/WikiText.class.st b/repository/TiddlyWiki/WikiText.class.st index ad7024a..195b2cd 100644 --- a/repository/TiddlyWiki/WikiText.class.st +++ b/repository/TiddlyWiki/WikiText.class.st @@ -1,53 +1,53 @@ -Class { - #name : #WikiText, - #superclass : #Object, - #instVars : [ - 'content' - ], - #category : 'TiddlyWiki-Model' -} - -{ #category : #accessing } -WikiText >> content [ - ^ content -] - -{ #category : #accessing } -WikiText >> content: aString [ - content := aString -] - -{ #category : #conversions } -WikiText >> converMarkdownBold [ - self content: (self content copyReplaceAll: '**' with: ''''''). -] - -{ #category : #conversions } -WikiText >> convertMarkdownBold [ - self content: (self content copyReplaceAll: '**' with: ''''''). - ^ self. -] - -{ #category : #conversions } -WikiText >> convertMarkdownLinks [ - | markdownLinks markdownLinksRegex | - "\[([\w|\s]+)\]\((\S+)\)" - markdownLinksRegex := '\[([\w|\s]+)\]\((\S+)\)'. - "For the explanation of the Regex details see: http://scottradcliff.com/how-to-parse-urls-in-markdown.html" - markdownLinks := self content regex: markdownLinksRegex matchesCollect: [:link | link ]. - markdownLinks ifEmpty: [ ^ self content ]. - markdownLinks do: [:markdownLink | | linkText closingLinkIndex newContent | - closingLinkIndex := markdownLink indexOf: $]. - linkText := markdownLink copyFrom: 2 to: closingLinkIndex. - newContent := self content copyReplaceAll: markdownLink with: '[[', linkText, ']'. - self content: newContent. - ]. - ^ self content -] - -{ #category : #accessing } -WikiText >> sample [ - ^ 'The ''quick'' brown ~~flea~~ fox //jumps// over the `lazy` dog. - - This is a link to HelloThere, and one to [[History of TiddlyWiki]] and [[other link]].' -] +Class { + #name : #WikiText, + #superclass : #Object, + #instVars : [ + 'content' + ], + #category : 'TiddlyWiki-Model' +} + +{ #category : #accessing } +WikiText >> content [ + ^ content +] + +{ #category : #accessing } +WikiText >> content: aString [ + content := aString +] + +{ #category : #conversions } +WikiText >> converMarkdownBold [ + self content: (self content copyReplaceAll: '**' with: ''''''). +] + +{ #category : #conversions } +WikiText >> convertMarkdownBold [ + self content: (self content copyReplaceAll: '**' with: ''''''). + ^ self. +] + +{ #category : #conversions } +WikiText >> convertMarkdownLinks [ + | markdownLinks markdownLinksRegex | + "\[([\w|\s]+)\]\((\S+)\)" + markdownLinksRegex := '\[([\w|\s]+)\]\((\S+)\)'. + "For the explanation of the Regex details see: http://scottradcliff.com/how-to-parse-urls-in-markdown.html" + markdownLinks := self content regex: markdownLinksRegex matchesCollect: [:link | link ]. + markdownLinks ifEmpty: [ ^ self content ]. + markdownLinks do: [:markdownLink | | linkText closingLinkIndex newContent | + closingLinkIndex := markdownLink indexOf: $]. + linkText := markdownLink copyFrom: 2 to: closingLinkIndex. + newContent := self content copyReplaceAll: markdownLink with: '[[', linkText, ']'. + self content: newContent. + ]. + ^ self content +] + +{ #category : #accessing } +WikiText >> sample [ + ^ 'The ''quick'' brown ~~flea~~ fox //jumps// over the `lazy` dog. + + This is a link to HelloThere, and one to [[History of TiddlyWiki]] and [[other link]].' +] diff --git a/repository/TiddlyWiki/WikiTextGrammar.class.st b/repository/TiddlyWiki/WikiTextGrammar.class.st index b28df9c..6b03dd1 100644 --- a/repository/TiddlyWiki/WikiTextGrammar.class.st +++ b/repository/TiddlyWiki/WikiTextGrammar.class.st @@ -1,47 +1,47 @@ -Class { - #name : #WikiTextGrammar, - #superclass : #PP2CompositeNode, - #instVars : [ - 'document', - 'link', - 'linkOpen', - 'linkContent', - 'linkClose' - ], - #category : 'TiddlyWiki-Model' -} - -{ #category : #accessing } -WikiTextGrammar >> document [ - ^ link islandInSea star -] - -{ #category : #accessing } -WikiTextGrammar >> link [ - ^ linkOpen, linkContent, linkClose ==> #second -] - -{ #category : #accessing } -WikiTextGrammar >> linkClose [ - ^ ']]' asPParser -] - -{ #category : #accessing } -WikiTextGrammar >> linkContent [ - ^ #any asPParser starLazy flatten -] - -{ #category : #accessing } -WikiTextGrammar >> linkOpen [ - ^ '[[' asPParser -] - -{ #category : #accessing } -WikiTextGrammar >> linkSea [ - ^ link sea ==> #second -] - -{ #category : #accessing } -WikiTextGrammar >> start [ - ^ document -] +Class { + #name : #WikiTextGrammar, + #superclass : #PP2CompositeNode, + #instVars : [ + 'document', + 'link', + 'linkOpen', + 'linkContent', + 'linkClose' + ], + #category : 'TiddlyWiki-Model' +} + +{ #category : #accessing } +WikiTextGrammar >> document [ + ^ link islandInSea star +] + +{ #category : #accessing } +WikiTextGrammar >> link [ + ^ linkOpen, linkContent, linkClose ==> #second +] + +{ #category : #accessing } +WikiTextGrammar >> linkClose [ + ^ ']]' asPParser +] + +{ #category : #accessing } +WikiTextGrammar >> linkContent [ + ^ #any asPParser starLazy flatten +] + +{ #category : #accessing } +WikiTextGrammar >> linkOpen [ + ^ '[[' asPParser +] + +{ #category : #accessing } +WikiTextGrammar >> linkSea [ + ^ link sea ==> #second +] + +{ #category : #accessing } +WikiTextGrammar >> start [ + ^ document +] diff --git a/repository/TiddlyWiki/WikiTextGrammarTest.class.st b/repository/TiddlyWiki/WikiTextGrammarTest.class.st index 35432e3..50f18d0 100644 --- a/repository/TiddlyWiki/WikiTextGrammarTest.class.st +++ b/repository/TiddlyWiki/WikiTextGrammarTest.class.st @@ -1,25 +1,25 @@ -Class { - #name : #WikiTextGrammarTest, - #superclass : #PP2CompositeNodeTest, - #category : 'TiddlyWiki-Model' -} - -{ #category : #accessing } -WikiTextGrammarTest >> parserClass [ - ^ WikiTextGrammar -] - -{ #category : #accessing } -WikiTextGrammarTest >> testDocument [ - | input | - input := WikiText new sample. - self parse: input rule: #document. - self assert: result size equals: 2 -] - -{ #category : #accessing } -WikiTextGrammarTest >> testLink [ - self - parse: '[[Just testing]]' - rule: #link -] +Class { + #name : #WikiTextGrammarTest, + #superclass : #PP2CompositeNodeTest, + #category : 'TiddlyWiki-Model' +} + +{ #category : #accessing } +WikiTextGrammarTest >> parserClass [ + ^ WikiTextGrammar +] + +{ #category : #accessing } +WikiTextGrammarTest >> testDocument [ + | input | + input := WikiText new sample. + self parse: input rule: #document. + self assert: result size equals: 2 +] + +{ #category : #accessing } +WikiTextGrammarTest >> testLink [ + self + parse: '[[Just testing]]' + rule: #link +] diff --git a/repository/TiddlyWiki/package.st b/repository/TiddlyWiki/package.st index b0b2b6d..e18b041 100644 --- a/repository/TiddlyWiki/package.st +++ b/repository/TiddlyWiki/package.st @@ -1 +1 @@ -Package { #name : #TiddlyWiki } +Package { #name : #TiddlyWiki }