Details

Applies to

MoinMoin macro (TableOfContents.py) v1.8.2 and v1.9.3 (2 patches submitted)

Purpose

To make TableOfContents numbering hierarchical

Description

This patch enables TableOfContents to produce hierarchical headers numbering. Example below

Old style:

1. Header 1
    1. Sub Header 1
    2. Sub Header 2
        1. Sub Sub Header 1
        1. Sub Sub Header 2
2. Header 2

New style:

1. Header 1
    1.1. Sub Header 1
    1.2. Sub Header 2
        1.2.1. Sub Sub Header 1
        1.2.2. Sub Sub Header 2
2. Header 2

Patch

   1 --- TableOfContents.old.py	2009-02-08 01:27:07.000000000 +0100
   2 +++ TableOfContents.py	2009-03-27 02:28:16.000000000 +0100
   3 @@ -149,11 +149,6 @@
   4  
   5      tocfm = TOCFormatter(macro.request)
   6      p = Page(macro.request, pname, formatter=tocfm, rev=macro.request.rev)
   7 -
   8 -    # this is so we get a correctly updated TOC if we just preview in the editor -
   9 -    # the new content is not stored on disk yet, but available as macro.parser.raw:
  10 -    p.set_raw_body(macro.parser.raw, modified=1)
  11 -
  12      output = macro.request.redirectedOutput(p.send_page,
  13                                              content_only=True,
  14                                              count_hit=False,
  15 @@ -162,66 +157,88 @@
  16      _ = macro.request.getText
  17  
  18      result = [
  19 -        macro.formatter.div(1, css_class="table-of-contents"),
  20 +        macro.formatter.div(1, css_class="table-of-contents", id="toc"),
  21          macro.formatter.paragraph(1, css_class="table-of-contents-heading"),
  22          macro.formatter.text(_('Contents')),
  23          macro.formatter.paragraph(0),
  24      ]
  25  
  26 +    lastlvl = 0
  27 +
  28 +    # variables needed to provide with nice, leveled prefixes
  29 +    levelnumbers = None
  30 +    levelnumbers = {}
  31 +    counter = 1
  32 +    lowest_lvl = None
  33  
  34 -    # find smallest used level and use that as the outer-most indentation,
  35 -    # to fix pages like HelpOnMacros that only use h2 and lower levels.
  36 -    lastlvl = 100
  37      for lvl, id, txt in macro.request._tocfm_collected_headings:
  38 +
  39          if txt is None:
  40              incl_id = id
  41              continue
  42          if lvl > maxdepth or id is None:
  43              continue
  44 -        if lvl < lastlvl:
  45 -            lastlvl = lvl
  46  
  47 -    # headings are 1-based, lastlvl needs to be one less so that one is closed
  48 -    lastlvl -= 1
  49 +        # determine the lowest level available
  50 +        if lowest_lvl is None or lowest_lvl > lvl:
  51 +                lowest_lvl = lvl
  52 +
  53 +        # determine number prefix for the TOC line
  54 +        if lvl > lastlvl:
  55 +                levelnumbers[lastlvl] = counter
  56 +                counter = 0
  57 +        elif lvl < lastlvl:
  58 +                counter = levelnumbers[lvl]
  59 +
  60 +        counter = counter + 1
  61 +        levelnumbers[lvl] = counter
  62 +
  63 +        line_number = ""
  64 +        for i in range(lowest_lvl, lvl):
  65 +                line_number = line_number + str(levelnumbers[i]) + "."
  66 +        line_number = line_number + str(counter) + "."
  67  
  68 -    for lvl, id, txt in macro.request._tocfm_collected_headings:
  69 -        if txt is None:
  70 -            incl_id = id
  71 -            continue
  72 -        if lvl > maxdepth or id is None:
  73 -            continue
  74  
  75          # will be reset by pop_unique_ids below
  76          macro.request.include_id = incl_id
  77  
  78          need_li = lastlvl >= lvl
  79 -        while lastlvl > lvl:
  80 -            result.extend([
  81 -                macro.formatter.listitem(0),
  82 -                macro.formatter.number_list(0),
  83 -            ])
  84 -            lastlvl -= 1
  85 +
  86 +
  87 +        # adjust lastlvl so that we can start lists from the lowest_lvl
  88 +        if lastlvl < lvl and lastlvl < lowest_lvl: lastlvl = lvl - 1
  89 +        if lastlvl > lvl and lastlvl < lowest_lvl: lastlvl = lvl + 1
  90 +
  91 +
  92 +        # open and close corresponding lists
  93          while lastlvl < lvl:
  94              result.extend([
  95 -                macro.formatter.number_list(1),
  96 +                macro.formatter.bullet_list(1, type="none"),
  97                  macro.formatter.listitem(1),
  98              ])
  99              lastlvl += 1
 100 +        while lastlvl > lvl:
 101 +            result.extend([
 102 +                macro.formatter.listitem(0),
 103 +                macro.formatter.bullet_list(0),
 104 +            ])
 105 +            lastlvl -= 1
 106          if need_li:
 107              result.extend([
 108                  macro.formatter.listitem(0),
 109                  macro.formatter.listitem(1),
 110              ])
 111 +
 112          result.extend([
 113              '\n',
 114              macro.formatter.anchorlink(1, id),
 115 -            macro.formatter.text(txt),
 116 +            macro.formatter.text(line_number + " " + txt),
 117              macro.formatter.anchorlink(0),
 118          ])
 119  
 120 -    while lastlvl > 0:
 121 +    while lastlvl > lvl:
 122          result.append(macro.formatter.listitem(0))
 123 -        result.append(macro.formatter.number_list(0))
 124 +        result.append(macro.formatter.bullet_list(0))
 125          lastlvl -= 1
 126  
 127      macro.request.pop_unique_ids()
TableOfContents-1.8.py.patch
   1 --- TableOfContents.py.dist	2010-06-26 23:46:42.000000000 +0200
   2 +++ TableOfContents.py	2010-09-01 18:57:24.000000000 +0200
   3 @@ -167,7 +167,7 @@
   4      _ = macro.request.getText
   5  
   6      result = [
   7 -        macro.formatter.div(1, css_class="table-of-contents"),
   8 +        macro.formatter.div(1, css_class="table-of-contents", id="toc"),
   9          macro.formatter.paragraph(1, css_class="table-of-contents-heading"),
  10          macro.formatter.text(_('Contents')),
  11          macro.formatter.paragraph(0),
  12 @@ -181,21 +181,48 @@
  13          if txt is None:
  14              incl_id = id
  15              continue
  16 -        if lvl < mindepth or lvl > maxdepth or id is None:
  17 +        if lvl > maxdepth or id is None:
  18              continue
  19          if lvl < lastlvl:
  20              lastlvl = lvl
  21  
  22      # headings are 1-based, lastlvl needs to be one less so that one is closed
  23 +    # variables needed to provide with nice, leveled prefixes
  24 +    # (part of the hierarhical TOC prefix code) 
  25 +    levelnumbers = None
  26 +    levelnumbers = {}
  27 +    counter = 1
  28 +    lowest_lvl = None
  29      lastlvl -= 1
  30  
  31      for lvl, id, txt in macro.request._tocfm_collected_headings:
  32          if txt is None:
  33              incl_id = id
  34              continue
  35 -        if lvl < mindepth or lvl > maxdepth or id is None:
  36 +        if lvl > maxdepth or id is None:
  37              continue
  38  
  39 +
  40 +        # determine the lowest level available 
  41 +        # (part of the hierarhical TOC prefix)
  42 +        if lowest_lvl is None or lowest_lvl > lvl:
  43 +                lowest_lvl = lvl
  44 +
  45 +        # determine number prefix for the TOC line 
  46 +        # (part of the hierarhical TOC prefix) 
  47 +        if lvl > lastlvl:
  48 +                levelnumbers[lastlvl] = counter
  49 +                counter = 0
  50 +        elif lvl < lastlvl:
  51 +                counter = levelnumbers[lvl]
  52 +        counter = counter + 1
  53 +        levelnumbers[lvl] = counter
  54 +   
  55 +        line_number = ""
  56 +        for i in range(lowest_lvl, lvl):
  57 +                line_number = line_number + str(levelnumbers[i]) + "."
  58 +        line_number = line_number + str(counter) + "."
  59 +
  60          # will be reset by pop_unique_ids below
  61          macro.request.uid_generator.include_id = incl_id
  62  
  63 @@ -203,12 +230,12 @@
  64          while lastlvl > lvl:
  65              result.extend([
  66                  macro.formatter.listitem(0),
  67 -                macro.formatter.number_list(0),
  68 +                macro.formatter.bullet_list(0),
  69              ])
  70              lastlvl -= 1
  71          while lastlvl < lvl:
  72              result.extend([
  73 -                macro.formatter.number_list(1),
  74 +                macro.formatter.bullet_list(1, type="none"),
  75                  macro.formatter.listitem(1),
  76              ])
  77              lastlvl += 1
  78 @@ -220,13 +247,13 @@
  79          result.extend([
  80              '\n',
  81              macro.formatter.anchorlink(1, id),
  82 -            macro.formatter.text(txt),
  83 +            macro.formatter.text(line_number + " " + txt),
  84              macro.formatter.anchorlink(0),
  85          ])
  86  
  87      while lastlvl > 0:
  88          result.append(macro.formatter.listitem(0))
  89 -        result.append(macro.formatter.number_list(0))
  90 +        result.append(macro.formatter.bullet_list(0))
  91          lastlvl -= 1
  92  
  93      macro.request.uid_generator.pop()
TableOfContents-1.9.3.py.patch

Complete macro

Both macros are attached below:

Discussion

Plan


CategoryMoinMoinPatch

MoinMoin: MoinMoinPatch/TableOfContentsHierarchicNumbers (last edited 2010-09-01 17:05:07 by StellarsHenson)