TiddlyWikiPharo/repository/TiddlyWiki/Tiddler.class.st

490 lines
11 KiB
Smalltalk
Raw Normal View History

2021-02-23 17:01:54 +00:00
"
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,
2021-02-23 17:01:54 +00:00
#instVars : [
'title',
'text',
'modified',
'created',
'creator',
'tags',
'type',
'list',
'caption',
'modifier',
'wiki',
'customFields',
'bag',
'revision'
2021-02-23 17:01:54 +00:00
],
#category : #'TiddlyWiki-Model'
2021-02-23 17:01:54 +00:00
}
{ #category : #'instance creation' }
Tiddler class >> nowLocal [
^ ((ZTimestampFormat fromString: '20010203160506700')
format: (ZTimestamp fromString: Time nowLocal asDateAndTime asString)) copyFrom: 1 to: 17
]
{ #category : #accessing }
2021-06-05 18:32:51 +00:00
Tiddler >> asDictionary [
| response |
response := Dictionary new
2021-06-05 18:32:51 +00:00
at: 'title' put: self title;
at: 'text' put: self text;
at: 'created' put: self created;
2021-06-05 18:32:51 +00:00
at: 'tags' put: self tags;
2021-08-09 13:52:19 +00:00
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;
2021-06-05 18:32:51 +00:00
yourself.
self customFields ifNotEmpty: [
self customFields keysAndValuesDo: [:k :v |
response at: k put: v
]
].
^ response
2021-09-09 01:00:14 +00:00
]
{ #category : #converting }
Tiddler >> asJson [
2021-09-09 01:00:14 +00:00
^ 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 |
2021-09-09 01:00:14 +00:00
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 }
2021-02-23 17:01:54 +00:00
Tiddler >> caption [
^ caption
]
{ #category : #accessing }
2021-02-23 17:01:54 +00:00
Tiddler >> caption: anObject [
caption := anObject
]
{ #category : #accessing }
2021-02-23 17:01:54 +00:00
Tiddler >> created [
^ created ifNil: [ created := self class nowLocal ]
2021-02-23 17:01:54 +00:00
]
{ #category : #accessing }
2021-02-23 17:01:54 +00:00
Tiddler >> created: anObject [
created := anObject
]
{ #category : #accessing }
2021-02-23 17:01:54 +00:00
Tiddler >> creator [
^ creator
]
{ #category : #accessing }
2021-02-23 17:01:54 +00:00
Tiddler >> creator: anObject [
creator := anObject
]
{ #category : #accessing }
Tiddler >> customFields [
^ customFields ifNil: [ customFields := Dictionary new]
]
{ #category : #accessing }
Tiddler >> deleteUid [
self customFields deleteKey: 'uid'.
]
{ #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 }
2021-09-09 01:00:14 +00:00
Tiddler >> exportSTONFile [
^ self exportSTONFileInto: 'tiddlers'
]
{ #category : #accessing }
Tiddler >> exportSTONFileInto: subfolder [
2022-03-08 23:41:54 +00:00
| stonFile output dashedTitle sanitized |
dashedTitle := '-' join: (self title substrings collect: [ :each | each ]).
2022-01-26 23:12:50 +00:00
sanitized := dashedTitle copyWithoutAll: #($¿ $? $! $/).
stonFile := self wiki file parent / subfolder / (sanitized, '--', (self uid copyFrom: 1 to: 5), '.ston').
2021-09-09 01:00:14 +00:00
^ MarkupFile exportAsFileOn: stonFile containing: self asStonStringPretty
]
{ #category : #accessing }
2021-09-04 23:14:24 +00:00
Tiddler >> exportWithTemplate: aTemplate [
^ aTemplate asMustacheTemplate value: self asDictionary
]
{ #category : #accessing }
2021-08-11 17:10:53 +00:00
Tiddler >> fromDictionary: aDictionary [
| customKeys |
2021-08-11 17:10:53 +00:00
self
title: (aDictionary at: 'title');
2021-09-06 23:27:40 +00:00
text: (aDictionary at: 'text' ifAbsentPut: [ nil ]);
2021-08-11 17:10:53 +00:00
tags: (aDictionary at: 'tags' ifAbsentPut: [ nil ]);
created: (aDictionary at: 'created' ifAbsentPut: [ self class nowLocal ]);
2021-08-11 17:10:53 +00:00
creator: (aDictionary at: 'creator' ifAbsentPut: [ nil ]);
modified: (aDictionary at: 'modified' ifAbsentPut: [ nil ]);
modifier: (aDictionary at: 'modifier' ifAbsentPut: [ nil ]);
type: (aDictionary at: 'type' ifAbsentPut: [ nil ]);
2021-09-01 22:42:21 +00:00
caption: (aDictionary at: 'caption' ifAbsentPut: [ nil ]);
bag: (aDictionary at: 'bag' ifAbsentPut: [ nil ]);
2021-10-04 20:20:55 +00:00
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 | | 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
].
2021-08-11 17:10:53 +00:00
]
{ #category : #'instance creation' }
2021-02-23 17:01:54 +00:00
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 [
<gtView>
^ aView textEditor
title: 'Text';
text: [ text ]
]
{ #category : #accessing }
2021-08-04 16:36:20 +00:00
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 = '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 }
2021-02-23 17:01:54 +00:00
Tiddler >> itemContentsStringFor: item into: stream [
stream
nextPutAll: item text;
nextPut: Character cr;
nextPut: Character cr
]
{ #category : #accessing }
Tiddler >> linkedTiddlers [
2021-08-17 18:24:00 +00:00
"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."
2021-08-17 18:24:00 +00:00
| pureTiddlersTitles |
2021-10-20 14:29:35 +00:00
self rawLinks ifNil: [ ^nil ].
2021-08-17 18:24:00 +00:00
pureTiddlersTitles := self rawLinks difference: self rawAliasedLinks.
^ self wiki tiddlers select: [:tiddler | pureTiddlersTitles includes: tiddler title ].
]
{ #category : #accessing }
2021-02-23 17:01:54 +00:00
Tiddler >> list [
^ list
]
{ #category : #accessing }
2021-02-23 17:01:54 +00:00
Tiddler >> list: anObject [
list := anObject
]
{ #category : #accessing }
2021-10-06 00:26:17 +00:00
Tiddler >> listedTiddlers [
2021-10-06 21:17:59 +00:00
"I export all tiddlers in the list field as an alphabetic collection.
2021-11-10 15:28:42 +00:00
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."
2021-10-06 21:17:59 +00:00
| remainList remainListArray listedTiddlers |
2021-10-06 00:26:17 +00:00
self list ifNil: [^ nil ].
2021-10-06 21:17:59 +00:00
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 }
2021-10-06 21:17:59 +00:00
Tiddler >> manualLinksList [
self list ifNil: [^ nil].
^ WikiTextGrammar new linkSea star parse: self list.
2021-10-06 00:26:17 +00:00
]
{ #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 }
2021-02-23 17:01:54 +00:00
Tiddler >> modified [
^ modified
2021-02-23 17:01:54 +00:00
]
{ #category : #accessing }
2021-02-23 17:01:54 +00:00
Tiddler >> modified: anObject [
modified := anObject
]
{ #category : #accessing }
Tiddler >> modifier [
2021-02-23 17:01:54 +00:00
^ modifier
2021-02-23 17:01:54 +00:00
]
{ #category : #accessing }
Tiddler >> modifier: anObject [
modifier := anObject
]
2021-02-23 17:01:54 +00:00
{ #category : #accessing }
Tiddler >> printOn: aStream [
super printOn: aStream.
aStream
nextPutAll: '( ', self title, ' )'
2021-02-23 17:01:54 +00:00
]
2021-10-20 14:29:35 +00:00
{ #category : #accessing }
Tiddler >> rawAliasedLinks [
^ self rawLinks select: [ :each | each includesSubstring: '|' ]
]
{ #category : #accessing }
Tiddler >> rawLinks [
2021-10-20 14:29:35 +00:00
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 }
2021-02-23 17:01:54 +00:00
Tiddler >> tags [
^ tags
]
{ #category : #accessing }
2021-02-23 17:01:54 +00:00
Tiddler >> tags: anObject [
tags := anObject
]
{ #category : #accessing }
2021-02-23 17:01:54 +00:00
Tiddler >> text [
^ text
]
{ #category : #accessing }
2021-02-23 17:01:54 +00:00
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 }
2021-02-23 17:01:54 +00:00
Tiddler >> title [
^ title
]
{ #category : #accessing }
2021-02-23 17:01:54 +00:00
Tiddler >> title: anObject [
title := anObject
]
{ #category : #accessing }
2021-02-23 17:01:54 +00:00
Tiddler >> type [
^ type
]
{ #category : #accessing }
2021-02-23 17:01:54 +00:00
Tiddler >> type: anObject [
type := anObject
]
{ #category : #accessing }
Tiddler >> uid [
^ self customFields at: 'uid' ifAbsentPut: [ self uidGenerator ].
]
{ #category : #accessing }
Tiddler >> uidGenerator [
| tempId |
self created
ifNotNil: [ tempId := self created hash hex. ]
ifNil: [ tempId := self class nowLocal hash hex ].
self customFields at: 'uid' put: tempId .
^ tempId
]
{ #category : #accessing }
Tiddler >> wiki [
^ wiki
]
{ #category : #accessing }
Tiddler >> wiki: aTiddlyWiki [
wiki := aTiddlyWiki
]