diff --git a/data/filters/wg21.py b/data/filters/wg21.py
index c10c6b5..5b2b66a 100755
--- a/data/filters/wg21.py
+++ b/data/filters/wg21.py
@@ -15,6 +15,11 @@
embedded_md = re.compile('@@(.*?)@@|@(.*?)@')
stable_names = {}
+current_pnum = {}
+current_note = 0
+current_example = 0
+current_pnum_count = 0
+
refs = {}
def wrap_elem(opening, elem, closing):
@@ -39,12 +44,12 @@ def prepare(doc):
doc.metadata['pagetitle'] = pf.convert_text(
pf.Plain(*doc.metadata['title'].content),
input_format='panflute',
- output_format='markdown')
+ output_format='plain')
datadir = doc.get_metadata('datadir')
with open(os.path.join(datadir, 'annex-f'), 'r') as f:
- stable_names.update(line.split(maxsplit=1) for line in f)
+ stable_names.update(line.rstrip().split(maxsplit=1) for line in f)
def highlighting(output_format):
return pf.convert_text(
@@ -295,11 +300,11 @@ def _color(html_color):
pf.RawInline('}', 'latex'))
elem.attributes['style'] = f'color: #{html_color}'
- def _nonnormative(name):
+ def _nonnormative(name, number='?'):
wrap_elem(
- pf.Span(pf.Str('[ '), pf.Emph(pf.Str(f'{name.title()}:')), pf.Space),
+ pf.Span(pf.Str('[\xa0'), pf.Emph(pf.Str(f'{name.title()} {number}:')), pf.Space),
elem,
- pf.Span(pf.Str(' — '), pf.Emph(pf.Str(f'end {name.lower()}')), pf.Str(' ]')))
+ pf.Span(pf.Str(' —\xa0'), pf.Emph(pf.Str(f'end {name.lower()}')), pf.Str('\xa0]')))
def _diff(color, latex_tag, html_tag):
if isinstance(elem, pf.Span):
@@ -320,22 +325,69 @@ def protect_code(elem, doc):
_color(doc.get_metadata(color))
def pnum():
+ global current_pnum
num = pf.stringify(elem)
+ depth = num.count('.')
+ parts = num.split('.')
+
+ def reset_below(i):
+ to_delete = [k for k in current_pnum if k > i]
+ for k in to_delete:
+ del current_pnum[k]
+
+ # If we see a level N, always reset levels below it.
+ reset_below(depth)
+
+ for i in range(len(parts)):
+ # placeholder pnum parts are expressed by #
+ if parts[i] == '#':
+ # replace placeholder by:
+ # - last used value if this is not the last part
+ # - last used value + 1 otherwise
+ if i == depth:
+ pt = current_pnum.get(i, 0) + 1
+ parts[i] = str(pt)
+ current_pnum[i] = pt
+ else:
+ pt = current_pnum.get(i)
+ if pt is None:
+ pf.debug('Missing current value for non-lowest-level placeholder in {}'.format(num))
+ pt = 1
+ current_pnum[i] = pt
+ reset_below(i)
+ parts[i] = str(pt)
+ else:
+ try:
+ val = int(parts[i])
+ if i not in current_pnum or current_pnum[i] != val:
+ current_pnum[i] = val
+ # When we see a new value at a level,
+ # reset everything below that level.
+ reset_below(i)
+ except ValueError:
+ pass
+
+ num = '.'.join(parts)
+
if '.' in num:
num = f'({num})'
+ global current_pnum_count
+ current_pnum_count = current_pnum_count + 1
+
if doc.format == 'latex':
return pf.RawInline(f'\\pnum{{{num}}}', 'latex')
elif doc.format == 'html':
return pf.Span(
- pf.RawInline(f'{num}', 'html'),
+ pf.RawInline(f'{num}', 'html'),
classes=['marginalizedparent'])
return pf.Superscript(pf.Str(num))
- def example(): _nonnormative('example')
- def note(): _nonnormative('note')
+ def example(number='?'): _nonnormative('example', number)
+ def note(number='?'): _nonnormative('note', number)
def ednote():
wrap_elem(pf.Str("[ Editor's note: "), elem, pf.Str(' ]'))
_color('0000ff')
@@ -348,6 +400,13 @@ def draftnote():
def add(): _diff('addcolor', 'uline', 'ins')
def rm(): _diff('rmcolor', 'sout', 'del')
+ if isinstance(elem, pf.Header):
+ # When entering a new section, reset all auto numbering.
+ global current_pnum, current_example, current_note
+ current_pnum = {}
+ current_example = 0
+ current_note = 0
+
if not any(isinstance(elem, cls) for cls in [pf.Div, pf.Span]):
return None
@@ -366,11 +425,39 @@ def rm(): _diff('rmcolor', 'sout', 'del')
pf.debug('mpark/wg21: stable name', target, 'not found')
return link
- note_cls = next(iter(cls for cls in elem.classes if cls in {'example', 'note', 'ednote', 'draftnote'}), None)
- if note_cls == 'example': example()
- elif note_cls == 'note': note()
- elif note_cls == 'ednote': ednote(); return
- elif note_cls == 'draftnote': draftnote(); return
+ for cls in elem.classes:
+ if cls.startswith('note'):
+ num = cls[4:]
+ if num == '-':
+ num = '?'
+ elif num:
+ try:
+ current_note = int(num)
+ except ValueError:
+ pass
+ else:
+ current_note = current_note + 1
+ num = str(current_note)
+ note(num)
+ elif cls.startswith('example'):
+ num = cls[7:]
+ if num == '-':
+ num = '?'
+ elif num:
+ try:
+ current_example = int(num)
+ except ValueError:
+ pass
+ else:
+ current_example = current_example + 1
+ num = str(current_example)
+ example(num)
+ elif cls == 'ednote':
+ ednote()
+ return
+ elif cls == 'draftnote':
+ draftnote()
+ return
diff_cls = next(iter(cls for cls in elem.classes if cls in {'add', 'rm'}), None)
if diff_cls == 'add': add()