Amend footnote div with duplicates.
| 364 | |
| 365 | |
| 366 | class FootnotePostTreeprocessor(Treeprocessor): |
| 367 | """ Amend footnote div with duplicates. """ |
| 368 | |
| 369 | def __init__(self, footnotes: FootnoteExtension): |
| 370 | self.footnotes = footnotes |
| 371 | |
| 372 | def add_duplicates(self, li: etree.Element, duplicates: int) -> None: |
| 373 | """ Adjust current `li` and add the duplicates: `fnref2`, `fnref3`, etc. """ |
| 374 | for link in li.iter('a'): |
| 375 | # Find the link that needs to be duplicated. |
| 376 | if link.attrib.get('class', '') == 'footnote-backref': |
| 377 | ref, rest = link.attrib['href'].split(self.footnotes.get_separator(), 1) |
| 378 | # Duplicate link the number of times we need to |
| 379 | # and point the to the appropriate references. |
| 380 | links = [] |
| 381 | for index in range(2, duplicates + 1): |
| 382 | sib_link = copy.deepcopy(link) |
| 383 | sib_link.attrib['href'] = '%s%d%s%s' % (ref, index, self.footnotes.get_separator(), rest) |
| 384 | links.append(sib_link) |
| 385 | self.offset += 1 |
| 386 | # Add all the new duplicate links. |
| 387 | el = list(li)[-1] |
| 388 | for link in links: |
| 389 | el.append(link) |
| 390 | break |
| 391 | |
| 392 | def get_num_duplicates(self, li: etree.Element) -> int: |
| 393 | """ Get the number of duplicate refs of the footnote. """ |
| 394 | fn, rest = li.attrib.get('id', '').split(self.footnotes.get_separator(), 1) |
| 395 | link_id = '{}ref{}{}'.format(fn, self.footnotes.get_separator(), rest) |
| 396 | return self.footnotes.found_refs.get(link_id, 0) |
| 397 | |
| 398 | def handle_duplicates(self, parent: etree.Element) -> None: |
| 399 | """ Find duplicate footnotes and format and add the duplicates. """ |
| 400 | for li in list(parent): |
| 401 | # Check number of duplicates footnotes and insert |
| 402 | # additional links if needed. |
| 403 | count = self.get_num_duplicates(li) |
| 404 | if count > 1: |
| 405 | self.add_duplicates(li, count) |
| 406 | |
| 407 | def run(self, root: etree.Element) -> None: |
| 408 | """ Crawl the footnote div and add missing duplicate footnotes. """ |
| 409 | self.offset = 0 |
| 410 | for div in root.iter('div'): |
| 411 | if div.attrib.get('class', '') == 'footnote': |
| 412 | # Footnotes should be under the first ordered list under |
| 413 | # the footnote div. So once we find it, quit. |
| 414 | for ol in div.iter('ol'): |
| 415 | self.handle_duplicates(ol) |
| 416 | break |
| 417 | |
| 418 | |
| 419 | class FootnoteTreeprocessor(Treeprocessor): |