[pmwiki-devel] Update Re: Using "!#anchor heading" markup
Petko Yotov
5ko at 5ko.fr
Wed Jun 3 03:41:47 PDT 2026
Thank you JR for your input.
CamelCase words in WikiStyles produced WikiWord links if these were
enabled and broke the WikiStyle. This was an omission or a known
limitation, should be fixed for 2.6.1.
Agreed with your points about a separate anchor tag for !!#anchor rather
than id attribute. An additional reason is for people to be able to
right-click on the visible anchor and select "Copy link", it should link
to itself.
Consequently:
- For rendering wiki pages, !!##?name will be replaced with
!![[##?name]] then left to the 2 other markup rules to handle (anchor,
heading).
- For including text sections like include Page#anchor, the same will be
replaced in the TextSection function before extracting the section.
I added to the core the [[##anchor]] markup to produce a visible anchor:
<a id="anchor" href="#anchor" class="visible-anchor">#anchor</a>
You can override this either by inserting a markup rule before '[[#'
that consumes the visible anchor markups, or by redefining '[[#'.
New variable $VisibleAnchorPrefix default '#'. This seems more intuitive
than '§' since the link is also #anchor, but can be redefined in
config.php if needed.
New class name 'visible-anchor' for these, with some styles:
font-size: .8rem;
opacity: .67;
People can override or complement the styles and the prefix character in
local configuration.
Visible anchors are detected in the core table of contents and used in
the toc links, but are not visible in the toc links. That means if a
heading is written as:
!!##anchor Heading
- the heading text will contain "#anchor Heading"
- the table of contents will link to Page#anchor, but the link text will
contain "Heading".
Duplicate anchors are removed rather than appearing with a different
prefix character. The earliest instance among [[#anchor]], [[##anchor]],
!!#anchor, !!##anchor, is rendered, the others are removed.
If a writer expects a visible anchor that does not show, this ought to
be a sufficient indication that the anchor was removed. :-)
Petko
On 01/06/2026 03:58, John Rankin wrote:
> 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>?
>
>> Currently, !!#anchor does not check for duplicates, maybe it should,
>> but should we also do something about all possible elements with an
>> identifier like:
>> ...
> 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