diff options
| author | shu <nvcsadjkojf@outlook.com> | 2026-07-26 18:33:43 +0800 |
|---|---|---|
| committer | shu <nvcsadjkojf@outlook.com> | 2026-07-26 18:33:43 +0800 |
| commit | c1414f940c1fca93df0c266a3e90c9ff1d7e88c7 (patch) | |
| tree | 4d613a365905d12699d71b3bfb2f68d2a7089c1c | |
Initial TiddlyWiki setup
35 files changed, 1295 insertions, 0 deletions
diff --git a/files/photo_2026-07-26_11-10-12.jpg b/files/photo_2026-07-26_11-10-12.jpg Binary files differnew file mode 100644 index 0000000..7ddab14 --- /dev/null +++ b/files/photo_2026-07-26_11-10-12.jpg diff --git a/scripts/dev.sh b/scripts/dev.sh new file mode 100755 index 0000000..7d43567 --- /dev/null +++ b/scripts/dev.sh @@ -0,0 +1,3 @@ +#/usr/bin/bash + +tiddlywiki . --listen port=10000 gzip=yes use-browser-cache=yes
\ No newline at end of file diff --git a/scripts/run.sh b/scripts/run.sh new file mode 100755 index 0000000..9164aa6 --- /dev/null +++ b/scripts/run.sh @@ -0,0 +1,3 @@ +#/usr/bin/bash + +tiddlywiki . --listen port=10000 use-browser-cache=yes
\ No newline at end of file diff --git a/tiddlers/$__DefaultTiddlers.tid b/tiddlers/$__DefaultTiddlers.tid new file mode 100644 index 0000000..21ef1e1 --- /dev/null +++ b/tiddlers/$__DefaultTiddlers.tid @@ -0,0 +1,6 @@ +created: 20131127215321439 +modified: 20260726054622104 +title: $:/DefaultTiddlers +type: text/vnd.tiddlywiki + +tiddlywiki
\ No newline at end of file diff --git a/tiddlers/$__StoryList.tid b/tiddlers/$__StoryList.tid new file mode 100644 index 0000000..b403e3e --- /dev/null +++ b/tiddlers/$__StoryList.tid @@ -0,0 +1,3 @@ +list: 2026年07月26日 tiddlywiki +title: $:/StoryList +type: text/vnd.tiddlywiki
\ No newline at end of file diff --git a/tiddlers/$__config_PageControlButtons_Visibility_$__core_ui_Buttons_home.tid b/tiddlers/$__config_PageControlButtons_Visibility_$__core_ui_Buttons_home.tid new file mode 100644 index 0000000..67bceca --- /dev/null +++ b/tiddlers/$__config_PageControlButtons_Visibility_$__core_ui_Buttons_home.tid @@ -0,0 +1,6 @@ +created: 20260726102227492 +modified: 20260726102227492 +title: $:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/home +type: text/vnd.tiddlywiki + +show
\ No newline at end of file diff --git a/tiddlers/$__config_PageControlButtons_Visibility_$__core_ui_Buttons_new-journal.tid b/tiddlers/$__config_PageControlButtons_Visibility_$__core_ui_Buttons_new-journal.tid new file mode 100644 index 0000000..bc1a522 --- /dev/null +++ b/tiddlers/$__config_PageControlButtons_Visibility_$__core_ui_Buttons_new-journal.tid @@ -0,0 +1,6 @@ +created: 20260726102231878 +modified: 20260726102231878 +title: $:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-journal +type: text/vnd.tiddlywiki + +show
\ No newline at end of file diff --git a/tiddlers/$__config_ShowHelp.tid b/tiddlers/$__config_ShowHelp.tid new file mode 100644 index 0000000..376b420 --- /dev/null +++ b/tiddlers/$__config_ShowHelp.tid @@ -0,0 +1,6 @@ +created: 20260726044420390 +modified: 20260726044429634 +title: $:/config/ShowHelp +type: text/vnd.tiddlywiki + +no
\ No newline at end of file diff --git a/tiddlers/$__config_StackedStoryViewFanHeight.tid b/tiddlers/$__config_StackedStoryViewFanHeight.tid new file mode 100644 index 0000000..864f185 --- /dev/null +++ b/tiddlers/$__config_StackedStoryViewFanHeight.tid @@ -0,0 +1,6 @@ +created: 20260726044413716 +modified: 20260726055007638 +title: $:/config/StackedStoryViewFanHeight +type: text/vnd.tiddlywiki + +250
\ No newline at end of file diff --git a/tiddlers/$__config_ViewToolbarButtons_Visibility_$__core_ui_Buttons_close-others.tid b/tiddlers/$__config_ViewToolbarButtons_Visibility_$__core_ui_Buttons_close-others.tid new file mode 100644 index 0000000..7c069e0 --- /dev/null +++ b/tiddlers/$__config_ViewToolbarButtons_Visibility_$__core_ui_Buttons_close-others.tid @@ -0,0 +1,6 @@ +created: 20260726102133335 +modified: 20260726102133335 +title: $:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/close-others +type: text/vnd.tiddlywiki + +show
\ No newline at end of file diff --git a/tiddlers/$__config_codemirror_lineNumbers b/tiddlers/$__config_codemirror_lineNumbers new file mode 100644 index 0000000..f32a580 --- /dev/null +++ b/tiddlers/$__config_codemirror_lineNumbers @@ -0,0 +1 @@ +true
\ No newline at end of file diff --git a/tiddlers/$__config_codemirror_lineNumbers.meta b/tiddlers/$__config_codemirror_lineNumbers.meta new file mode 100644 index 0000000..7fa4175 --- /dev/null +++ b/tiddlers/$__config_codemirror_lineNumbers.meta @@ -0,0 +1,4 @@ +created: 20260726064722702 +modified: 20260726064722702 +title: $:/config/codemirror/lineNumbers +type: bool
\ No newline at end of file diff --git a/tiddlers/$__config_codemirror_styleActiveLine b/tiddlers/$__config_codemirror_styleActiveLine new file mode 100644 index 0000000..f32a580 --- /dev/null +++ b/tiddlers/$__config_codemirror_styleActiveLine @@ -0,0 +1 @@ +true
\ No newline at end of file diff --git a/tiddlers/$__config_codemirror_styleActiveLine.meta b/tiddlers/$__config_codemirror_styleActiveLine.meta new file mode 100644 index 0000000..cea5b45 --- /dev/null +++ b/tiddlers/$__config_codemirror_styleActiveLine.meta @@ -0,0 +1,4 @@ +created: 20260726064738722 +modified: 20260726064738722 +title: $:/config/codemirror/styleActiveLine +type: bool
\ No newline at end of file diff --git a/tiddlers/$__github-ribbon.tid b/tiddlers/$__github-ribbon.tid new file mode 100644 index 0000000..18c4049 --- /dev/null +++ b/tiddlers/$__github-ribbon.tid @@ -0,0 +1,15 @@ +created: 20260726044443524 +modified: 20260726051940055 +tags: $:/tags/PageTemplate +title: $:/github-ribbon +type: text/vnd.tiddlywiki + +<$transclude + $tiddler="$:/plugins/tiddlywiki/github-fork-ribbon/template" + position="right" + url="https://github.com/ocian/f" + text="在 GitHub 查看" + color="#24292f" + top="30px" + fixed="fixed" +/>
\ No newline at end of file diff --git a/tiddlers/$__language.tid b/tiddlers/$__language.tid new file mode 100644 index 0000000..db602ed --- /dev/null +++ b/tiddlers/$__language.tid @@ -0,0 +1,6 @@ +created: 20260726042314670 +modified: 20260726043257359 +title: $:/language +type: text/vnd.tiddlywiki + +$:/languages/zh-Hans
\ No newline at end of file diff --git a/tiddlers/$__theme.tid b/tiddlers/$__theme.tid new file mode 100644 index 0000000..a017f8f --- /dev/null +++ b/tiddlers/$__theme.tid @@ -0,0 +1,6 @@ +created: 20260726044518862 +modified: 20260726044539242 +title: $:/theme +type: text/vnd.tiddlywiki + +$:/themes/tiddlywiki/snowwhite
\ No newline at end of file diff --git a/tiddlers/$__themes_tiddlywiki_vanilla_settings_codefontfamily.tid b/tiddlers/$__themes_tiddlywiki_vanilla_settings_codefontfamily.tid new file mode 100644 index 0000000..e38c2a3 --- /dev/null +++ b/tiddlers/$__themes_tiddlywiki_vanilla_settings_codefontfamily.tid @@ -0,0 +1,6 @@ +created: 20260726060835918 +modified: 20260726060845913 +title: $:/themes/tiddlywiki/vanilla/settings/codefontfamily +type: text/vnd.tiddlywiki + +ui-monospace,"JetBrains Mono", "SFMono-Regular", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace
\ No newline at end of file diff --git a/tiddlers/$__themes_tiddlywiki_vanilla_settings_fontfamily.tid b/tiddlers/$__themes_tiddlywiki_vanilla_settings_fontfamily.tid new file mode 100644 index 0000000..fc62d11 --- /dev/null +++ b/tiddlers/$__themes_tiddlywiki_vanilla_settings_fontfamily.tid @@ -0,0 +1,6 @@ +created: 20260726060855282 +modified: 20260726060903020 +title: $:/themes/tiddlywiki/vanilla/settings/fontfamily +type: text/vnd.tiddlywiki + +-apple-system, BlinkMacSystemFont, "Noto Sans CJK SC", "Segoe UI", "Noto Sans", sans-serif, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"
\ No newline at end of file diff --git a/tiddlers/$__view.tid b/tiddlers/$__view.tid new file mode 100644 index 0000000..9af7273 --- /dev/null +++ b/tiddlers/$__view.tid @@ -0,0 +1,6 @@ +created: 20260726054950244 +modified: 20260726054950244 +title: $:/view +type: text/vnd.tiddlywiki + +stacked
\ No newline at end of file diff --git a/tiddlers/2026年07月26日.tid b/tiddlers/2026年07月26日.tid new file mode 100644 index 0000000..fd624e5 --- /dev/null +++ b/tiddlers/2026年07月26日.tid @@ -0,0 +1,7 @@ +created: 20260726102904258 +modified: 20260726102913646 +tags: 日志 +title: 2026年07月26日 +type: text/vnd.tiddlywiki + +今天做了什么
\ No newline at end of file diff --git a/tiddlers/HelloThere.tid b/tiddlers/HelloThere.tid new file mode 100644 index 0000000..d354a6e --- /dev/null +++ b/tiddlers/HelloThere.tid @@ -0,0 +1,12 @@ +title: HelloThere + +The "full" edition of TiddlyWiki consists of all the available languages, themes and plugins for TiddlyWiki. + +It is intended for use in testing TiddlyWiki - in particular, for switching between all the available language plugins. + +{{$:/language/ControlPanel/Basics/Language/Prompt}} {{$:/snippets/minilanguageswitcher}} + +--- + +{{$:/core/ui/ControlPanel/Plugins}} + diff --git a/tiddlers/copy-codeblock.tid b/tiddlers/copy-codeblock.tid new file mode 100644 index 0000000..2251c62 --- /dev/null +++ b/tiddlers/copy-codeblock.tid @@ -0,0 +1,72 @@ +title: $:/plugins/local/copy-codeblock/copy-codeblock.js +type: application/javascript +module-type: widget + +/*\ +title: $:/plugins/local/copy-codeblock/copy-codeblock.js +type: application/javascript +module-type: widget + +Adds a copy button to code blocks. +\*/ +(function() { +"use strict"; + +var CodeBlockWidget = require("$:/core/modules/widgets/codeblock.js").codeblock; + +var CopyCodeBlockWidget = function(parseTreeNode,options) { + this.initialise(parseTreeNode,options); +}; + +CopyCodeBlockWidget.prototype = new CodeBlockWidget(); +CopyCodeBlockWidget.prototype.constructor = CopyCodeBlockWidget; + +CopyCodeBlockWidget.prototype.postRender = function() { + var self = this, + preNode = this.domNodes[0], + previousNode, + button; + + // Preserve syntax highlighting supplied by the highlight plugin. + if(CodeBlockWidget.prototype.postRender) { + CodeBlockWidget.prototype.postRender.call(this); + } + + if(!$tw.browser || !preNode || preNode.isTiddlyWikiFakeDom) { + return; + } + + // The system code view already renders its own copy button. + previousNode = preNode.previousElementSibling; + if(previousNode && previousNode.querySelector && previousNode.querySelector(".tc-image-copy-clipboard")) { + return; + } + + preNode.style.position = "relative"; + preNode.style.paddingRight = "5em"; + + button = this.document.createElement("button"); + button.setAttribute("type","button"); + button.setAttribute("aria-label","Copy code"); + button.setAttribute("title","Copy code"); + button.className = "tc-btn-invisible tc-copy-codeblock-button"; + button.textContent = "Copy"; + button.style.position = "absolute"; + button.style.top = "0.5em"; + button.style.right = "0.5em"; + button.style.zIndex = "1"; + button.style.padding = "0.2em 0.45em"; + button.style.cursor = "pointer"; + + button.addEventListener("click",function(event) { + event.preventDefault(); + event.stopPropagation(); + $tw.utils.copyToClipboard(self.getAttribute("code","")); + }); + + preNode.appendChild(button); +}; + +exports.codeblock = CopyCodeBlockWidget; + +})(); diff --git a/tiddlers/current-tiddler-toc-widget.tid b/tiddlers/current-tiddler-toc-widget.tid new file mode 100644 index 0000000..a68e449 --- /dev/null +++ b/tiddlers/current-tiddler-toc-widget.tid @@ -0,0 +1,284 @@ +title: $:/plugins/local/current-tiddler-toc/widget.js +type: application/javascript +module-type: widget + +/*\ +title: $:/plugins/local/current-tiddler-toc/widget.js +type: application/javascript +module-type: widget + +Displays a table of contents for the current story tiddler. +\*/ +(function() { +"use strict"; + +var Widget = require("$:/core/modules/widgets/widget.js").widget; + +var CurrentTiddlerTocWidget = function(parseTreeNode,options) { + this.initialise(parseTreeNode,options); +}; + +CurrentTiddlerTocWidget.prototype = new Widget(); +CurrentTiddlerTocWidget.prototype.constructor = CurrentTiddlerTocWidget; + +CurrentTiddlerTocWidget.prototype.render = function(parent,nextSibling) { + this.parentDomNode = parent; + this.computeAttributes(); + this.execute(); + + var container = this.document.createElement("div"); + container.className = "tc-current-tiddler-toc"; + + parent.insertBefore(container,nextSibling); + this.domNodes.push(container); + this.containerNode = container; + + if($tw.browser) { + var self = this, + windowObject = this.document.defaultView || window; + + this.windowObject = windowObject; + this.resizeHandler = function() { + self.updateMaxHeight(); + }; + windowObject.addEventListener("resize",this.resizeHandler); + if(windowObject.visualViewport) { + windowObject.visualViewport.addEventListener("resize",this.resizeHandler); + } + } + + this.scheduleBuild(); +}; + +CurrentTiddlerTocWidget.prototype.execute = function() { +}; + +CurrentTiddlerTocWidget.prototype.getStoryTitles = function() { + return this.wiki.getTiddlerList("$:/StoryList") || []; +}; + +CurrentTiddlerTocWidget.prototype.findTiddlerFrame = function(title) { + var frames = this.document.querySelectorAll(".tc-tiddler-frame[data-tiddler-title]"), + index; + + for(index = 0; index < frames.length; index++) { + var frame = frames[index], + frameTitle = frame.getAttribute("data-tiddler-title"), + frameTiddler; + + if(frameTitle === title) { + return frame; + } + + frameTiddler = this.wiki.getTiddler(frameTitle); + + if(frameTiddler && (frameTiddler.fields["draft.of"] === title || frameTiddler.fields["draft.title"] === title)) { + return frame; + } + } + + return null; +}; + +CurrentTiddlerTocWidget.prototype.clearContainer = function() { + while(this.containerNode && this.containerNode.firstChild) { + this.containerNode.removeChild(this.containerNode.firstChild); + } +}; + +CurrentTiddlerTocWidget.prototype.showMessage = function(message) { + var messageNode = this.document.createElement("div"); + + messageNode.className = "tc-current-tiddler-toc-empty"; + messageNode.textContent = message; + this.containerNode.appendChild(messageNode); +}; + +CurrentTiddlerTocWidget.prototype.updateMaxHeight = function() { + if(!this.containerNode || !this.containerNode.parentNode || !this.windowObject) { + return; + } + + var viewport = this.windowObject.visualViewport, + viewportHeight = viewport ? viewport.height : this.windowObject.innerHeight, + top = this.containerNode.getBoundingClientRect().top, + availableHeight = Math.max(160,Math.floor(viewportHeight - top - 16)); + + this.containerNode.style.maxHeight = availableHeight + "px"; +}; + +CurrentTiddlerTocWidget.prototype.getHeadings = function(frame) { + var body = frame.querySelector(".tc-tiddler-body"); + + if(!body) { + body = frame.querySelector(".tc-tiddler-preview-preview"); + } + + if(!body) { + return []; + } + + var headingNodes = body.querySelectorAll("h1, h2, h3, h4, h5, h6"), + headings = [], + index; + + for(index = 0; index < headingNodes.length; index++) { + var heading = headingNodes[index]; + + // Ignore headings that belong to nested, independent tiddler frames. + if(heading.closest && heading.closest(".tc-tiddler-frame") !== frame) { + continue; + } + + headings.push({ + node: heading, + level: parseInt(heading.tagName.substring(1),10), + text: heading.textContent.trim() || "未命名标题" + }); + } + + return headings; +}; + +CurrentTiddlerTocWidget.prototype.addTiddlerGroup = function(title,frame) { + var self = this, + groupNode = this.document.createElement("section"), + titleButton = this.document.createElement("button"); + + groupNode.className = "tc-current-tiddler-toc-group"; + titleButton.setAttribute("type","button"); + titleButton.className = "tc-btn-invisible tc-current-tiddler-toc-title"; + titleButton.textContent = title; + titleButton.title = "滚动到条目:" + title; + titleButton.addEventListener("click",function(event) { + event.preventDefault(); + frame.scrollIntoView({ + behavior: "smooth", + block: "start" + }); + }); + groupNode.appendChild(titleButton); + + var headings = this.getHeadings(frame); + + if(!headings.length) { + var emptyNode = this.document.createElement("div"); + emptyNode.className = "tc-current-tiddler-toc-group-empty"; + emptyNode.textContent = "没有标题"; + groupNode.appendChild(emptyNode); + this.containerNode.appendChild(groupNode); + return; + } + + var minimumLevel = headings.reduce(function(result,heading) { + return Math.min(result,heading.level); + },6), + listNode = this.document.createElement("ol"); + + listNode.className = "tc-current-tiddler-toc-list"; + groupNode.appendChild(listNode); + + headings.forEach(function(heading) { + var itemNode = self.document.createElement("li"), + buttonNode = self.document.createElement("button"); + + itemNode.className = "tc-current-tiddler-toc-item"; + itemNode.style.paddingLeft = ((heading.level - minimumLevel) * 1.1) + "em"; + + buttonNode.setAttribute("type","button"); + buttonNode.className = "tc-btn-invisible tc-current-tiddler-toc-link"; + buttonNode.textContent = heading.text; + buttonNode.title = heading.text; + buttonNode.addEventListener("click",function(event) { + event.preventDefault(); + heading.node.scrollIntoView({ + behavior: "smooth", + block: "start" + }); + }); + + itemNode.appendChild(buttonNode); + listNode.appendChild(itemNode); + }); + + this.containerNode.appendChild(groupNode); +}; + +CurrentTiddlerTocWidget.prototype.build = function() { + if(!this.containerNode || !this.containerNode.parentNode) { + return; + } + + this.clearContainer(); + + var titles = this.getStoryTitles(), + index, + visibleCount = 0; + + if(!titles.length) { + this.showMessage("当前没有打开的条目"); + this.updateMaxHeight(); + return; + } + + for(index = 0; index < titles.length; index++) { + var title = titles[index], + frame = this.findTiddlerFrame(title); + + if(frame) { + this.addTiddlerGroup(title,frame); + visibleCount += 1; + } + } + + if(!visibleCount) { + this.showMessage("打开的条目尚未显示"); + } + + this.updateMaxHeight(); +}; + +CurrentTiddlerTocWidget.prototype.scheduleBuild = function() { + var self = this; + + if(!$tw.browser) { + return; + } + + if(this.buildTimer) { + clearTimeout(this.buildTimer); + } + + // Wait until the story river has completed the current DOM update. + this.buildTimer = setTimeout(function() { + self.buildTimer = null; + self.build(); + },0); +}; + +CurrentTiddlerTocWidget.prototype.refresh = function() { + this.computeAttributes(); + this.scheduleBuild(); + return false; +}; + +CurrentTiddlerTocWidget.prototype.removeChildDomNodes = function() { + if(this.buildTimer) { + clearTimeout(this.buildTimer); + this.buildTimer = null; + } + if(this.windowObject && this.resizeHandler) { + this.windowObject.removeEventListener("resize",this.resizeHandler); + if(this.windowObject.visualViewport) { + this.windowObject.visualViewport.removeEventListener("resize",this.resizeHandler); + } + this.resizeHandler = null; + this.windowObject = null; + } + + Widget.prototype.removeChildDomNodes.call(this); +}; + +exports["current-tiddler-toc"] = CurrentTiddlerTocWidget; + +})(); diff --git a/tiddlers/files API demo.tid b/tiddlers/files API demo.tid new file mode 100644 index 0000000..dce6e46 --- /dev/null +++ b/tiddlers/files API demo.tid @@ -0,0 +1,51 @@ +created: 20260726073547121 +modified: 20260726085801292 +tags: tiddlywiki +title: files API demo +type: text/vnd.tiddlywiki + +\procedure store-file-list() +<$action-setfield + $tiddler="$:/temp/files-list" + text=<<data>> + type="application/json" +/> +\end + +<$button> + <$action-sendmessage + $message="tm-http-request" + url="./api/files" + method="GET" + oncompletion=<<store-file-list>> + /> + 刷新文件列表 +</$button> + +<pre><$text text={{$:/temp/files-list}}/></pre> + +[img[./files/photo_2026-07-26_11-10-12.jpg]] + + +```caddyfile +example.com { + encode zstd gzip + + @api path /api/* + reverse_proxy @api localhost:3000 + + header { + X-Content-Type-Options nosniff + } +} +``` + +```json5 +{ + // 支持注释 + unquoted: 'value', + hexadecimal: 0xFF, + infinity: Infinity, + trailingComma: true, +} +```
\ No newline at end of file diff --git a/tiddlers/files-list-api.tid b/tiddlers/files-list-api.tid new file mode 100644 index 0000000..063fddb --- /dev/null +++ b/tiddlers/files-list-api.tid @@ -0,0 +1,132 @@ +title: $:/plugins/local/files-api/get-files.js +type: application/javascript +module-type: route + +/*\ +title: $:/plugins/local/files-api/get-files.js +type: application/javascript +module-type: route + +GET /api/files +\*/ +"use strict"; + +var fs = require("fs"), + path = require("path"); + +exports.methods = ["GET"]; +exports.path = /^\/api\/files\/?$/; + +exports.info = { + priority: 100 +}; + +function encodeFilePath(filename) { + return filename + .split(path.sep) + .map(encodeURIComponent) + .join("/"); +} + +async function scanDirectory(rootDirectory,directory,prefix) { + var entries, + files = []; + + try { + entries = await fs.promises.readdir(directory,{ + withFileTypes: true + }); + } catch(error) { + if(error.code === "ENOENT") { + return []; + } + throw error; + } + + for(var index = 0; index < entries.length; index++) { + var entry = entries[index]; + + // 不公开隐藏文件。 + if(entry.name.charAt(0) === ".") { + continue; + } + + var absolutePath = path.join(directory,entry.name); + + // 忽略符号链接,避免扫描到 files/ 目录之外。 + if(entry.isDirectory()) { + var childFiles = await scanDirectory( + rootDirectory, + absolutePath, + path.join(prefix,entry.name) + ); + files.push.apply(files,childFiles); + continue; + } + + if(!entry.isFile()) { + continue; + } + + var relativePath = path.join(prefix,entry.name), + extension = path.extname(entry.name).toLowerCase(), + extensionInfo = $tw.config.fileExtensionInfo[extension], + stats; + + try { + stats = await fs.promises.stat(absolutePath); + } catch(error) { + // 文件可能在扫描过程中被删除。 + continue; + } + + files.push({ + name: entry.name, + path: relativePath.split(path.sep).join("/"), + url: (prefix === "" ? "" : "") + + encodeFilePath(relativePath), + type: extensionInfo ? + extensionInfo.type : + "application/octet-stream", + size: stats.size, + modified: stats.mtime.toISOString() + }); + } + + return files; +} + +exports.handler = function(request,response,state) { + var rootDirectory = path.resolve(state.boot.wikiPath,"files"), + pathPrefix = state.pathPrefix || ""; + + scanDirectory(rootDirectory,rootDirectory,"") + .then(function(files) { + files.sort(function(left,right) { + return left.path.localeCompare(right.path); + }); + + files.forEach(function(file) { + file.url = pathPrefix + "/files/" + file.url; + }); + + state.sendResponse( + 200, + {"Content-Type": "application/json; charset=utf-8"}, + JSON.stringify(files), + "utf8" + ); + }) + .catch(function(error) { + console.error("Unable to list files directory:",error); + + state.sendResponse( + 500, + {"Content-Type": "application/json; charset=utf-8"}, + JSON.stringify({ + error: "Unable to list files directory" + }), + "utf8" + ); + }); +};
\ No newline at end of file diff --git a/tiddlers/files-list-api.tid.js.meta b/tiddlers/files-list-api.tid.js.meta new file mode 100644 index 0000000..066c85b --- /dev/null +++ b/tiddlers/files-list-api.tid.js.meta @@ -0,0 +1,5 @@ +created: 20260726082748103 +modified: 20260726082841751 +tags: tiddlywiki +title: files-list-api.tid +type: application/javascript
\ No newline at end of file diff --git a/tiddlers/highlight-caddyfile.tid b/tiddlers/highlight-caddyfile.tid new file mode 100644 index 0000000..d36ea30 --- /dev/null +++ b/tiddlers/highlight-caddyfile.tid @@ -0,0 +1,65 @@ +tiddlers/highlight-caddyfile.tid +title: $:/plugins/local/highlight-languages/caddyfile.js +type: application/javascript +module-type: highlight + +/*\ +title: $:/plugins/local/highlight-languages/caddyfile.js +type: application/javascript +module-type: highlight + +Caddyfile language definition for highlight.js. +\*/ +"use strict"; + +hljs.registerLanguage("caddyfile",function(hljs) { + return { + name: "Caddyfile", + aliases: ["caddy"], + case_insensitive: true, + contains: [ + { + className: "comment", + begin: /#/, + end: /$/ + }, + { + className: "section", + begin: /^\s*(?=[^#\n{]*(?:[.:,]|\blocalhost\b))(?:https?:\/\/)?[^\s#{}]+(?:\s*,\s*[^\s#{}]+)*(?=\s*\{?\s*$)/, + relevance: 10 + }, + { + className: "keyword", + begin: /^\s*[A-Za-z_][A-Za-z0-9_-]*(?=\s|$)/, + relevance: 1 + }, + { + className: "meta", + match: /@[A-Za-z0-9_-]+/ + }, + { + className: "variable", + match: /\{\$?[A-Za-z_][A-Za-z0-9_.\-[\]*]*\}/ + }, + { + className: "title", + match: /\([A-Za-z_][A-Za-z0-9_-]*\)/ + }, + hljs.QUOTE_STRING_MODE, + hljs.APOS_STRING_MODE, + { + className: "literal", + match: /\b(?:true|false|on|off)\b/ + }, + { + className: "number", + match: /\b\d+(?:\.\d+)?(?:ns|us|ms|s|m|h|d|kb|mb|gb|tb)?\b/i, + relevance: 0 + }, + { + className: "punctuation", + match: /[{}]/ + } + ] + }; +});
\ No newline at end of file diff --git a/tiddlers/highlight-json5.tid b/tiddlers/highlight-json5.tid new file mode 100644 index 0000000..099df98 --- /dev/null +++ b/tiddlers/highlight-json5.tid @@ -0,0 +1,59 @@ +title: $:/plugins/local/highlight-languages/json5.js +type: application/javascript +module-type: highlight + +/*\ +title: $:/plugins/local/highlight-languages/json5.js +type: application/javascript +module-type: highlight + +JSON5 language definition for highlight.js. +\*/ +"use strict"; + +hljs.registerLanguage("json5",function(hljs) { + return { + name: "JSON5", + aliases: ["json5"], + keywords: { + literal: "true false null" + }, + contains: [ + hljs.C_LINE_COMMENT_MODE, + hljs.C_BLOCK_COMMENT_MODE, + { + className: "attr", + match: /[A-Za-z_$][0-9A-Za-z_$]*(?=\s*:)/ + }, + { + className: "attr", + match: /"(?:\\.|[^"\\\r\n])*"(?=\s*:)/ + }, + { + className: "attr", + match: /'(?:\\.|[^'\\\r\n])*'(?=\s*:)/ + }, + hljs.QUOTE_STRING_MODE, + hljs.APOS_STRING_MODE, + { + className: "number", + variants: [ + { + begin: /[+-]?(?:Infinity|NaN)\b/ + }, + { + begin: /[+-]?0[xX][0-9a-fA-F]+\b/ + }, + { + begin: /[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?/ + } + ], + relevance: 0 + }, + { + className: "punctuation", + match: /[{}\[\],:]/ + } + ] + }; +});
\ No newline at end of file diff --git a/tiddlers/highlight-tiddlywiki.tid b/tiddlers/highlight-tiddlywiki.tid new file mode 100644 index 0000000..1d3d53a --- /dev/null +++ b/tiddlers/highlight-tiddlywiki.tid @@ -0,0 +1,191 @@ +title: $:/plugins/local/highlight-languages/tiddlywiki.js +type: application/javascript +module-type: highlight + +/*\ +title: $:/plugins/local/highlight-languages/tiddlywiki.js +type: application/javascript +module-type: highlight + +TiddlyWiki TID and WikiText language definition for highlight.js. +\*/ +"use strict"; + +hljs.registerLanguage("tiddlywiki",function(hljs) { + var systemTiddler = { + className: "symbol", + match: /\$:\/[^\s\][\]<>{}"']+/ + }, + variable = { + className: "variable", + variants: [ + { + begin: /<</, + end: />>/ + }, + { + match: /<[^<>\s]+>/ + } + ] + }, + transclusion = { + className: "template-variable", + variants: [ + { + begin: /\{\{\{/, + end: /\}\}\}/ + }, + { + begin: /\{\{/, + end: /\}\}/ + } + ], + contains: [ + systemTiddler, + variable + ] + }, + link = { + className: "link", + variants: [ + { + begin: /\[\[/, + end: /\]\]/ + }, + { + begin: /\[(?:img|ext)\[/, + end: /\]\]/ + } + ], + contains: [ + systemTiddler + ] + }, + filter = { + className: "selector", + begin: /\[(?=[^\]\n]*[A-Za-z][A-Za-z0-9_-]*\[)/, + end: /\]/, + contains: [ + { + className: "keyword", + match: /[A-Za-z][A-Za-z0-9_.-]*(?=\[)/ + }, + { + className: "string", + begin: /\[/, + end: /\]/, + contains: [ + systemTiddler, + variable + ] + }, + variable, + systemTiddler + ] + }; + + return { + name: "TiddlyWiki", + aliases: [ + "tid", + "wikitext" + ], + contains: [ + { + className: "comment", + begin: /<!--/, + end: /-->/ + }, + { + className: "comment", + begin: /\/%/, + end: /%\// + }, + { + className: "meta", + begin: /^\\(?:define|end|function|import|parameters|procedure|rules|whitespace|widget)\b/, + end: /$/, + contains: [ + variable, + systemTiddler, + hljs.QUOTE_STRING_MODE, + hljs.APOS_STRING_MODE + ] + }, + { + className: "attr", + match: /^[A-Za-z0-9_.-]+(?=\s*:)/ + }, + { + className: "section", + begin: /^!{1,6}\s+/, + end: /$/ + }, + { + className: "bullet", + match: /^[*#;:]+\s+/ + }, + { + className: "quote", + begin: /^>{1,3}\s+/, + end: /$/ + }, + { + className: "tag", + begin: /<\/?\$?[A-Za-z][A-Za-z0-9_.:-]*/, + end: /\/?>/, + contains: [ + { + className: "attr", + match: /[A-Za-z_$][A-Za-z0-9_.:-]*(?=\s*=)/ + }, + hljs.QUOTE_STRING_MODE, + hljs.APOS_STRING_MODE, + transclusion, + variable, + filter, + systemTiddler + ] + }, + { + className: "template-tag", + begin: /<</, + end: />>/, + contains: [ + hljs.QUOTE_STRING_MODE, + hljs.APOS_STRING_MODE, + systemTiddler + ] + }, + transclusion, + link, + filter, + systemTiddler, + { + className: "code", + begin: /`+/, + end: /`+/ + }, + { + className: "strong", + begin: /''/, + end: /''/ + }, + { + className: "emphasis", + begin: /\/\//, + end: /\/\// + }, + { + className: "emphasis", + begin: /__/, + end: /__/ + }, + { + className: "deletion", + begin: /~~/, + end: /~~/ + } + ] + }; +});
\ No newline at end of file diff --git a/tiddlers/sidebar-current-tiddler-toc.tid b/tiddlers/sidebar-current-tiddler-toc.tid new file mode 100644 index 0000000..9d73d6d --- /dev/null +++ b/tiddlers/sidebar-current-tiddler-toc.tid @@ -0,0 +1,69 @@ +title: $:/plugins/local/current-tiddler-toc/sidebar +type: text/vnd.tiddlywiki +tags: $:/tags/SideBar +caption: 目录 +list-after: $:/core/ui/SideBar/More + +<style> +.tc-current-tiddler-toc { + font-size: 0.95em; + overflow-y: auto; + overscroll-behavior: contain; + scrollbar-gutter: stable; + padding-right: 0.25em; +} + +.tc-current-tiddler-toc-group { + margin: 0 0 1em; +} + +.tc-current-tiddler-toc-title { + display: block; + width: 100%; + font-weight: 600; + margin: 0 0 0.35em; + padding: 0.2em 0; + text-align: left; + overflow-wrap: anywhere; +} + +.tc-current-tiddler-toc-list { + list-style: none; + margin: 0; + padding: 0; +} + +.tc-current-tiddler-toc-item { + margin: 0; + padding-top: 0.2em; + padding-bottom: 0.2em; +} + +.tc-current-tiddler-toc-link { + display: block; + width: 100%; + padding: 0.2em 0; + text-align: left; + line-height: 1.35; + overflow-wrap: anywhere; +} + +.tc-current-tiddler-toc-link:hover, +.tc-current-tiddler-toc-link:focus { + text-decoration: underline; +} + +.tc-current-tiddler-toc-empty { + color: <<colour muted-foreground>>; + font-style: italic; +} + +.tc-current-tiddler-toc-group-empty { + padding-left: 1.1em; + color: <<colour muted-foreground>>; + font-size: 0.9em; + font-style: italic; +} +</style> + +<$current-tiddler-toc/> diff --git a/tiddlers/tag.tid b/tiddlers/tag.tid new file mode 100644 index 0000000..e1aca35 --- /dev/null +++ b/tiddlers/tag.tid @@ -0,0 +1,29 @@ +created: 20260726102059006 +modified: 20260726102249923 +tags: 🍀 +title: tag +type: text/vnd.tiddlywiki + +<style> +.tc-all-tags { + display: flex; + flex-wrap: wrap; + align-items: flex-start; + width: 100%; + max-width: 100%; + gap: 0.5rem; +} + +.tc-all-tags .tc-tag-list-item { + margin: 0; +} +</style> + +<div class="tc-all-tags"> +<$list + filter="[all[tiddlers]tags[]!prefix[$:/]sort[title]]" + emptyMessage="目前没有普通标签。" +> +<$transclude tiddler="$:/core/ui/TagTemplate"/> +</$list> +</div> diff --git a/tiddlers/tiddlywiki.tid b/tiddlers/tiddlywiki.tid new file mode 100644 index 0000000..9c209ee --- /dev/null +++ b/tiddlers/tiddlywiki.tid @@ -0,0 +1,112 @@ +created: 20260726051257984 +modified: 20260726102329635 +tags: 资料 🍀 +title: tiddlywiki +type: text/vnd.tiddlywiki + +! 新增一个语法高亮 + +增加一个 [[tiddlers/highlight-tiddlywiki.tid|$:/plugins/local/highlight-languages/tiddlywiki.js]] 文件,重启服务就可以了 + +<details> +<summary>点击展开文件内容</summary> + +{{$:/plugins/local/highlight-languages/tiddlywiki.js}} + +</details> + +! 在侧边增加一个新的 tab + +```tid +title: $:/plugins/local/sidebar/starred +type: text/vnd.tiddlywiki +tags: $:/tags/SideBar +caption: 🍀 +list-after: $:/core/ui/SideBar/More + +<div class="tc-sidebar-tab-open"> + +<$list + filter="[tag[🍀]!has[draft.of]sort[title]]" + emptyMessage="还没有设置 🍀 标签的条目。" +> +<div class="tc-sidebar-tab-open-item"> +<$link/> +</div> +</$list> + +</div> +``` + +! 插件 - github-fork-ribbon + +在页面角落显示一个类似 GitHub “Fork me” 的斜角丝带,并链接到指定网址 + +编辑 [[$:/github-ribbon]] 并添加标签 {{$:/tags/PageTemplate||$:/core/ui/TagTemplate}} + +填写内容 + +```tid +<$transclude + $tiddler="$:/plugins/tiddlywiki/github-fork-ribbon/template" + position="right" + url="https://github.com/你的账号/你的仓库" + text="在 GitHub 查看" + color="#24292f" + top="30px" + fixed="fixed" +/> +``` + +! 插件 - 代码复制 + +在代码块右上角展示一个复制按钮,插件内容保存在 [[tiddlers/copy-codeblock.tid|$:/plugins/local/copy-codeblock/copy-codeblock.js]] + +<details> +<summary>点击展开文件内容</summary> + +{{$:/plugins/local/copy-codeblock/copy-codeblock.js}} + +</details> + +! 资源文件管理 + +图片文件可以和条目文件分开保存,可以和 html 分开加载 + +资源文件可以放置在 files 文件夹中,通过 ./files/... 的方式引用 + +资源文件的上传下载,用 webdav 好了 + +增加索取所有文件的接口,写入到 tiddlers/files-list-api.tid 文件中 + +<details> +<summary>点击展开文件内容</summary> + +{{files-list-api.tid}} + +</details> + +在 wiki 中获取文件列表 + +```tid +\procedure store-file-list() +<$action-setfield + $tiddler="$:/temp/files-list" + text=<<data>> + type="application/json" +/> +\end + +<$button> + <$action-sendmessage + $message="tm-http-request" + url="./api/files" + method="GET" + oncompletion=<<store-file-list>> + /> + 刷新文件列表 +</$button> + +<pre><$text text={{$:/temp/files-list}}/></pre> +``` + diff --git a/tiddlers/🍀.tid b/tiddlers/🍀.tid new file mode 100644 index 0000000..d0025b8 --- /dev/null +++ b/tiddlers/🍀.tid @@ -0,0 +1,20 @@ +caption: 🍀 +created: 20260726085324422 +list-after: $:/core/ui/SideBar/More +modified: 20260726085741585 +tags: $:/tags/SideBar +title: 🍀 +type: text/vnd.tiddlywiki + +<div class="tc-sidebar-tab-open"> + +<$list + filter="[tag[🍀]!has[draft.of]sort[title]]" + emptyMessage="还没有设置 🍀 标签的条目。" +> +<div class="tc-sidebar-tab-open-item"> +<$link/> +</div> +</$list> + +</div>
\ No newline at end of file diff --git a/tiddlywiki.info b/tiddlywiki.info new file mode 100644 index 0000000..e11cfa9 --- /dev/null +++ b/tiddlywiki.info @@ -0,0 +1,87 @@ +{ + "description": "Full edition, containing all languages, themes and plugins", + "plugins": [ + "tiddlywiki/filesystem", + "tiddlywiki/tiddlyweb", + "tiddlywiki/github-fork-ribbon", + "tiddlywiki/codemirror", + "tiddlywiki/highlight", + "tiddlywiki/powered-by-tiddlywiki" + ], + "plugins-disabled": [ + "tiddlywiki/browser-sniff", + "tiddlywiki/browser-storage", + "tiddlywiki/bibtex", + "tiddlywiki/classictools", + "tiddlywiki/comments", + "tiddlywiki/innerwiki", + "tiddlywiki/internals", + "tiddlywiki/jszip", + "tiddlywiki/katex", + "tiddlywiki/markdown", + "tiddlywiki/qrcode", + "tiddlywiki/railroad", + "tiddlywiki/twitter", + "tiddlywiki/xlsx-utils", + "tiddlywiki/sax", + "tiddlywiki/text-slicer", + "tiddlywiki/xmldom", + "tiddlywiki/stacked-view" + ], + "languages": [ + "zh-Hans" + ], + "languages-disabled": [ + "ar-PS", + "ca-ES", + "cs-CZ", + "da-DK", + "de-AT", + "de-DE", + "el-GR", + "en-PH", + "en-US", + "es-ES", + "fa-IR", + "fr-FR", + "he-IL", + "hi-IN", + "ia-IA", + "it-IT", + "ja-JP", + "ko-KR", + "mk-MK", + "nl-NL", + "pa-IN", + "pl-PL", + "pt-PT", + "pt-BR", + "ru-RU", + "sk-SK", + "sl-SI", + "sv-SE", + "zh-Hant", + "zh-HK" + ], + "themes": [ + "tiddlywiki/snowwhite", + "tiddlywiki/vanilla" + ], + "themes-disabled": [ + "tiddlywiki/centralised", + "tiddlywiki/tight", + "tiddlywiki/heavier", + "tiddlywiki/tight-heavier", + "tiddlywiki/readonly", + "tiddlywiki/seamless", + "tiddlywiki/starlight" + ], + "build": { + "index": [ + "--rendertiddler", + "$:/core/save/all", + "index.html", + "text/plain" + ] + } +}
\ No newline at end of file |
