Skip to content

feat(form_fit): set tabs on a paragraph's own tab stops - #475

Merged
airmang merged 2 commits into
mainfrom
feat/form-fit-custom-tab-stops
Oct 16, 2026
Merged

airmang merged 2 commits into
mainfrom
feat/form-fit-custom-tab-stops

Conversation

@airmang

@airmang airmang commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

Stacked on #470 (default tab stops); the diff against that branch is this change alone.

What

FormFit and the page estimate now lay a tab out on the stops of the paragraph's tab definition, as Hancom Office does:

  • The first stop past the tab whose text can be aligned there comes first. A left stop starts the text there, a right stop ends it there, a centre stop centres it there, and a decimal stop puts its last full stop there.
  • The aligned text neither starts before the tab nor passes the line's end. A stop it cannot take is passed over. A left stop is taken where it stands, but past a stop already passed over, it too ends its text at the line's end.
  • The automatic tab at the end is a right stop at the line's end, among the others. The automatic tab of a hanging indent is a left stop where its lines start.
  • Then the default stops. Past a stop it could not take, a tab whose text has no room on the line after the default stop takes no width.
  • A tab reaching the margin itself, even one of no width, goes on to the next line.

Before, such a tab was laid out as a space-class glyph.

Tests

  • New Hancom-saved fixtures (saved by Hancom Office 2024, scrubbed) of paragraphs with stops of their own after labels, numbers and words. They cover a centre stop then the default stops, a left stop past the line's end, a decimal stop passed over, the automatic tab at the end and a right stop with no room. Without the line caches they fail before this change and pass after.
  • test_a_tab_reaches_the_paragraphs_own_stops_first covers each rule of tab_reach.

🤖 Generated with Claude Code

FormFit and the page estimate now lay a tab out on the stops of the
paragraph's tab definition, as Hancom Office does:

- The first stop past the tab whose text can be aligned there comes first: a
  left stop starts the text there, a right stop ends it there, a centre stop
  centres it there and a decimal stop puts its last full stop there. The
  aligned text neither starts before the tab nor passes the line's end; a stop
  it cannot take is passed over. A left stop past the line's end is taken all
  the same.
- The automatic tab at the end is a right stop at the line's end among the
  others; the automatic tab of a hanging indent a left stop where its lines
  start.
- Then the default stops. Past a stop it could not take, a tab whose text has
  no room on the line after the default stop takes no width.
- A tab reaching the margin itself no longer fits on the line.

Before, such a tab was laid out as a space-class glyph. Hancom-saved fixtures
hold paragraphs of all these kinds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@airmang
airmang changed the base branch from fix/form-fit-default-tab-stops to main October 16, 2026 05:08
Past a stop that could not take the text, a left stop past the line's end, or whose text would pass it, ends the text at the line's end, as Hancom Office lays it out; with no stop passed over, a left stop is still taken where it stands. A tab reaching the margin goes on to the next line even when it takes no width. Two more Hancom-saved fixtures hold such tabs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@airmang airmang left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Reviewed the custom tab-stop implementation and surrounding line measurement code, including the new 7c2e2e8 changes for left stops after a skipped stop and a zero-width tab at the margin. After parent #470 merged, retargeted this stacked PR to main and verified the resulting scope. On this exact new head integrated with current main dae1ee2, the tab-related FormFit/page-estimation suite passed: 792 passed, 733 deselected. No reproducible defect found in the reviewed scope. Holding merge because the new head's Python 3.10–3.14 CI jobs are still running; the successful checks and broader 1521-test run on the superseded c02e0d0 head do not certify the new head. Recheck head, base, threads and all applicable checks before merging.

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.

1 participant