* Fix regex for code block end detection in wikiparser
* Anchor the codeblock end fence to its own line
Close an empty code block without consuming the tiddler, while a fence
only counts when it stands alone on its line.
* Match the end fence with (^|\r?\n) so the empty block case closes at
the line start and a code line ending in ``` stays inside the block
* Add test-codeblock-parser.js covering empty blocks with language and
CRLF, delimiter newline handling, mid-line fences and a missing fence
* Move background action log inside platforms check
* Add change note for #9891
* Shorten change note
* Release notes: move #9891 from 5.4.1 to 5.5.0
PR #9891 is still open, so the background-action log change is planned for 5.5.0 instead of 5.4.1.
* Fix change-category for #9891 release note
is not a valid category; use instead.
* Update docs: running a custom Node.js TiddlyWiki version with npx
* Update docs: document different options of running multiple TW versions
---------
Co-authored-by: shadow <shadow@darkstar.localdomain>
Co-authored-by: me <me@localhost>
* Fix the CSV parser blanking a table
getCellInfo read the loop variable i before its declaration, so hoisting made
it undefined and charAt(undefined) read the first character of the whole text.
Any CSV opening with a separator therefore returned every cell empty.
- Test the cell against the start of the cell rather than the hoisted i
- Keep a separator inside a quoted cell literal
- Cover the parser with tests
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Add a change note for the CSV fix
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Skip system tiddlers in back-indexer updates
Fix#9916: editing a system tiddler that links or transcludes another
tiddler made it a backlinks[]/backtranscludes[] source until the next
index rebuild (shipped since v5.3.4).
* Guard BackSubIndexer.update() with isSystemTiddler() on both sides,
matching the initial scan; this also skips parsing $:/StoryList on
every navigation
* Add test-back-indexer.js: regression guards plus adversarial probes
for shadow reveals and hostile __proto__ titles
* Add ChangeNote
* Fakedom: uppercase tagName for HTML elements per DOM spec
Browsers uppercase tagName for HTML elements. Other namespaces (SVG,
MathML, XML) preserve case. Fakedom now matches, so widget code can use
the natural `node.tagName === "OPTGROUP"` form in both environments.
https://dom.spec.whatwg.org/#dom-element-tagname
* Tests: cover fakedom tagName spec compliance
Three specs pin the DOM contract for tagName: uppercase for HTML
elements, case preservation for other namespaces, and non-mutating
reads. Includes the OPTGROUP predicate the select widget will rely on
once it can drop its defensive .toUpperCase() call.
https://dom.spec.whatwg.org/#dom-element-tagname
* Fakedom: empty or null namespace creates a no-namespace element
Per DOM spec, createElementNS("") and createElementNS(null) have to produce
elements with no namespace. Fakedom previously defaults both to HTML,
which made tagName incorrectly uppercase non-HTML elements.
createElement without arguments still defaults to HTML.
https://dom.spec.whatwg.org/#dom-document-createelementns
* Add ChangeNote
* Fix Node.js deprecated warning
* Add ChangeNote
* Change deprecation to bugfix for DEP0169 warning
Updated change type from 'deprecation' to 'bugfix' for the Node.js server's handling of the DEP0169 warning.
01d3cde96 refactored parseMacroParameterAsAttribute to use a
do/while(false) construct with break statements - this updates
parseAttribute with an analogous refactoring for consistency
* Fix invalid source positions in parse tree nodes
Several wikitext rules recorded start and end offsets that did not match
the source they represent. The offsets are only used for source position
mapping, not rendering or serialization, so output is unchanged and
source.slice(start, end) now equals the node text.
* import: the filter attribute start was set to the whole source string
instead of the numeric offset. It used this.parser.source where it
meant this.parser.pos, so every \import node carried a copy of the
entire source as its start.
* codeinline: the text node end pointed past the closing backtick, so the
span included the closing delimiter and could read one or two characters
too far. It now ends where the content ends.
* wikilinkprefix and extlink: a suppressed link such as ~SomeLink or
~http://example.com produced a text node whose span included the
leading ~ while its text did not. The span now starts after the ~.
* Add 5.4.1 change note for #9882
Document the parse tree source position fixes: inline code, suppressed
external links, suppressed wikilinks, and the import filter rule.
* Add tests for parse tree source positions
Cover the four wikitext parser rules whose `start` and `end` offsets are
corrected in this PR: codeinline, extlink, wikilinkprefix, and import.
* Update aho-corasick.js
Optimized Aho-Corasick string matching algorithm implementation with enhanced
performance and error handling for TiddlyWiki freelinking functionality.
- Uses WeakMap for failure links. WeakMap keys are compared by object identity
(reference equality), which is required here because trie nodes are plain
objects — a regular {} map would not work because JavaScript only supports
string and Symbol keys, forcing object keys to be coerced to strings.
- Outputs are merged at build time (classic AC optimization), eliminating the
need to walk the failure chain during search.
- search() converts case per character to avoid Unicode index desync (e.g.
Turkish İ expands under toLowerCase(), shifting subsequent indices).
- No match count cap in search(); truncation is handled at the render stage
by processTextWithMatches() to avoid silently dropping matches mid-text.
- Optional word boundary filtering: CJK always allowed; Latin requires
non-word characters on both sides.
* Update text.js
- Render output capped by $:/config/Freelinks/MaxLinks (default 500).
The cap applies to the final set of non-overlapping rendered links, not to
the raw search results: search always runs to completion so that the
longest-match selection has full information. Text beyond the cap remains
as plain text rather than being silently omitted.
* Create config-Freelinks-MAX_LINKS_TIDDLER.tid
setting for MAX_LINKS_TIDDLER
* Update and rename config-Freelinks-MAX_LINKS_TIDDLER.tid to config-Freelinks-MaxLinks.tid
fix typo
* Update settings.tid
add MaxLinks setting
* Update readme.tid
add MaxLinks setting text
* Create #9836.tid
release note
* Update tiddlywiki.info
add freelinks for test build
* Update macros-view.tid
fix structure problem
* Update text.js
add IGNORE_CASE_TIDDLER to whitelist
* Rename #9836.tid to #9836.tid
move to 5.4.1
* Update text.js
I deleted the wrong line last time, so I'm putting it back.
* Update text.js
eslint fix
* Update text.js
refactor: inline plain-text via dynamic core reference
* Delete plugins/tiddlywiki/freelinks/plain-text.js
remove plain-text.js: now inlined via dynamic core reference
* Update text.js
restore plain-text.js, remove new Function extraction
* Add files via upload
restore plain-text.js, remove new Function extraction
* Update #9836.tid
update new bug
* Update #9836.tid
tw version fix
* Update tiddlywiki.info
reverse to original