" 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 >> downloadLink: v into: subfolder [ | filePath fileName semiFilePath | fileName := v asUrl segments last. semiFilePath := subfolder , fileName. filePath := (FileLocator temp / semiFilePath) fullName. GtSubprocessWithInMemoryOutput new shellCommand: 'curl -L -# ' , v , ' -o ' , filePath; runAndWait; stdout. ^ FileLocator temp / semiFilePath ] { #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 tiddlers isNotEmpty ifTrue: [^ self exportJSONFileFromTiddlers ]. 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 >> exportJSONFileFromTiddlers [ | response | response := '' writeStream. response nextPutAll: '['; cr. self tiddlers allButLastDo: [:tiddler | response nextPutAll: tiddler asJsonString; nextPutAll: ','; cr ]. response nextPutAll: self tiddlers last asJsonString; cr; nextPutAll: ']'; cr. ^ MarkupFile exportAsFileOn: self folder / 'tiddlers.json' containing: response contents ] { #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 >> importSTONFilesFrom: aFolder [ | tiddlerFiles | self folder: aFolder. tiddlerFiles := (aFolder / 'tiddlers') children select: [ :localFile | localFile basename endsWith: '.ston' ]. self tiddlers: (tiddlerFiles collect: [ :each | | tempTiddler| tempTiddler := STON fromString: each contents. tempTiddler wiki: self. tempTiddler]) ] { #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 >> jsonCache [ self downloadLink: self tiddlersJSONUrl into: self folder. ] { #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 config at: 'networkView' at: 'background' ifAbsentPut: [Color lightOrange] ] { #category : #accessing } TiddlyWiki >> networkViewBackground: aColor [ self config at: 'networkView' at: 'background' put: aColor. ] { #category : #accessing } TiddlyWiki >> networkViewForeground [ ^ self config at: 'networkView' at: 'foreground' ifAbsentPut: [Color blue] ] { #category : #accessing } TiddlyWiki >> networkViewForeground: aColor [ self config at: 'networkView' at: 'foreground' put: aColor. ] { #category : #accessing } TiddlyWiki >> networkViewHighlightingCreatedAfter: aDate [ | view | view := GtMondrian new. view nodes stencil: [ :each | | color size | color := (each creationTime > (ZTimestamp fromString: aDate) ) 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 >> networkViewHighlightingCreator: creatorName [ | view | view := GtMondrian new. view nodes stencil: [ :each | | color size | color := (each creator isNotNil and: [each creator trimBoth = 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 >> networkViewHighlightingNodesIn: aCollection [ ^ self networkViewHighlightingNodesIn: aCollection withColor: self networkViewForeground ] { #category : #accessing } TiddlyWiki >> networkViewHighlightingNodesIn: aCollection withColor: aColor [ | view | view := GtMondrian new. view nodes stencil: [ :each | | color size | color := (aCollection includes: each ) ifTrue: [ aColor ] 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 [ | printName | printName := self name ifNil: ['unamed']. super printOn: aStream. aStream nextPutAll: '( ', printName ,' )' ] { #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 [ | jsonAddress | self isInTiddlyHost ifFalse: [ ^ self ]. jsonAddress := self remote asString, '/tiddlers.json'. ^ [jsonAddress asZnUrl retrieveContents] onErrorDo: [ self jsonCache ]. ] { #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 : #'as yet unclassified' } TiddlyWiki >> substitutions [ ^ self config at: 'substitutions' ifAbsentPut: [ Dictionary new]. ] { #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' ]