aboutsummaryrefslogtreecommitdiffstats
path: root/tiddlers
diff options
context:
space:
mode:
authorshu <nvcsadjkojf@outlook.com>2026-07-26 18:33:43 +0800
committershu <nvcsadjkojf@outlook.com>2026-07-26 18:33:43 +0800
commitc1414f940c1fca93df0c266a3e90c9ff1d7e88c7 (patch)
tree4d613a365905d12699d71b3bfb2f68d2a7089c1c /tiddlers
Initial TiddlyWiki setup
Diffstat (limited to 'tiddlers')
-rw-r--r--tiddlers/$__DefaultTiddlers.tid6
-rw-r--r--tiddlers/$__StoryList.tid3
-rw-r--r--tiddlers/$__config_PageControlButtons_Visibility_$__core_ui_Buttons_home.tid6
-rw-r--r--tiddlers/$__config_PageControlButtons_Visibility_$__core_ui_Buttons_new-journal.tid6
-rw-r--r--tiddlers/$__config_ShowHelp.tid6
-rw-r--r--tiddlers/$__config_StackedStoryViewFanHeight.tid6
-rw-r--r--tiddlers/$__config_ViewToolbarButtons_Visibility_$__core_ui_Buttons_close-others.tid6
-rw-r--r--tiddlers/$__config_codemirror_lineNumbers1
-rw-r--r--tiddlers/$__config_codemirror_lineNumbers.meta4
-rw-r--r--tiddlers/$__config_codemirror_styleActiveLine1
-rw-r--r--tiddlers/$__config_codemirror_styleActiveLine.meta4
-rw-r--r--tiddlers/$__github-ribbon.tid15
-rw-r--r--tiddlers/$__language.tid6
-rw-r--r--tiddlers/$__theme.tid6
-rw-r--r--tiddlers/$__themes_tiddlywiki_vanilla_settings_codefontfamily.tid6
-rw-r--r--tiddlers/$__themes_tiddlywiki_vanilla_settings_fontfamily.tid6
-rw-r--r--tiddlers/$__view.tid6
-rw-r--r--tiddlers/2026年07月26日.tid7
-rw-r--r--tiddlers/HelloThere.tid12
-rw-r--r--tiddlers/copy-codeblock.tid72
-rw-r--r--tiddlers/current-tiddler-toc-widget.tid284
-rw-r--r--tiddlers/files API demo.tid51
-rw-r--r--tiddlers/files-list-api.tid132
-rw-r--r--tiddlers/files-list-api.tid.js.meta5
-rw-r--r--tiddlers/highlight-caddyfile.tid65
-rw-r--r--tiddlers/highlight-json5.tid59
-rw-r--r--tiddlers/highlight-tiddlywiki.tid191
-rw-r--r--tiddlers/sidebar-current-tiddler-toc.tid69
-rw-r--r--tiddlers/tag.tid29
-rw-r--r--tiddlers/tiddlywiki.tid112
-rw-r--r--tiddlers/🍀.tid20
31 files changed, 1202 insertions, 0 deletions
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