diff --git a/tests/testing_utils.py b/tests/testing_utils.py index 7acf4399..9c9d956d 100644 --- a/tests/testing_utils.py +++ b/tests/testing_utils.py @@ -166,9 +166,10 @@ def _parse_base(html_content, base_url=BASE_URL): images.get_image_from_uri, cache={}, url_fetcher=document.url_fetcher, optimize_size=()) target_collector = TargetCollector() + footnotes = {} return ( document.etree_element, style_for, get_image_from_uri, base_url, - target_collector, counter_style) + target_collector, counter_style, footnotes) def parse(html_content): diff --git a/weasyprint/document.py b/weasyprint/document.py index 6bb7fe76..94aa4235 100644 --- a/weasyprint/document.py +++ b/weasyprint/document.py @@ -884,6 +884,7 @@ class Document: target_collector = TargetCollector() page_rules = [] user_stylesheets = [] + footnotes = {} image_cache = {} if image_cache is None else image_cache for css in stylesheets or []: if not hasattr(css, 'matcher'): @@ -900,7 +901,7 @@ class Document: PROGRESS_LOGGER.info('Step 4 - Creating formatting structure') context = LayoutContext( style_for, get_image_from_uri, font_config, counter_style, - target_collector) + target_collector, footnotes) return context @classmethod @@ -919,7 +920,8 @@ class Document: root_box = build_formatting_structure( html.etree_element, context.style_for, context.get_image_from_uri, - html.base_url, context.target_collector, counter_style) + html.base_url, context.target_collector, counter_style, + context.footnotes) page_boxes = layout_document(html, root_box, context) rendering = cls( diff --git a/weasyprint/formatting_structure/build.py b/weasyprint/formatting_structure/build.py index 089afe95..946acda7 100644 --- a/weasyprint/formatting_structure/build.py +++ b/weasyprint/formatting_structure/build.py @@ -51,11 +51,12 @@ ASCII_TO_WIDE.update({0x20: '\u3000', 0x2D: '\u2212'}) def build_formatting_structure(element_tree, style_for, get_image_from_uri, - base_url, target_collector, counter_style): + base_url, target_collector, counter_style, + footnotes): """Build a formatting structure (box tree) from an element tree.""" box_list = element_to_box( element_tree, style_for, get_image_from_uri, base_url, - target_collector, counter_style) + target_collector, counter_style, footnotes) if box_list: box, = box_list else: @@ -70,7 +71,7 @@ def build_formatting_structure(element_tree, style_for, get_image_from_uri, return style box, = element_to_box( element_tree, root_style_for, get_image_from_uri, base_url, - target_collector, counter_style) + target_collector, counter_style, footnotes) target_collector.check_pending_targets() @@ -91,7 +92,7 @@ def make_box(element_tag, style, content, element): def element_to_box(element, style_for, get_image_from_uri, base_url, - target_collector, counter_style, state=None): + target_collector, counter_style, footnotes, state=None): """Convert an element and its children into a box with children. Return a list of boxes. Most of the time the list will have one item but @@ -175,7 +176,7 @@ def element_to_box(element, style_for, get_image_from_uri, base_url, for child_element in element: children.extend(element_to_box( child_element, style_for, get_image_from_uri, base_url, - target_collector, counter_style, state)) + target_collector, counter_style, footnotes, state)) text = child_element.tail if text: text_box = boxes.TextBox.anonymous_from(box, text) @@ -215,12 +216,16 @@ def element_to_box(element, style_for, get_image_from_uri, base_url, box.children.append(boxes.TextBox.anonymous_from(box, '​')) if style['float'] == 'footnote': + style['float'] = 'none' style = style_for(element, 'footnote-call') counter_values['footnote'][-1] += 1 - box = make_box(f'{element.tag}::footnote-call', style, [], element) - box.children = content_to_boxes( + footnote_call_box = make_box( + f'{element.tag}::footnote-call', style, [], element) + footnote_call_box.children = content_to_boxes( style, box, quote_depth, counter_values, get_image_from_uri, target_collector, counter_style) + footnotes[footnote_call_box] = box + box = footnote_call_box # Specific handling for the element. (eg. replaced element) return html.handle_element(element, box, get_image_from_uri, base_url) diff --git a/weasyprint/layout/__init__.py b/weasyprint/layout/__init__.py index 073b51bf..516b5259 100644 --- a/weasyprint/layout/__init__.py +++ b/weasyprint/layout/__init__.py @@ -210,12 +210,13 @@ def layout_document(html, root_box, context, max_loops=8): class LayoutContext: def __init__(self, style_for, get_image_from_uri, font_config, - counter_style, target_collector): + counter_style, target_collector, footnotes): self.style_for = style_for self.get_image_from_uri = partial(get_image_from_uri, context=self) self.font_config = font_config self.counter_style = counter_style self.target_collector = target_collector + self.footnotes = footnotes self._excluded_shapes_lists = [] self.excluded_shapes = None # Not initialized yet self.string_set = defaultdict(lambda: defaultdict(lambda: list()))