Feature Proposal: Add a way to shift heading levels

a headershift parameter to adjust included header levels


The header levels almost never fit if I try to include topics which weren't designed to be included originally. It would be nice if VarINCLUDE would support a headershift parameter to shift the level of included headers up or down.

See also pdfheadershift of GenPDFAddOn.

Description and Documentation

Extend VarINCLUDE with a headershift parameter. The numeric argument indicates by how many levels the headers will be shifted (up for positive and down for negative values). E.g. h1 would become h3 for a value of 3.


%INCLUDE{"TestTopic" headershift="3"}%




-- Contributors: MartinKaufmann - 27 Nov 2009


Trademark Wiki definitely will have "Relative Heading Levels for INCLUDE" in its next release, implemented by a headingoffset parameter.

-- FranzJosefGigler - 14 Dec 2010

Note that experience with GenPDFAddOn suggests that a simple shift is too simple in many cases. See Tasks.Item9251 and Support/Question559. Note that for Foswiki topics, these considerations may not apply, but there are implications on correct PDF Table of Contents generation. it would be nice if the ability to shift headers was general enough to also work with PDF generation.

-- GeorgeClark - 14 Dec 2010

call me simplistic, but why would we not want to make it headershift="adaptive", where it automatically fit into the doc its included into..

-- SvenDowideit - 15 Dec 2010

Sorry for nit-pick, but headershift="auto" might be more appropriate... but I can't help that think, without a proper DOM, it's going to be buggy/difficult...

-- PaulHarvey - 02 Dec 2011

na, without DOM/TOM you just wait til the html is completely rendered, and then split(/(<\\?h\d>)/, $entirehtml) and get nifty with the countering. ugly, but very effective.

-- SvenDowideit - 02 Dec 2011

Just thinking.

---+ Heading1

%INCLUDE{"%TOPIC%" section="foo" headingshift="auto"}%

%STARTSECTION{"foo"}%---++ Heading2

  format="---+++ Heading 3

$percntINCLUDE{\"$web.$topic\" headingshift=\"auto\"}$percnt"

-- PaulHarvey - 02 Dec 2011

I would keep it simple.

Just implement the offset and let the user find out if he needs to increment or decrement by 1 or 2. That is what they in practical life.

-- KennethLavrsen - 02 Dec 2011

I agree that this is tricky. One way to implement it post-rendering would be to use a pseudo-tag - this would be more generally useful than a macro param (it could also be used by plugins, for e.g.). For example:

---+ An H1
<baseh 2>
---+ An H2

This would pass through rendering cleanly, and can be cleanly applied just before calling the post-rendering handlers. The effect would be to increment all <h tags inside the pseudo-tag.

-- CrawfordCurrie - 17 Feb 2012

I'm too comfortable with "special tags" like <baseh> ... Can't point to any particular reason why though.

We do have to take into consideration that (tm)wiki has implemented header shifting. Unless there is something really wrong with their implementation, I believe it would be better for the user base to try to stay compatible. Hopefully we are still attracting an occasional conversion over to Foswiki.

-- GeorgeClark - 17 Feb 2012

It's a question of separation of concerns. A %INCLUDE is a macro expansion; it has nothing to do with rendering. Conflating header adjustment with a macro expansion is confusing the two concerns in a way that is just storing up trouble for the future. I haven't looked at their code but I will bet you ten pints of yak milk that (tm)wiki gets it wrong if any of those headings are generated as the result of a macro expansion. I'll also take a wild guess that any literal <h tags don't get adjusted, and that it f***s up verbatim content too. It's an almost inevitable result of narrow focus on just the INCLUDE macro.

Having said that, it would be sensible to support whatever parameter they added to INCLUDE. A quick look at their docs shows:

Adjust the level of headings in the included topic. A "2" or "+2" increases the level by two, e.g. a ---+ H1 turns into a ---+++ H3. Positive and negative values are supported. Adjusted min and max levels are H1 and H6, respectively.
no adjustment
IMHO the cleanest way to implement this is to wrap a <hoffset> around the included content. Job done.

I'm in itch-scratching mode this morning, so I might take a crack at implementing this.

Later: patch attached implements <hoff2> to increment heading levels and </hoff1> to decrment them, as well as a (tm)wiki-compatible parameter on INCLUDE.

this would be good to have in 1.2

BTW this is the way %TOC should be done as well. The macro approach has the same sorts of difficulties.

-- CrawfordCurrie - 18 Feb 2012

Updated the core patch.

-- CrawfordCurrie - 20 Feb 2012

From a XML point of view <hoffN> is a serious problem. This isn't coverable by any dtd or schema. Not that we are about to write one.

In general arguments to an XML tag belong into argument position and should not be encoded as part of the tag name.

So instead of writing

it should be at something like
<hoff value="911">

Also, duplicating the offset in the closing tag might be nice for implementation reasons, but not from the pov of an XML design, nor from an author's perspective. When he decides to shift headings a bit more, it has to be changed in two places instead of just one. This holds even more when you'd like to compute the offset by some TML:
<hoff value="%CALC{...}%"

You don't want to be computing the same TML expression twice just for the fact that the numbers are duplicated in the closing tag.

-- MichaelDaum - 21 Feb 2012

I considered this problem, but considered that <hoff is working on <h tags, and should be consistent. While balancing the <hoff tags is a good idea from an XML perspective, it would enormously complicate the implementation, and is probably moot anyway as hoff never makes it beyond the renderer.

-- CrawfordCurrie - 21 Feb 2012

As I understand it, you need <hoff tags as hints, but the closing tag would complicate the implementation.

Why not <hoff diff="+1" />

That way it's XML balanced as well

-- JulianLevens - 21 Feb 2012

"enormously complicate the implementation" ... why's that? You only need a list to remember the recent value the headings got pushed. Coming accross a closing hoff pops the top value from the list and uses that.

-- MichaelDaum - 21 Feb 2012

OK, so maybe "enormously complicates" is a bit OTT, but Julian is right. Perhaps I just like the fact that the current implementation is extremely tolerant of unbalanced/unclosed/unXML usage of hoff, and processing doesn't require any cleverness; it can be done using a simple split.

To avoid the balancing act, I would be OK with making the hoff tag a self-closer, like img. Thus:

---+ H1
<h off="1" />
---+ H2
<h off="-1" />
---+ H1

-- CrawfordCurrie - 21 Feb 2012

Note that the (tm)wiki implementation also does header shifting of search results. So if we are looking to maintain some level of compatibility for upgraders, search needs to be reviewed as well

See: Item6560 and RelativeHeadingLevelsforSEARCH for their implementation.

-- GeorgeClark - 21 Feb 2012

Trivial to implement with <h off. However 100% compatibility cannot be achieved that way; their implementation is just not smart enough, we would have to brain-damage ours.

-- CrawfordCurrie - 21 Feb 2012

Want to change the spec to use ho rather than h. h may conflict with other tags; ho is less likely to, and is no less revealing.

-- CrawfordCurrie - 04 Mar 2012

I ask for a spec change too :/

can you change it so that it becomes a html comment? ie

<!-- renderhint h_offset="-2" -->

That way we can even leave them in the final output for debugging, and set ourselves up doe having a generalised renderhint system that we could leverage... (and can even combine multiple hints..)

-- SvenDowideit - 04 Mar 2012

<!-- danger danger. Nested comments are not supported in HTML or XML. So the first --> closes the comments. Accidentally nesting comments can cause all sorts of uglyness. So please avoid that syntax!

-- GeorgeClark - 05 Mar 2012

mmm, george - would we not be better off accepting that the <!-- tags are dangerous, and so need to write something to de-nest them?

-- SvenDowideit - 05 Mar 2012

/me was going to make the same comment as George, but instead waits for the dust to settle.

-- CrawfordCurrie - 05 Mar 2012

This is marked merged to core which I assume means the functionality is available, but the documentation in Foswiki-1.1.9, Plugin API version 2.2 doesn't mention any shifting param in the INCLUDE docs. Include doc version: Topic revision: r1 - 20 Sep 2010, ProjectContributor.

This functionality (even if not perfect) is really really really useful when creating runbooks and other documentation from pages that were originally meant to be standalone. Also the ability to elide %TOC% using hidetoc is a nice feature (although it can be simulated using named sections/section includes).

Do I need to be running a beta release or something to get this?

-- JohnRouillard - 30 Jun 2015

It's a Foswiki 1.2 feature, available in betas and the soon-to-be-born release candidate.

-- Main.CrawfordCurrie - 30 Jun 2015 - 14:20
Topic revision: r32 - 05 Jul 2015, GeorgeClark - This page was cached on 31 May 2016 - 04:07.

The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License