Commit Graph

18 Commits

Author SHA1 Message Date
Kinneyzhang
64eb2f38d5 refactor!: per-gap break permissions — punctuation as first-class boxes
Kinsoku moves from merge-based box attachment to a general break-
permission layer, the foundation for no-break spans, NBSP, verbatim
atoms and punctuation protrusion:

- tokenizer: every CJK char (punctuation included) is its own box;
  the hold/attach machinery is gone.  Fixes two latent bugs: a second
  consecutive closer (字。」) could start a line, and an opener held
  across spaces reordered box content vs the original string
- ekp--str-type: cjk-punct splits into cjk-open (Ps/Pi) / cjk-close
- ekp-para gains breaks-allowed (bool-vector) + forbidden-positions
  (sparse, for C); glue at unbreakable punct gaps is nws, so
  punctuation hugs its content and justification stretch no longer
  opens gaps at 「x or x。
- halfwidth kinsoku: boxes consisting purely of .,;:!?)]}’”»›… may
  not start a line ((&[{‘“«‹ may not end one) — an ASCII comma after
  a CJK char no longer dangles at line start (old behavior violated
  CLREQ)
- DP (elisp 1D, elisp loose 2D, C): forbidden gaps are skipped as
  candidates while the line keeps extending; the emergency fallback
  generalizes from single boxes to atomic runs (no permitted break
  inside), recording real gap counts so multi-box emergency lines
  render correctly
- C module 1.2: ekp-c-break-with-arrays 11→12 args
  (forbidden-positions), batch vectors 12 elements, version gate bumped

Hyphenation improvement: 「Hello / Hello」 previously failed the
word regexp as merged boxes and were never hyphenated; as separate
boxes they hyphenate normally.

Tests: 48 ERT green (split tests migrated to the new box contract;
new unit test for break permissions and a rendered-output kinsoku
sweep across widths); 300-case fuzz 0 failures with C 1.2 parity.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 21:05:50 +08:00
Kinneyzhang
9afe491e1a chore: silence build warnings on non-macOS toolchains
- ekp_hyphen.c: check fgets return when skipping the dictionary
  encoding line (gcc -Wunused-result via glibc fortify); behavior
  unchanged — an empty file already fell through to EOF in the loops
- ekp-utils.el: declare-function for font-info, which does not exist
  in non-window-system builds (emacs-nox); call site is runtime-guarded
  by display-multi-font-p. Keeps byte-compile-error-on-warn green.

Verified: clean gcc build + 36/36 ERT + 300-case fuzz on Ubuntu 24.04
(Emacs 29.3, arm64), clean clang build + 36/36 ERT on macOS (30.2).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 19:53:39 +08:00
Kinneyzhang
112b3a0e52 refactor!: overhaul KP core — correctness, C parity, performance, tests, docs
- fix: ekp-param-set silently reset after first justify (now persists;
  ekp-param-reset added)
- fix: narrow-width CJK returned empty string (data loss); two-pass
  emergency-break strategy guarantees output for any input
- fix: K-P penalties never synced to C module; space-box metrics
  divergence between C and Elisp engines
- fix: para cache ignored ekp-latin-lang (stale hyphenation after
  language switch) and used collision-prone sxhash keys
- fix: fullwidth letters/digits misclassified as CJK punctuation
- fix: combining chars split from their base char in the tokenizer
- fix: punctuation-wrapped words (word!/(word)/word;) never hyphenated
- fix: renderer double-counted stripped space widths; negative glue
  clamped; batch/tty font detection no longer crashes
- feat: real looseness support via (position × line-count) DP
- perf: O(1) line metrics and gap counts via prefix arrays (inner loop
  previously allocated O(n) subsequences → O(n³) total); box measurement
  dedupe; eq fast-path para lookup; prebuilt per-para glue arrays
  → zh justify 7547ms → 96ms (compiled elisp) / 57ms (C);
    range-justify 68.5s → 0.48s / 34ms; C module itself 3–19× faster
- test: 36 batch-safe ERT tests + 300-case property fuzz (C/elisp
  byte-identical output, zero content loss) replacing ad-hoc suite
- docs: readme/readme_zh/DEVELOPER/DEVELOPER_ZH/ekp_c-README rewritten
  to match the implementation; phase handoff in .phrase/phases/

BREAKING: requires Emacs 29.1+; C module must be rebuilt (v1.1, new
arities); ekp-threshold-factor / ekp-flagged-penalty /
ekp-forced-break-penalty removed; Rust module stubs removed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 18:44:02 +08:00
copilot-swe-agent[bot]
50d41ed30f
fix: enforce kinsoku rules for CJK opening punctuation in box splitting
Opening brackets ((, 「, 《, etc.) are now attached to the following
character instead of the preceding one, preventing them from appearing
at the end of a line which violates kinsoku typographic rules.

Fixes #9

Agent-Logs-Url: https://github.com/Kinneyzhang/emacs-kp/sessions/d05069f4-db64-4601-9816-f582edad4a1b

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-05-24 15:22:52 +00:00
copilot-swe-agent[bot]
9b89115b5d fix: address code review feedback - improve docstrings and use defalias consistently
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-02-10 12:19:22 +00:00
copilot-swe-agent[bot]
af855e3394 refactor: Linus-style code quality improvements across Elisp and C modules
- Extract shared binary search from duplicate ekp--hyphenate-p/ekp--flagged-p
- Remove duplicate ekp-root-dir definition (shadowed ekp-utils.el version)
- Remove dead ekp-clear-caches from ekp-utils.el (cleared non-existent var)
- Replace hardcoded 'zsh' with shell-file-name for portability
- Deduplicate module reload: shared ekp--module-reload for Rust/C
- Add NULL guard for ekp_global in ekp_paragraph.c (crash prevention)
- Track actual thread count in pool to fix destroy joining wrong count
- Normalize line endings (CRLF→LF) in ekp-utils.el

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-02-10 12:18:00 +00:00
copilot-swe-agent[bot]
6d65902933 Fix: preserve all leading spaces in paragraph indentation
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-25 13:23:00 +00:00
Kinneyzhang
c88bbdd395 add dynamic moudle to improve prefermance 2026-01-25 13:50:46 +08:00
Kinneyzhang
91d9bbc1e9 process spaces between words 2026-01-25 01:17:18 +08:00
Kinneyzhang
6421f6b1fb refactor ekp cache and code improve 2026-01-24 22:40:53 +08:00
Kinneyzhang
68b46f8337 code improve 2026-01-24 20:44:38 +08:00
Kinneyzhang
ca9349e99f fix bug when text is blank string 2025-09-26 00:18:37 +08:00
Kinneyzhang
37baccded8 keep original text properties of string after typesetting 2025-08-22 00:06:14 +08:00
Kinneyzhang
165be829df a batter ekp-cjk-char-p 2025-08-19 11:31:48 +08:00
Kinneyzhang
564f33ba27 fix issue #1 2025-07-28 19:45:40 +08:00
Kinneyzhang
e9b36312fb update readme 2025-07-27 22:33:28 +08:00
Kinneyzhang
a265357e41 update readme 2025-07-27 21:35:44 +08:00
Kinneyzhang
f7f1f7104c first commit 2025-07-26 23:52:04 +08:00