Skip to content

fix(layout): keep authorship scripts on parent line - #433

Open
yzxcj797 wants to merge 1 commit into
firecrawl:mainfrom
yzxcj797:fix/291-author-affiliation-formatting
Open

fix(layout): keep authorship scripts on parent line#433
yzxcj797 wants to merge 1 commit into
firecrawl:mainfrom
yzxcj797:fix/291-author-affiliation-formatting

Conversation

@yzxcj797

@yzxcj797 yzxcj797 commented Aug 19, 2026

Copy link
Copy Markdown

Problem

Issue #291's arXiv reproduction still splits the first author onto its own heading-like line. The author affiliation markers use a smaller font and a baseline about 3.6pt above the names, which exceeds the normal line-grouping tolerance.

A broad script merge is not safe: mathematical variables, numeric exponents, and trademark symbols can also sit above the baseline.

Change

Keep compact authorship markers such as , , and their short numeric suffixes on the parent line only when all of these hold:

  • the run is at least 15% smaller than the parent text;
  • its baseline remains within a bounded script shift;
  • it starts immediately after the preceding run;
  • it uses the compact authorship-marker vocabulary;
  • an authorship symbol starts or already exists in the run.

This keeps the full author row together while leaving formula variables, numeric exponents, detached small text, and separate affiliation entries on their own lines.

Tests

  • Added six synthetic line-grouping regressions for the author case and detached, widely offset, variable, exponent, and overlong-marker boundaries.
  • Verified the public arXiv reproduction no longer emits #### Yichuan Wang as a separate line.
  • Existing Shannon and Freon snapshots cover the formula-variable and trademark boundaries.

Fixes #291


Summary by cubic

Keeps compact authorship superscripts on the same line as the author name to prevent heading-like splits in arXiv reproductions. Previously, small markers could form new lines; now they merge into the parent line only under strict size, position, and vocabulary checks, leaving math variables, exponents, and detached small text unchanged.

  • Introduces is_affiliation_marker, has_authorship_symbol, and continues_authorship_script_run; integrates with group_single_column to allow merges only when text is ≤85% of parent size, within a bounded script shift, immediately adjacent, and uses the authorship-marker vocabulary.
  • Adds six regression tests and verifies the public arXiv case no longer emits "#### Yichuan Wang".
  • Default line-grouping tolerance remains unchanged; the new logic only applies to authorship markers.

Written for commit c026a45. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/extractor/layout.rs">

<violation number="1" location="src/extractor/layout.rs:2936">
P2: When a mathematical run contains ASCII `*`, `has_authorship_symbol` treats the whole run as an authorship marker. A contiguous smaller numeric exponent can then be merged into the formula; restrict symbol detection to compact marker-only runs or distinguish multiplication from standalone markers.</violation>

<violation number="2" location="src/extractor/layout.rs:2954">
P2: When a line already contains an authorship marker (`∗`/`†`/`§`/`¶`/`*`), the new script-run path lets any small digit/punct run that sits within ~1.75pt horizontally of the line end and within 0.6× the parent font vertically (e.g. 6pt at 10pt) merge onto that line, with the `has_y_change` left-margin/stacked-line check fully bypassed. A separate affiliation number that is adjacent to a short author run can therefore be glued onto the author line even though it starts its own entry. Bound the script shift to the actual script offset window already used elsewhere (top of the usual ~3.6pt superscript band) rather than 0.6× the whole font em, so only genuine superscript markers next to the parent run are merged.</violation>

<violation number="3" location="src/extractor/layout.rs:2965">
P2: For RTL author rows, markers placed to the visual left fail the LTR-only gap and X-order checks, so the regression remains. Make the continuation geometry direction-aware before applying the authorship override.</violation>
</file>

Shadow auto-approve: would not auto-approve because issues were found.

Fix all with cubic | Re-trigger cubic

Comment thread src/extractor/layout.rs
// parent run. A wider gap is the next affiliation entry, not a continuation
// of the preceding institution.
let maximum_script_gap = (1.0_f32).max(item.font_size.max(last_item.font_size) * 0.25);
let follows_line_end = horizontal_gap >= -1.0 && horizontal_gap <= maximum_script_gap;

@cubic-dev-ai cubic-dev-ai Bot Aug 19, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: For RTL author rows, markers placed to the visual left fail the LTR-only gap and X-order checks, so the regression remains. Make the continuation geometry direction-aware before applying the authorship override.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/extractor/layout.rs, line 2965:

<comment>For RTL author rows, markers placed to the visual left fail the LTR-only gap and X-order checks, so the regression remains. Make the continuation geometry direction-aware before applying the authorship override.</comment>

<file context>
@@ -2916,6 +2916,62 @@ fn should_use_y_sorting(items: &[TextItem]) -> bool {
+    // parent run. A wider gap is the next affiliation entry, not a continuation
+    // of the preceding institution.
+    let maximum_script_gap = (1.0_f32).max(item.font_size.max(last_item.font_size) * 0.25);
+    let follows_line_end = horizontal_gap >= -1.0 && horizontal_gap <= maximum_script_gap;
+
+    follows_line_end
</file context>
Fix with cubic

Comment thread src/extractor/layout.rs
}

fn has_authorship_symbol(text: &str) -> bool {
text.chars()

@cubic-dev-ai cubic-dev-ai Bot Aug 19, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: When a mathematical run contains ASCII *, has_authorship_symbol treats the whole run as an authorship marker. A contiguous smaller numeric exponent can then be merged into the formula; restrict symbol detection to compact marker-only runs or distinguish multiplication from standalone markers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/extractor/layout.rs, line 2936:

<comment>When a mathematical run contains ASCII `*`, `has_authorship_symbol` treats the whole run as an authorship marker. A contiguous smaller numeric exponent can then be merged into the formula; restrict symbol detection to compact marker-only runs or distinguish multiplication from standalone markers.</comment>

<file context>
@@ -2916,6 +2916,62 @@ fn should_use_y_sorting(items: &[TextItem]) -> bool {
+}
+
+fn has_authorship_symbol(text: &str) -> bool {
+    text.chars()
+        .any(|c| matches!(c, '∗' | '*' | '†' | '‡' | '§' | '¶'))
+}
</file context>
Fix with cubic

Comment thread src/extractor/layout.rs
};

let font_ratio = item.font_size / first_item.font_size;
let maximum_script_shift = (y_tolerance.max(first_item.font_size * 0.6)).max(0.0);

@cubic-dev-ai cubic-dev-ai Bot Aug 19, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: When a line already contains an authorship marker (//§//*), the new script-run path lets any small digit/punct run that sits within ~1.75pt horizontally of the line end and within 0.6× the parent font vertically (e.g. 6pt at 10pt) merge onto that line, with the has_y_change left-margin/stacked-line check fully bypassed. A separate affiliation number that is adjacent to a short author run can therefore be glued onto the author line even though it starts its own entry. Bound the script shift to the actual script offset window already used elsewhere (top of the usual ~3.6pt superscript band) rather than 0.6× the whole font em, so only genuine superscript markers next to the parent run are merged.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/extractor/layout.rs, line 2954:

<comment>When a line already contains an authorship marker (`∗`/`†`/`§`/`¶`/`*`), the new script-run path lets any small digit/punct run that sits within ~1.75pt horizontally of the line end and within 0.6× the parent font vertically (e.g. 6pt at 10pt) merge onto that line, with the `has_y_change` left-margin/stacked-line check fully bypassed. A separate affiliation number that is adjacent to a short author run can therefore be glued onto the author line even though it starts its own entry. Bound the script shift to the actual script offset window already used elsewhere (top of the usual ~3.6pt superscript band) rather than 0.6× the whole font em, so only genuine superscript markers next to the parent run are merged.</comment>

<file context>
@@ -2916,6 +2916,62 @@ fn should_use_y_sorting(items: &[TextItem]) -> bool {
+    };
+
+    let font_ratio = item.font_size / first_item.font_size;
+    let maximum_script_shift = (y_tolerance.max(first_item.font_size * 0.6)).max(0.0);
+    let horizontal_gap = item.x - (last_item.x + last_item.width);
+    let starts_or_continues_authorship_marker = has_authorship_symbol(item.text.trim())
</file context>
Fix with cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ERROR: arxiv paper title and people name format process error

1 participant