[pmwiki-devel] Update Re: Using "!#anchor heading" markup
John Rankin
john.rankin at affinity.co.nz
Sun May 31 18:58:21 PDT 2026
On 31/05/2026 8:16 pm, Petko Yotov wrote:
> On 30/05/2026 04:45, John Rankin wrote:
> <snip>
>> 3. !!##anchor heading produces a visible anchor, again for
>> consistency.
>
> The core "!!#anchor..." produces:
> <h2 id="anchor">...</h2>
>
> not:
> <h2><a id="anchor"></a>...</h2>
>
> so in !!#anchor there is no actual anchor tag. I guess you can have a
> markup rule that rewrites !!##anchor into !![[##anchor]] for it to be
> made visible.
The pagetoc recipe has always used !!# and !!## as shorthand for
"generate a unique anchor id and insert an anchor". So, from the point
of view of the recipe:
!!#idName as shorthand for !![[#idName]]
is an equally valid interpretation as:
!!#idName as shorthand for !!%id=idName apply=block%
I think !!#idName and !!##idName should both produce either an id or an
anchor, not one of each.
I modified pagetoc to generate %id=idName apply=block% instead of
[[#idName]] and encountered 2 problems:
- %id=CamelCase apply=block% treats CamelCase as a WikiWord if WikiWords
are enabled
- !!%id=idName apply=block% works as expected, but Q:%id=idName
apply=block% (pmwiki's Q: and A: markup) ignores the id under my (older)
version of pmwiki
At that point I reverted to converting ^(!+|Q:)(##?idName) into
[[##?idName]].
Perhaps !!%idName would be better than !!#idName to designate idName
will produce <h2 id='idName'> ... </h2>?
>
>> 5. Is there a case for making duplicate anchor ids visible as part of
>> the pmwiki core?
>
> Currently, !!#anchor does not check for duplicates, maybe it should,
> but should we also do something about all possible elements with an
> identifier like:
>
> (:input id=something:) planned (:input#something.className:)
> (:div id=something:) planned (:div#something.className:)
> (:details id=something:)
> %list id=something%
My feeling is to do minimum unless there is user demand. So if authors
use anchor markup, they can rely on pmwiki to detect a duplicate anchor
id, but if they use an id=idName attribute, they are on their own. This
leave !!#idName in a grey area. My preferred option would be !!#idName
produces an anchor that pmwiki checks, while !!%idName produces an id
attribute that pmwiki does not check.
>
> What if a writer adds to a page [[#wikitext]] when the skin already
> defines <div id="wikitext">? At some point we might want say PmWiki is
> not an HTML standards validator and leave the responsibility with the
> writers. A recipe may use output buffering and htmltidy to remove
> duplicate ids when this is required.
I think if the skin uses [[#wikitext]], a writer's use of [[#wikitext]]
will be tracked. Yes? If the skin uses id='wikitext', then since (see
above) pmwiki doesn't check id attributes, the duplicate will not be
found. And I think that's OK.
If some future pmwiki release checks all id attributes, then it will
find the duplicate at that time.
>
> If there are duplicate identifiers, which one should win? The
> different markups are processed in order one after another, even if in
> the page !!#anchor is before [[#anchor]], the engine will see the
> latter first.
This problem goes away if !!#idName produces [[#idName]]. And if pmwiki
doesn't check id attributes for duplicates, the problem doesn't go away,
but pmwiki ignores it.
>
> If both are in the page and both are rendered, a link to Page#anchor
> will focus the one that is earlier in the page.
>
> If both are in the page, using (:include Page#anchor:) will include
> from [[#anchor]] not from !!#anchor because of the order of
> $TextSectionAnchorPatterns.
If !!#anchor produces an [[#anchor]] and pmwiki detects and reports
duplicate anchors, this problem goes away, as the writer is given an
opportunity to correct the problem. If the author chooses not to correct
the problem, that's their choice.
>
> I would not render a character for a removed anchor with duplicate
> identifiers, because recipes and pagelists can include parts of
> multiple pages that are wrapped in the same anchors:
>
> (:include {=$FullName}#start#end:)
> (:b3-list:)
>
> If duplicate anchors are replaced with �, these will appear as new
> weird characters in pagelists that worked fine before.
Yes, I agree. The purpose of displaying � for duplicate idNames is to
make it easier for writers to create a correct page table of contents.
So I think pagetoc should limit its error reporting to
^(!!|Q:)(##?idName|[[##?idName]]) instances.
That would significantly reduce (but probably not eliminate) the
instance of anomalies. So if a page contains
[[#idName]] foo
followed by
!![[#idName]]
the second instance will be flagged. If the page contains
!![[#idName]]
followed by
[[#idName]] bar
the second instance will be ignored.
>
>> 6. Should I be separating out visible and duplicate anchor markup
>> processing into its own separate recipe?
>
> If someone needs visible anchors but prefers one of the several other
> table-of-contents recipes, it may be good to split them.
Unless people ask, I'm inclined to leave well alone.
>
>> Should such a recipe be an optional part of the pmwiki core?
>
> If visible anchors are popular, we can consider adding them to the
> core. I know of a single wiki that is using these extensively.
>
> The core already matches [[##anchor]] as well as !!#anchor for
> inclusion of sections in (:include Page#anchor:).
Does the optional table-of-contents recipe that's now part of the core
recognise visible anchors? If so, perhaps this recipe should handle
[[##visible]] markup, rather than rely on a cookbook recipe.
>
>> 4. (:toc anchors=visible:) makes all anchors in the toc headings
>> visible (overriding any !![[#anchor]] markup); a new option (:toc
>> anchors=!visible:) hides all anchors (overriding any !![[##anchor]]
>> markup), except for any duplicate ids; (:toc:) processes anchors as
>> written.
>
> <snip>
Thanks.
JR
More information about the pmwiki-devel
mailing list