TiddlyWikiPharo/repository/TiddlyWiki/Tiddler.class.st

379 lines
8.6 KiB
Smalltalk

"
I model a Tiddler object in [TiddlyWiki](https://tiddlywiki.com/).
I implement the standard fields as described in the standard documentation at: <https://tiddlywiki.com/#TiddlerFields>
"
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)
]
{ #category : #accessing }
Tiddler >> asDictionary [
| response |
response := Dictionary new
at: 'title' put: self title;
at: 'text' put: self text;
at: 'created' put: self created asString;
at: 'tags' put: self tags;
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;
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 crlf;
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 >> creator [
^ creator
]
{ #category : #accessing }
Tiddler >> creator: anObject [
creator := anObject
]
{ #category : #accessing }
Tiddler >> customFields [
^ customFields ifNil: [ customFields := Dictionary new]
]
{ #category : #accessing }
Tiddler >> exportJSONFile [
| jsonFile |
jsonFile := self wiki file parent / 'tiddlers' / (self title asDashedLowercase,'.', self created asString, '.json').
^ MarkupFile exportAsFileOn: jsonFile containing:self asJson
]
{ #category : #accessing }
Tiddler >> exportSTONFile [
| stonFile output |
stonFile := self wiki file parent / 'tiddlers' / (self title asDashedLowercase, '.', self created asString, '.ston') .
^ MarkupFile exportAsFileOn: stonFile containing: self asStonStringPretty
]
{ #category : #accessing }
Tiddler >> exportWithTemplate: aTemplate [
^ aTemplate asMustacheTemplate value: self asDictionary
]
{ #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: [ nil ]);
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 ifEmpty: [ ^ self ].
customKeys do: [:key |
self customFields at: key put: (aDictionary at: key) ].
]
{ #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 >> 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 : #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 >> revision [
^ revision
]
{ #category : #accessing }
Tiddler >> revision: aNumberString [
revision := aNumberString
]
{ #category : #accessing }
Tiddler >> tags [
^ tags
]
{ #category : #accessing }
Tiddler >> tags: anObject [
tags := anObject
]
{ #category : #accessing }
Tiddler >> text [
^ text
]
{ #category : #accessing }
Tiddler >> text: anObject [
text := anObject
]
{ #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 >> wiki [
^ wiki
]
{ #category : #accessing }
Tiddler >> wiki: aTiddlyWiki [
wiki := aTiddlyWiki
]