1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-06-30 00:58:51 +00:00
Files
s793016 e730836d6f Freelinks Plugin: Add configurable MaxLinks cap and remove search truncation (#9836)
* 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
2026-06-20 19:25:19 +01:00
..
2020-01-04 16:33:52 +00:00

title: $:/plugins/tiddlywiki/freelinks/readme

This plugin adds automatic generation of links to tiddler titles.

The plugin uses the Aho-Corasick algorithm for efficient pattern matching with large numbers of tiddlers.

!! Configuration

Freelinking is activated for runs of text that have the following variables set:

* `tv-wikilinks` is NOT equal to `no`
* `tv-freelinks` is set to `yes`

Freelinks are case sensitive by default but can be configured to ignore case in the settings panel.

Word boundary checking can be configured in the settings panel. When enabled (default for Western languages), links are created only for complete words. When disabled, partial matches within words are also linked.

When multiple tiddler titles match the same text, longer titles take precedence over shorter ones.

Tiddlers do not create links to themselves.

Use `$:/config/Freelinks/TargetFilter` to define which tiddlers are eligible for auto-linking.

Within view templates, the variable `tv-freelinks` is automatically set to the content of `$:/config/Freelinks/Enable`, which can be set via the settings panel of this plugin.

Use `$:/config/Freelinks/MaxLinks` to set the maximum number of links rendered per text node (default: 500). 

Since TiddlyWiki splits tiddler content into multiple text nodes, the effective limit per tiddler is higher than this value. Text beyond the limit remains as plain text rather than being silently dropped. This cap protects against DOM overload when a large number of tiddler titles match the text, for example in dictionary-scale wikis. Raising this value significantly increases render time.

!! Notes

To change within which tiddlers freelinking occurs requires customising the shadow tiddler [[$:/plugins/tiddlywiki/freelinks/macros/view]]. This tiddler is tagged `$:/tags/Macro/View` which means that it will be included as a local macro in each view template. By default, its content is:

```
<$set name="tv-freelinks" value={{$:/config/Freelinks/Enable}}/>
```

That means that for each tiddler the variable `tv-freelinks` will be set to the tiddler `$:/config/Freelinks/Enable`, which is set to "yes" or "no" by the settings in control panel.

Instead, we can use a filter expression to, say, only freelink within the tiddler with the title "HelloThere":

```
<$set name="tv-freelinks" value={{{ [<currentTiddler>match[HelloThere]then[yes]else[no]] }}}/>
```

Or, we can make a filter that will only freelink within tiddlers with the tag "MyTag":

```
<$set name="tv-freelinks" value={{{ [<currentTiddler>tag[MyTags]then[yes]else[no]] }}}/>
```

Or we can combine both approaches:

```
<$set name="tv-freelinks" value={{{ [<currentTiddler>match[HelloThere]] ~[<currentTiddler>tag[MyTag]] +[then[yes]else[no]] }}}/>
```

!! Implementation Details

The Aho-Corasick algorithm implementation includes:

* Unicode character support for international text
* Prevention of self-referential links within the current tiddler
* Uses a `WeakMap` for failure links, required for correct object-keyed traversal
* Merges pattern outputs at build time for efficient single-pass search
* Converts case per character during search to avoid Unicode index desync (e.g. Turkish İ, German ß)
* Runs search to completion without truncation; the `MaxLinks` cap is applied at render time so that the longest-match selection always has full information and text beyond the cap is preserved as plain text rather than silently dropped
* Graceful fallback handling for invalid patterns
* Skips draft tiddlers and system tiddlers (`$:/`) during cache invalidation to avoid unnecessary rebuilds on UI interactions