idml 0.9.7 → 0.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/TODO.pdf/125-script-spacing.md +22 -0
- data/TODO.pdf/126-part-cache.md +22 -0
- data/TODO.pdf/13-cjk-text-layout.md +5 -3
- data/lib/idml/package.rb +10 -0
- data/lib/idml/text_engine/cjk_layout.rb +32 -0
- data/lib/idml/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 29f97721ebdd63304b8c879eaa45764906dfa40b85363688aa9d860ccdd6f62c
|
|
4
|
+
data.tar.gz: 439a3e3454be081957617ce5107ae735a47d56c4dc206104d3e483c5a20db669
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0c669bcf817d1e2b8ab74c116e3a0e472b8ca5529fdfeba4f0adb85d7f1ddb78da5d422c63907cbe68f4a7c381ce5862d17b674063070bce64e9664584159b97
|
|
7
|
+
data.tar.gz: b427dc2a77703a71074fc541eb8eea36485dc78607dea9faa8f13d3ca69c70e013a749374ef8abca81057bdf5e7563f6717bea30e45ad967a5836ead3e325d6a
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# TODO PDF 125: CJK/Latin automatic script spacing (mojikumi subset)
|
|
2
|
+
|
|
3
|
+
## Status: COMPLETE — implemented 2026-08-20
|
|
4
|
+
|
|
5
|
+
## What was done
|
|
6
|
+
|
|
7
|
+
- `TextEngine::CjkLayout.apply_script_spacing` widens the leading
|
|
8
|
+
glyph by an eighth em at every CJK ↔ ASCII alphanumeric boundary
|
|
9
|
+
— InDesign's default inter-script auto spacing (a mojikumi
|
|
10
|
+
behavior).
|
|
11
|
+
- Wired inside `TextEngine::Shaper#shape`, so every shaping path
|
|
12
|
+
(horizontal frame text, footnotes, ruby, vertical columns)
|
|
13
|
+
applies it uniformly — one integration point, no per-caller
|
|
14
|
+
changes.
|
|
15
|
+
- Punctuation neighbors are ignored (only letters/digits form
|
|
16
|
+
boundaries).
|
|
17
|
+
|
|
18
|
+
## Remaining from TODO 13
|
|
19
|
+
|
|
20
|
+
Class-based mojikumi (per-pair punctuation compression tables,
|
|
21
|
+
line-end punctuation hanging beyond half-em) remains a documented
|
|
22
|
+
stretch goal.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# TODO PDF 126: Package#part memoization
|
|
2
|
+
|
|
3
|
+
## Status: COMPLETE — implemented 2026-08-20
|
|
4
|
+
|
|
5
|
+
## Problem
|
|
6
|
+
|
|
7
|
+
`Package#part(name)` re-read and re-parsed the zip entry on every
|
|
8
|
+
call. Rendering resolves `story_by_id` per frame plus preferences
|
|
9
|
+
(Footnote.option), styles, and graphics repeatedly — each lookup
|
|
10
|
+
decompressed and re-parsed the same XML.
|
|
11
|
+
|
|
12
|
+
## What was done
|
|
13
|
+
|
|
14
|
+
Parsed parts are memoized in a per-`Package` hash
|
|
15
|
+
(`parse_part` remains the single read+parse path; `each_part` /
|
|
16
|
+
`read_part` stay uncached raw reads for round-trip byte fidelity).
|
|
17
|
+
|
|
18
|
+
## Acceptance criteria
|
|
19
|
+
|
|
20
|
+
- [x] Repeated `part(name)` calls return the same object.
|
|
21
|
+
- [x] Different parts do not share objects.
|
|
22
|
+
- [x] Whole-package round-trip specs unchanged (raw reads).
|
|
@@ -20,9 +20,11 @@ kinsoku shori, ruby annotations).
|
|
|
20
20
|
frame width (previously they overflowed as one long line) — this
|
|
21
21
|
also fixes horizontal CJK wrapping.
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
vertical
|
|
25
|
-
|
|
23
|
+
2026-08-20 completions: tate-chu-yoko (TODO 124), Latin rotation
|
|
24
|
+
and vertical ruby (TODO 122), CJK/Latin automatic script spacing
|
|
25
|
+
(TODO 125, a mojikumi subset wired into Shaper). The remaining
|
|
26
|
+
stretch goal is full class-based mojikumi (per-pair punctuation
|
|
27
|
+
compression tables). See `lib/idml/text_engine/cjk_layout.rb` and
|
|
26
28
|
`lib/idml/text_engine/vertical_text_layout.rb`.
|
|
27
29
|
|
|
28
30
|
## Progress 2026-08-17
|
data/lib/idml/package.rb
CHANGED
|
@@ -134,13 +134,23 @@ module Idml
|
|
|
134
134
|
# Returns a typed part instance for `name` when a class is registered
|
|
135
135
|
# for that file pattern (e.g. Designmap for designmap.xml). Falls
|
|
136
136
|
# back to Parts::Raw — a lossless XML wrapper — for unmodeled parts.
|
|
137
|
+
# Parsed parts are memoized: rendering resolves stories,
|
|
138
|
+
# preferences, and styles repeatedly (per frame), and each
|
|
139
|
+
# un-memoized read would re-decompress and re-parse the zip
|
|
140
|
+
# entry.
|
|
137
141
|
def part(name)
|
|
142
|
+
@part_cache ||= {}
|
|
143
|
+
@part_cache[name] ||= parse_part(name)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def parse_part(name)
|
|
138
147
|
xml = read_part(name)
|
|
139
148
|
klass = Idml::Parts.class_for(name)
|
|
140
149
|
return Idml::Parts::Raw.from_xml(xml) unless klass
|
|
141
150
|
|
|
142
151
|
klass.from_xml(xml)
|
|
143
152
|
end
|
|
153
|
+
private :parse_part
|
|
144
154
|
|
|
145
155
|
def each_part
|
|
146
156
|
return enum_for(:each_part) unless block_given?
|
|
@@ -7,6 +7,38 @@ module Idml
|
|
|
7
7
|
module CjkLayout
|
|
8
8
|
module_function
|
|
9
9
|
|
|
10
|
+
# Mojikumi subset: automatic inter-script spacing — an eighth
|
|
11
|
+
# em is inserted between adjacent CJK and ASCII alphanumeric
|
|
12
|
+
# glyphs (widenning the leading glyph of each pair), matching
|
|
13
|
+
# InDesign's default CJK/Latin auto spacing.
|
|
14
|
+
SCRIPT_SPACING_EM = 0.125
|
|
15
|
+
|
|
16
|
+
def apply_script_spacing(glyphs, size)
|
|
17
|
+
spacing = size * SCRIPT_SPACING_EM
|
|
18
|
+
(0...(glyphs.length - 1)).each do |index|
|
|
19
|
+
leading = glyphs[index]
|
|
20
|
+
following = glyphs[index + 1]
|
|
21
|
+
next unless script_boundary?(leading.codepoint,
|
|
22
|
+
following.codepoint)
|
|
23
|
+
|
|
24
|
+
leading.width += spacing
|
|
25
|
+
end
|
|
26
|
+
glyphs
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# True when exactly one of the pair is CJK and the other is
|
|
30
|
+
# an ASCII letter or digit.
|
|
31
|
+
def script_boundary?(left, right)
|
|
32
|
+
(cjk?(left) && ascii_alnum?(right)) ||
|
|
33
|
+
(ascii_alnum?(left) && cjk?(right))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def ascii_alnum?(codepoint)
|
|
37
|
+
(0x30..0x39).cover?(codepoint) ||
|
|
38
|
+
(0x41..0x5A).cover?(codepoint) ||
|
|
39
|
+
(0x61..0x7A).cover?(codepoint)
|
|
40
|
+
end
|
|
41
|
+
|
|
10
42
|
CJK_RANGES = [
|
|
11
43
|
0x3000..0x303F, # CJK Symbols and Punctuation
|
|
12
44
|
0x3040..0x309F, # Hiragana
|
data/lib/idml/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: idml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose
|
|
@@ -183,6 +183,8 @@ files:
|
|
|
183
183
|
- TODO.pdf/122-vertical-latin-ruby.md
|
|
184
184
|
- TODO.pdf/123-keep-options.md
|
|
185
185
|
- TODO.pdf/124-tatechuyoko-vertical.md
|
|
186
|
+
- TODO.pdf/125-script-spacing.md
|
|
187
|
+
- TODO.pdf/126-part-cache.md
|
|
186
188
|
- TODO.pdf/13-cjk-text-layout.md
|
|
187
189
|
- TODO.pdf/14-page-item-element-models.md
|
|
188
190
|
- TODO.pdf/15-wire-spread-children.md
|