feat: parse and show ^id

This commit is contained in:
linonetwo 2023-09-15 22:17:19 +08:00
parent 49c96901f3
commit 5b6f5b2704
2 changed files with 91 additions and 0 deletions

View File

@ -0,0 +1,39 @@
/*\
title: $:/core/modules/parsers/wikiparser/rules/blockidentifier.js
type: application/javascript
module-type: wikirule
Use hash as a tag for paragraph, we call it block identifier.
1. Hash won't change, it can be written by hand or be generated, and it is a ` \^\S+$` string after line: `text ^cb9d485` or `text ^1`, so it can be human readable (while without space), here are the parse rule for this.
2. When creating widgets for rendering, omit this hash, so it's invisible in view mode. But this widget will create an anchor to jump to.
\*/
exports.name = "blockidentifier";
exports.types = {inline: true};
/*
Instantiate parse rule
*/
exports.init = function(parser) {
this.parser = parser;
// Regexp to match the block identifier located on the end of the line.
this.matchRegExp = /[ ]\^\S+$/mg;
};
/*
Parse the most recent match
*/
exports.parse = function() {
// Move past the match
this.parser.pos = this.matchRegExp.lastIndex;
var id = this.match[0].slice(2);
// Parse tree nodes to return
return [{
type: "blockidentifier",
attributes: {
id: {type: "string", value: id}
},
children: []
}];
};

View File

@ -0,0 +1,52 @@
/*\
title: $:/core/modules/widgets/blockidentifier.js
type: application/javascript
module-type: widget
An invisible element with block id metadata.
\*/
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var BlockIdentifierWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
BlockIdentifierWidget.prototype = new Widget();
BlockIdentifierWidget.prototype.render = function(parent,nextSibling) {
// Save the parent dom node
this.parentDomNode = parent;
// Compute our attributes
this.computeAttributes();
// Execute our logic
this.execute();
// Create an invisible DOM element with data that can be accessed from JS or CSS
this.spanDomNode = this.document.createElement("span");
this.spanDomNode.setAttribute("data-id",this.id);
this.spanDomNode.className = "tc-block-id";
parent.insertBefore(this.spanDomNode,nextSibling);
this.domNodes.push(this.spanDomNode);
};
/*
Compute the internal state of the widget
*/
BlockIdentifierWidget.prototype.execute = function() {
// Get the id from the parse tree node or manually assigned attributes
this.id = this.getAttribute("id");
// Make the child widgets
this.makeChildWidgets();
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
BlockIdentifierWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(($tw.utils.count(changedAttributes) > 0)) {
this.refreshSelf();
return true;
} else {
return this.refreshChildren(changedTiddlers);
}
};
exports.blockidentifier = BlockIdentifierWidget;