mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-01-25 04:14:40 +00:00
Compare commits
12 Commits
filter-ins
...
wikify-ope
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e47b88dc7 | ||
|
|
48b45f0e35 | ||
|
|
da4f5c64ca | ||
|
|
a0fbd4e0f3 | ||
|
|
77cb8335c1 | ||
|
|
55b680e485 | ||
|
|
80058e7f45 | ||
|
|
9df912a341 | ||
|
|
082654564a | ||
|
|
1480d495b3 | ||
|
|
5e8d6fb790 | ||
|
|
55cf0b2965 |
50
.github/workflows/pr-check-build-size.yml
vendored
Normal file
50
.github/workflows/pr-check-build-size.yml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
name: Calculate PR build size
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, reopened, synchronize]
|
||||
|
||||
jobs:
|
||||
calculate-build-size:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: read
|
||||
contents: read
|
||||
outputs:
|
||||
pr_size: ${{ steps.get_sizes.outputs.pr_size }}
|
||||
base_size: ${{ steps.get_sizes.outputs.base_size }}
|
||||
steps:
|
||||
- name: build-size-check
|
||||
id: get_sizes
|
||||
uses: TiddlyWiki/cerebrus@v4
|
||||
with:
|
||||
pr_number: ${{ github.event.pull_request.number }}
|
||||
repo: ${{ github.repository }}
|
||||
base_ref: ${{ github.base_ref }}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
mode: size:calc
|
||||
|
||||
dispatch-followup:
|
||||
needs: calculate-build-size
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: write # Required to dispatch another workflow
|
||||
pull-requests: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: Trigger follow-up workflow
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
await github.rest.actions.createWorkflowDispatch({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
workflow_id: 'pr-comment-build-size.yml',
|
||||
ref: 'master',
|
||||
inputs: {
|
||||
pr_number: '${{ github.event.pull_request.number }}',
|
||||
base_ref: '${{ github.event.pull_request.base.ref }}',
|
||||
pr_size: '${{ needs.calculate-build-size.outputs.pr_size }}',
|
||||
base_size: '${{ needs.calculate-build-size.outputs.base_size }}'
|
||||
}
|
||||
});
|
||||
36
.github/workflows/pr-comment-build-size.yml
vendored
Normal file
36
.github/workflows/pr-comment-build-size.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: Comment on PR build size (Trusted workflow)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
pr_number:
|
||||
required: true
|
||||
type: string
|
||||
base_ref:
|
||||
required: true
|
||||
type: string
|
||||
pr_size:
|
||||
required: true
|
||||
type: string
|
||||
base_size:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
comment-on-pr:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Build and check size
|
||||
uses: TiddlyWiki/cerebrus@v4
|
||||
with:
|
||||
pr_number: ${{ inputs.pr_number }}
|
||||
repo: ${{ github.repository }}
|
||||
base_ref: ${{ inputs.base_ref }}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
mode: size:comment
|
||||
pr_size: ${{ inputs.pr_size }}
|
||||
base_size: ${{ inputs.base_size }}
|
||||
18
.github/workflows/pr-path-validation.yml
vendored
Normal file
18
.github/workflows/pr-path-validation.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: Validate PR Paths
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, reopened, synchronize]
|
||||
|
||||
jobs:
|
||||
validate-pr:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Validate PR
|
||||
uses: TiddlyWiki/cerebrus@v4
|
||||
with:
|
||||
pr_number: ${{ github.event.pull_request.number }}
|
||||
repo: ${{ github.repository }}
|
||||
base_ref: ${{ github.base_ref }}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
37
core/modules/filters/wikify.js
Normal file
37
core/modules/filters/wikify.js
Normal file
@@ -0,0 +1,37 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/wikify.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operator wikifying each string in the input list and returning the result as a list of strings
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.wikify = function(source,operator,options) {
|
||||
var output = operator.operands[0],
|
||||
mode = operator.operands[1],
|
||||
type = operator.operands[2],
|
||||
results = [];
|
||||
source(function(tiddler,title) {
|
||||
var wikifier = new $tw.utils.Wikifier({
|
||||
wiki: options.wiki,
|
||||
widget: options.widget,
|
||||
text: title,
|
||||
type: type,
|
||||
mode: mode,
|
||||
output: output
|
||||
});
|
||||
results.push(wikifier.getResult());
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -50,7 +50,7 @@ exports.parse = function() {
|
||||
var reEnd;
|
||||
if(this.match[5]) {
|
||||
// If so, it is a multiline definition and the end of the body is marked with \end
|
||||
reEnd = new RegExp("((:?^|\\r?\\n)[^\\S\\n\\r]*\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[2]) + ")?(?:$|\\r?\\n))","mg");
|
||||
reEnd = new RegExp("((:?^|\\r?\\n)[^\\S\\n\\r]*\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[2]) + ")?\\s*?(?:$|\\r?\\n))","mg");
|
||||
} else {
|
||||
// Otherwise, the end of the definition is marked by the end of the line
|
||||
reEnd = /($|\r?\n)/mg;
|
||||
|
||||
@@ -55,7 +55,7 @@ exports.parse = function() {
|
||||
var reEnd;
|
||||
if(this.match[3]) {
|
||||
// If so, it is a multiline definition and the end of the body is marked with \end
|
||||
reEnd = new RegExp("((?:^|\\r?\\n)[^\\S\\n\\r]*\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[1]) + ")?(?:$|\\r?\\n))","mg");
|
||||
reEnd = new RegExp("((?:^|\\r?\\n)[^\\S\\n\\r]*\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[1]) + ")?\\s*?(?:$|\\r?\\n))","mg");
|
||||
} else {
|
||||
// Otherwise, the end of the definition is marked by the end of the line
|
||||
reEnd = /($|\r?\n)/mg;
|
||||
|
||||
108
core/modules/utils/wikifier.js
Normal file
108
core/modules/utils/wikifier.js
Normal file
@@ -0,0 +1,108 @@
|
||||
/*\
|
||||
title: $:/core/modules/utils/wikifier.js
|
||||
type: application/javascript
|
||||
module-type: utils
|
||||
|
||||
A high level helper class for parsing and wikification
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*
|
||||
Options include:
|
||||
wiki: wiki to be used for wikification
|
||||
widget: optional widget to be used as parent of wikified text
|
||||
text: text to be parsed/wikified
|
||||
type: type of the text
|
||||
mode: inline or block
|
||||
output: text, formattedtext, html, parsetree or widgettree
|
||||
*/
|
||||
function Wikifier(options) {
|
||||
this.wiki = options.wiki || $tw.wiki;
|
||||
this.widget = options.widget || $tw.rootWidget;
|
||||
this.text = options.text || "";
|
||||
this.type = options.type || "";
|
||||
this.mode = options.mode || "block";
|
||||
this.output = options.output || "text";
|
||||
// Create the parse tree
|
||||
this.parser = this.wiki.parseText(this.type,this.text,{
|
||||
parseAsInline: this.mode === "inline"
|
||||
});
|
||||
// Create the widget tree
|
||||
this.widgetNode = this.wiki.makeWidget(this.parser,{
|
||||
document: $tw.fakeDocument,
|
||||
parentWidget: this.widget
|
||||
});
|
||||
// Render the widget tree to the container
|
||||
this.container = $tw.fakeDocument.createElement("div");
|
||||
this.widgetNode.render(this.container,null);
|
||||
};
|
||||
|
||||
Wikifier.prototype.refresh = function(changedTiddlers) {
|
||||
// Refresh the widget tree
|
||||
return this.widgetNode.refresh(changedTiddlers);
|
||||
};
|
||||
|
||||
/*
|
||||
Return the result string
|
||||
*/
|
||||
Wikifier.prototype.getResult = function() {
|
||||
var result;
|
||||
switch(this.output) {
|
||||
case "text":
|
||||
result = this.container.textContent;
|
||||
break;
|
||||
case "formattedtext":
|
||||
result = this.container.formattedTextContent;
|
||||
break;
|
||||
case "html":
|
||||
result = this.container.innerHTML;
|
||||
break;
|
||||
case "parsetree":
|
||||
result = JSON.stringify(this.parser.tree,0,$tw.config.preferences.jsonSpaces);
|
||||
break;
|
||||
case "widgettree":
|
||||
result = JSON.stringify(this.getWidgetTree(),0,$tw.config.preferences.jsonSpaces);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/*
|
||||
Return a string of the widget tree
|
||||
*/
|
||||
Wikifier.prototype.getWidgetTree = function() {
|
||||
var copyNode = function(widgetNode,resultNode) {
|
||||
var type = widgetNode.parseTreeNode.type;
|
||||
resultNode.type = type;
|
||||
switch(type) {
|
||||
case "element":
|
||||
resultNode.tag = widgetNode.parseTreeNode.tag;
|
||||
break;
|
||||
case "text":
|
||||
resultNode.text = widgetNode.parseTreeNode.text;
|
||||
break;
|
||||
}
|
||||
if(Object.keys(widgetNode.attributes || {}).length > 0) {
|
||||
resultNode.attributes = {};
|
||||
$tw.utils.each(widgetNode.attributes,function(attr,attrName) {
|
||||
resultNode.attributes[attrName] = widgetNode.getAttribute(attrName);
|
||||
});
|
||||
}
|
||||
if(Object.keys(widgetNode.children || {}).length > 0) {
|
||||
resultNode.children = [];
|
||||
$tw.utils.each(widgetNode.children,function(widgetChildNode) {
|
||||
var node = {};
|
||||
resultNode.children.push(node);
|
||||
copyNode(widgetChildNode,node);
|
||||
});
|
||||
}
|
||||
},
|
||||
results = {};
|
||||
copyNode(this.widgetNode,results);
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.Wikifier = Wikifier;
|
||||
|
||||
})();
|
||||
@@ -36,89 +36,22 @@ Compute the internal state of the widget
|
||||
WikifyWidget.prototype.execute = function() {
|
||||
// Get our parameters
|
||||
this.wikifyName = this.getAttribute("name");
|
||||
this.wikifyText = this.getAttribute("text");
|
||||
this.wikifyType = this.getAttribute("type");
|
||||
this.wikifyMode = this.getAttribute("mode","block");
|
||||
this.wikifyOutput = this.getAttribute("output","text");
|
||||
// Create the parse tree
|
||||
this.wikifyParser = this.wiki.parseText(this.wikifyType,this.wikifyText,{
|
||||
parseAsInline: this.wikifyMode === "inline"
|
||||
});
|
||||
// Create the widget tree
|
||||
this.wikifyWidgetNode = this.wiki.makeWidget(this.wikifyParser,{
|
||||
document: $tw.fakeDocument,
|
||||
parentWidget: this
|
||||
});
|
||||
// Render the widget tree to the container
|
||||
this.wikifyContainer = $tw.fakeDocument.createElement("div");
|
||||
this.wikifyWidgetNode.render(this.wikifyContainer,null);
|
||||
this.wikifyResult = this.getResult();
|
||||
// Create the wikifier
|
||||
this.wikifier = new $tw.utils.Wikifier({
|
||||
wiki: this.wiki,
|
||||
widget: this,
|
||||
text: this.getAttribute("text"),
|
||||
type: this.getAttribute("type"),
|
||||
mode: this.getAttribute("mode","block"),
|
||||
output: this.getAttribute("output","text")
|
||||
});
|
||||
this.wikifyResult = this.wikifier.getResult();
|
||||
// Set context variable
|
||||
this.setVariable(this.wikifyName,this.wikifyResult);
|
||||
// Construct the child widgets
|
||||
this.makeChildWidgets();
|
||||
};
|
||||
|
||||
/*
|
||||
Return the result string
|
||||
*/
|
||||
WikifyWidget.prototype.getResult = function() {
|
||||
var result;
|
||||
switch(this.wikifyOutput) {
|
||||
case "text":
|
||||
result = this.wikifyContainer.textContent;
|
||||
break;
|
||||
case "formattedtext":
|
||||
result = this.wikifyContainer.formattedTextContent;
|
||||
break;
|
||||
case "html":
|
||||
result = this.wikifyContainer.innerHTML;
|
||||
break;
|
||||
case "parsetree":
|
||||
result = JSON.stringify(this.wikifyParser.tree,0,$tw.config.preferences.jsonSpaces);
|
||||
break;
|
||||
case "widgettree":
|
||||
result = JSON.stringify(this.getWidgetTree(),0,$tw.config.preferences.jsonSpaces);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/*
|
||||
Return a string of the widget tree
|
||||
*/
|
||||
WikifyWidget.prototype.getWidgetTree = function() {
|
||||
var copyNode = function(widgetNode,resultNode) {
|
||||
var type = widgetNode.parseTreeNode.type;
|
||||
resultNode.type = type;
|
||||
switch(type) {
|
||||
case "element":
|
||||
resultNode.tag = widgetNode.parseTreeNode.tag;
|
||||
break;
|
||||
case "text":
|
||||
resultNode.text = widgetNode.parseTreeNode.text;
|
||||
break;
|
||||
}
|
||||
if(Object.keys(widgetNode.attributes || {}).length > 0) {
|
||||
resultNode.attributes = {};
|
||||
$tw.utils.each(widgetNode.attributes,function(attr,attrName) {
|
||||
resultNode.attributes[attrName] = widgetNode.getAttribute(attrName);
|
||||
});
|
||||
}
|
||||
if(Object.keys(widgetNode.children || {}).length > 0) {
|
||||
resultNode.children = [];
|
||||
$tw.utils.each(widgetNode.children,function(widgetChildNode) {
|
||||
var node = {};
|
||||
resultNode.children.push(node);
|
||||
copyNode(widgetChildNode,node);
|
||||
});
|
||||
}
|
||||
},
|
||||
results = {};
|
||||
copyNode(this.wikifyWidgetNode,results);
|
||||
return results;
|
||||
};
|
||||
|
||||
/*
|
||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||
*/
|
||||
@@ -130,9 +63,9 @@ WikifyWidget.prototype.refresh = function(changedTiddlers) {
|
||||
return true;
|
||||
} else {
|
||||
// Refresh the widget tree
|
||||
if(this.wikifyWidgetNode.refresh(changedTiddlers)) {
|
||||
if(this.wikifier.refresh(changedTiddlers)) {
|
||||
// Check if there was any change
|
||||
var result = this.getResult();
|
||||
var result = this.wikifier.getResult();
|
||||
if(result !== this.wikifyResult) {
|
||||
// If so, save the change
|
||||
this.wikifyResult = result;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
title: Operators/Wikify/TextMode
|
||||
description: Simple wikify operator
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\parsermode inline
|
||||
<$text text={{{ [subfilter{Filter}] }}}/>
|
||||
+
|
||||
title: Filter
|
||||
|
||||
[{Text}wikify[html],[inline],[text/vnd.tiddlywiki]]
|
||||
+
|
||||
title: Text
|
||||
|
||||
This is ''the text'' that is __wikified__
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
This is <strong>the text</strong> that is <u>wikified</u>
|
||||
@@ -0,0 +1,64 @@
|
||||
title: Operators/Wikify/ParseTreeMode
|
||||
description: Simple wikify operator
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\parsermode inline
|
||||
<$text text={{{ [subfilter{Filter}] }}}/>
|
||||
+
|
||||
title: Filter
|
||||
|
||||
[{Text}wikify[parsetree],[inline],[text/vnd.tiddlywiki]]
|
||||
+
|
||||
title: Text
|
||||
|
||||
This is ''the text'' that is __wikified__
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
[
|
||||
{
|
||||
"type": "text",
|
||||
"text": "This is ",
|
||||
"start": 0,
|
||||
"end": 8
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"tag": "strong",
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "the text",
|
||||
"start": 10,
|
||||
"end": 18
|
||||
}
|
||||
],
|
||||
"start": 8,
|
||||
"end": 20,
|
||||
"rule": "bold"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"text": " that is ",
|
||||
"start": 20,
|
||||
"end": 29
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"tag": "u",
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "wikified",
|
||||
"start": 31,
|
||||
"end": 39
|
||||
}
|
||||
],
|
||||
"start": 29,
|
||||
"end": 41,
|
||||
"rule": "underscore"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,21 @@
|
||||
title: Operators/Wikify/TextMode
|
||||
description: Simple wikify operator
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\parsermode inline
|
||||
<$text text={{{ [subfilter{Filter}] }}}/>
|
||||
+
|
||||
title: Filter
|
||||
|
||||
[{Text}wikify[text],[inline],[text/vnd.tiddlywiki]]
|
||||
+
|
||||
title: Text
|
||||
|
||||
This is ''the text'' that is __wikified__
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
This is the text that is wikified
|
||||
@@ -116,6 +116,22 @@ describe("WikiText parser tests", function() {
|
||||
);
|
||||
});
|
||||
|
||||
it("should parse macro definitions with end statements followed by spaces", function() {
|
||||
expect(parse("\\define myMacro()\nnothing\n\\end \n")).toEqual(
|
||||
|
||||
[{"type":"set","attributes":{"name":{"name":"name","type":"string","value":"myMacro"},"value":{"name":"value","type":"string","value":"nothing"}},"children":[],"params":[],"isMacroDefinition":true,"orderedAttributes":[{"name":"name","type":"string","value":"myMacro"},{"name":"value","type":"string","value":"nothing"}],"start":0,"end":33,"rule":"macrodef"}]
|
||||
|
||||
);
|
||||
});
|
||||
|
||||
it("should parse macro definitions with named end statements followed by spaces", function() {
|
||||
expect(parse("\\define myMacro()\nnothing\n\\end myMacro \n")).toEqual(
|
||||
|
||||
[{"type":"set","attributes":{"name":{"name":"name","type":"string","value":"myMacro"},"value":{"name":"value","type":"string","value":"nothing"}},"children":[],"params":[],"isMacroDefinition":true,"orderedAttributes":[{"name":"name","type":"string","value":"myMacro"},{"name":"value","type":"string","value":"nothing"}],"start":0,"end":40,"rule":"macrodef"}]
|
||||
|
||||
);
|
||||
});
|
||||
|
||||
it("should parse procedure definitions with no parameters", function() {
|
||||
expect(parse("\\procedure myMacro()\nnothing\n\\end\n")).toEqual(
|
||||
|
||||
@@ -132,6 +148,22 @@ describe("WikiText parser tests", function() {
|
||||
);
|
||||
});
|
||||
|
||||
it("should parse procedure definitions with end statements followed by spaces", function() {
|
||||
expect(parse("\\procedure myMacro()\nnothing\n\\end \n")).toEqual(
|
||||
|
||||
[{"type":"set","attributes":{"name":{"name":"name","type":"string","value":"myMacro"},"value":{"name":"value","type":"string","value":"nothing"}},"children":[],"params":[],"orderedAttributes":[{"name":"name","type":"string","value":"myMacro"},{"name":"value","type":"string","value":"nothing"}],"isProcedureDefinition":true,"start":0,"end":36,"rule":"fnprocdef"}]
|
||||
|
||||
);
|
||||
});
|
||||
|
||||
it("should parse procedure definitions with named end statements followed by spaces", function() {
|
||||
expect(parse("\\procedure myMacro()\nnothing\n\\end myMacro \n")).toEqual(
|
||||
|
||||
[{"type":"set","attributes":{"name":{"name":"name","type":"string","value":"myMacro"},"value":{"name":"value","type":"string","value":"nothing"}},"children":[],"params":[],"orderedAttributes":[{"name":"name","type":"string","value":"myMacro"},{"name":"value","type":"string","value":"nothing"}],"isProcedureDefinition":true,"start":0,"end":43,"rule":"fnprocdef"}]
|
||||
|
||||
);
|
||||
});
|
||||
|
||||
it("should parse procedure definitions with parameters", function() {
|
||||
expect(parse("\\procedure myMacro(one,two,three,four:elephant)\nnothing\n\\end\n")).toEqual(
|
||||
|
||||
@@ -155,6 +187,22 @@ describe("WikiText parser tests", function() {
|
||||
);
|
||||
});
|
||||
|
||||
it("should parse function definitions with end statements followed by spaces", function() {
|
||||
expect(parse("\\function myMacro()\nnothing\n\\end \n")).toEqual(
|
||||
|
||||
[{"type":"set","attributes":{"name":{"name":"name","type":"string","value":"myMacro"},"value":{"name":"value","type":"string","value":"nothing"}},"children":[],"params":[],"orderedAttributes":[{"name":"name","type":"string","value":"myMacro"},{"name":"value","type":"string","value":"nothing"}],"isFunctionDefinition":true,"start":0,"end":35,"rule":"fnprocdef"}]
|
||||
|
||||
);
|
||||
});
|
||||
|
||||
it("should parse function definitions with named end statements followed by spaces", function() {
|
||||
expect(parse("\\function myMacro()\nnothing\n\\end myMacro \n")).toEqual(
|
||||
|
||||
[{"type":"set","attributes":{"name":{"name":"name","type":"string","value":"myMacro"},"value":{"name":"value","type":"string","value":"nothing"}},"children":[],"params":[],"orderedAttributes":[{"name":"name","type":"string","value":"myMacro"},{"name":"value","type":"string","value":"nothing"}],"isFunctionDefinition":true,"start":0,"end":42,"rule":"fnprocdef"}]
|
||||
|
||||
);
|
||||
});
|
||||
|
||||
it("should parse single line function definitions with no parameters", function() {
|
||||
expect(parse("\\function myMacro() nothing\n")).toEqual(
|
||||
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
title: 中文社区 - Chinese Community
|
||||
tags: Community
|
||||
|
||||
# A Chinese community tutorial program that people can edit together:
|
||||
#* Main site: [ext[https://tw-cn.netlify.app/]]
|
||||
#* Accelerated access: [ext[https://tw-cn.cpolar.top/]]
|
||||
#* Alternate: [ext[https://tiddly-wiki-chinese-tutorial.vercel.app]]
|
||||
# Tiddlywiki Chinese Chat Forum: [ext[https://talk.tidgi.fun/topic/6]]
|
||||
# Chinese translation of Tiddlywiki official website [ext[https://bramchen.github.io/tw5-docs/zh-Hans/]]
|
||||
# The best Chinese introductory tutorial for newbies [ext[https://keatonlao.github.io/tiddlywiki-xp/]]
|
||||
|
||||
---
|
||||
|
||||
# 大家可以一起编辑的中文社区教程项目:
|
||||
#* 主站:[ext[https://tw-cn.netlify.app/]]
|
||||
#* 加速访问:[ext[https://tw-cn.cpolar.top/]]
|
||||
#* 备用:[ext[https://tiddly-wiki-chinese-tutorial.vercel.app]]
|
||||
# 太微中文交流论坛:[ext[https://talk.tidgi.fun/topic/6]]
|
||||
# 太微官网汉化版:[ext[https://bramchen.github.io/tw5-docs/zh-Hans/]]
|
||||
# 最适合新手的中文入门教程:[ext[https://keatonlao.github.io/tiddlywiki-xp/]]
|
||||
* 大家可以一起编辑的中文社区教程项目:
|
||||
*# 主站:[ext[https://tw-cn.netlify.app/]]
|
||||
*# 加速访问:[ext[https://tw-cn.cpolar.top/]]
|
||||
*# 备用:[ext[https://tiddly-wiki-chinese-tutorial.vercel.app]]
|
||||
* 太微中文交流论坛:[ext[https://talk.tidgi.fun/topic/6]]
|
||||
* 太微官网汉化版:[ext[https://bramchen.github.io/tw5-docs/zh-Hans/]]
|
||||
* 最适合新手的中文入门教程:[ext[https://keatonlao.github.io/tiddlywiki-xp/]]
|
||||
* TiddlyWiki 爱好者 QQ 群: 946052860
|
||||
*# [ext[点击链接加入群聊【TiddlyWiki爱好者】|https://qm.qq.com/q/13SFxVArlu]]
|
||||
*# [ext[点击链接加入腾讯频道【太微TiddlyWiki】|https://pd.qq.com/s/474hgpll1]]
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
"description": "Documentation from https://tiddlywiki.com",
|
||||
"plugins": [
|
||||
"tiddlywiki/browser-sniff",
|
||||
"tiddlywiki/railroad",
|
||||
"tiddlywiki/internals",
|
||||
"tiddlywiki/menubar",
|
||||
"tiddlywiki/confetti",
|
||||
"tiddlywiki/dynannotate",
|
||||
"tiddlywiki/internals",
|
||||
"tiddlywiki/menubar",
|
||||
"tiddlywiki/railroad",
|
||||
"tiddlywiki/tour"
|
||||
],
|
||||
"themes": [
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
"name": "Confetti",
|
||||
"description": "Animated confetti effect",
|
||||
"list": "readme",
|
||||
"stability": "STABILITY_1_EXPERIMENTAL"
|
||||
"stability": "STABILITY_2_STABLE"
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
"name": "Geospatial Utilities",
|
||||
"description": "Geospatial utilities",
|
||||
"list": "readme docs settings license",
|
||||
"stability": "STABILITY_1_EXPERIMENTAL"
|
||||
"stability": "STABILITY_2_STABLE"
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
"name": "Stacked View",
|
||||
"description": "Stacked card storyview",
|
||||
"list": "readme",
|
||||
"stability": "STABILITY_1_EXPERIMENTAL"
|
||||
"stability": "STABILITY_2_STABLE"
|
||||
}
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
"description": "A tour of TiddlyWiki",
|
||||
"list": "readme docs settings",
|
||||
"dependents": ["$:/plugins/tiddlywiki/confetti","$:/plugins/tiddlywiki/dynannotate"],
|
||||
"stability": "STABILITY_1_EXPERIMENTAL"
|
||||
"stability": "STABILITY_2_STABLE"
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
"name": "TW5.com Docs",
|
||||
"description": "Documentation from tiddlywiki.com",
|
||||
"list": "readme",
|
||||
"stability": "STABILITY_1_EXPERIMENTAL"
|
||||
"stability": "STABILITY_2_STABLE"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user