idml 0.10.7 → 0.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 943028d5bf17ca306e3cce0d23c4b042ddaa9473295f2fa7f4af43009a7423a0
4
- data.tar.gz: b9c3c1e5421ffa4de44396dbc94124434dda470c3f10fabd5ddd81146c3991c1
3
+ metadata.gz: e05a75aaa533dcd8f478d6b4ab635d15cf6c64ac85bebbd42fe3b136ed0c6783
4
+ data.tar.gz: 3a478cdb4b23ac26ceb9914d5e3740286ef6fda60c80605a01dc6f2a38086b7a
5
5
  SHA512:
6
- metadata.gz: 86717ea81b1ede4576d3d41e7026cd2731ec40024ea887d33a03c4ff7771384cb0ae9fd04f5948a322d48986dae2946adcebf167a7c51ae3ce7890a28726e7ee
7
- data.tar.gz: 12a2089f4600a04fe5cd1d74e409c0933dc6f691156ffca4eeb87fcb25fd5d89e2a1ec58261c8a087ea00b93cf42abee0bb54d64f72032dc3b6bbe919f6cc6b4
6
+ metadata.gz: effb89c7a3869aa7c268027e4653ecc2072fc41402d53ff2ad8ca0405862b83076bd82637cc9f64a369cd3ceb2ca23b2e6e9ca7ba300de2fd9f073801c65c199
7
+ data.tar.gz: 371206ab57061b8fa94733db6e489565eeb0cd588ffb6b0908a9a0c6e84fcec2d64745501dd8ec7b8147cb3044119c47d08f479e50cec26e939a35f5127ecf9e
@@ -0,0 +1,27 @@
1
+ # TODO PDF 142: Run-grouped Latin rotation in vertical writing
2
+
3
+ ## Status: COMPLETE — implemented 2026-08-27
4
+
5
+ ## Problem
6
+
7
+ In vertical (StoryOrientation="Vertical") text, every non-CJK glyph
8
+ rotated 90° individually — each Latin letter got its own rotated
9
+ graphics state and stacked one cell apart. InDesign rotates a whole
10
+ Latin run as one block (the word reads sideways as a unit).
11
+
12
+ ## Solution
13
+
14
+ `TextFrameRenderer#emit_vertical_stack` partitions a vertical run's
15
+ glyphs: CJK singletons stay upright; consecutive non-CJK glyphs
16
+ (groups never span columns, x-reset on column change) render as ONE
17
+ text op inside a single rotated graphics state. The font's natural
18
+ advances land each glyph exactly where per-glyph rotation placed
19
+ it, so the change is lossless for position — but a whole word now
20
+ rotates as a unit and emits one op instead of N. The per-glyph
21
+ `emit_vertical_glyph` path is gone (dead after grouping covered it).
22
+
23
+ ## Files
24
+
25
+ - `lib/idml/render/renderers/text_frame_renderer.rb`
26
+ - `spec/idml/render/vertical_render_spec.rb`
27
+ - `spec/idml/render/vertical_multirun_spec.rb`
@@ -0,0 +1,31 @@
1
+ # TODO PDF 143: JumpObject wrap — text below the object
2
+
3
+ ## Status: COMPLETE — implemented 2026-08-27
4
+
5
+ ## Problem
6
+
7
+ JumpObjectTextWrap approximated as the bounding box: text narrowed
8
+ beside the object. InDesign's JumpObject means text NEVER flows
9
+ beside the object — it continues below it.
10
+
11
+ ## Solution
12
+
13
+ - `TextWrapResolver::Contour` gains a `jump` flag, set from
14
+ `TextWrapMode="JumpObjectTextWrap"`.
15
+ - A jump contour blocks the FULL frame width in
16
+ `wrap_adjustment`.
17
+ - `TextFrameRenderer#skip_below_jump_object`: when the run's band
18
+ is fully blocked (wrap width below the point size), the cursor
19
+ skips to `jump_contour_bottom` — the blocking object's bottom
20
+ edge — and the wrap re-measures there once. Text resumes below
21
+ the object, never beside it.
22
+
23
+ NextColumn still approximates as the box (it needs column-jump
24
+ chaining, documented in TODO.pdf/61).
25
+
26
+ ## Files
27
+
28
+ - `lib/idml/render/text_wrap_resolver.rb`
29
+ - `lib/idml/render/renderers/text_frame_renderer.rb`
30
+ - `spec/idml/render/text_wrap_resolver_spec.rb`
31
+ - `spec/idml/render/jump_object_render_spec.rb` (end-to-end)
@@ -0,0 +1,36 @@
1
+ # TODO PDF 144: Named mojikumi sets modeled
2
+
3
+ ## Status: COMPLETE (modeling) — implemented 2026-08-27
4
+
5
+ ## Problem
6
+
7
+ Designmap-level `<MojikumiTable>` elements (named mojikumi sets:
8
+ 詳細 etc. with per-class-pair aki overrides) were ignored by the
9
+ model — a document declaring custom spacing lost that information
10
+ on round-trip.
11
+
12
+ ## Solution
13
+
14
+ New elements per `designmap.rnc` / `datatype.rnc`:
15
+
16
+ - `Elements::MojikumiTable` — Self / Name / BasedOnMojikumiSet +
17
+ `#aki_overrides` (flattened document-order overrides).
18
+ - `Elements::MojikumiTableProperties` — OverrideMojikumiAkiList.
19
+ - `Elements::OverrideMojikumiAkiList` — the entries.
20
+ - `Elements::OverrideMojikumiAki` — all 8 typedef attributes
21
+ (Target/SideMojikumiClass, SideIsAfterTarget, Minimum/Desired/
22
+ Maximum, CompressionPriority, AkiDoesNotFloat).
23
+
24
+ `Parts::Designmap` maps the children; round-trip verified.
25
+
26
+ **Not yet applied**: rendering still uses the built-in class-based
27
+ aki rules (TODOs 125/132/13); consuming BasedOnMojikumiSet and the
28
+ override entries in `CjkLayout` is the follow-up (TODO.pdf/61).
29
+
30
+ ## Files
31
+
32
+ - `lib/idml/elements/mojikumi_table.rb`
33
+ - `lib/idml/parts/designmap.rb`
34
+ - `lib/idml/elements.rb`
35
+ - `spec/idml/elements/mojikumi_table_spec.rb`
36
+ - `spec/idml/parts/designmap_spec.rb`
@@ -1,6 +1,6 @@
1
1
  # TODO PDF 61: Known limitations and future work
2
2
 
3
- ## Status: DOCUMENTED — refreshed 2026-08-27
3
+ ## Status: DOCUMENTED — refreshed 2026-08-27 (second refresh)
4
4
 
5
5
  Previously listed limitations (font embedding, tagged PDF, per-run
6
6
  styling, dead code) were resolved by TODOs 52/53/55/67/76 long ago;
@@ -27,15 +27,19 @@ this list reflects the current state.
27
27
  - **Text wrap**: BoundingBoxTextWrap, Contour, and Inverse modes
28
28
  render (TODOs 130-131) with TextWrapSide side-awareness (TODO 138:
29
29
  LeftSide / RightSide / LargestArea pick the flow side; spine
30
- variants approximate as BothSides); JumpObject/NextColumn
31
- approximate as the box; Contour-mode shapes are not side-aware.
30
+ variants approximate as BothSides); JumpObject moves text below
31
+ the object (TODO 143); NextColumn approximates as the box;
32
+ Contour-mode shapes are not side-aware.
32
33
 
33
34
  ### CJK
34
35
  - **Mojikumi**: script spacing (TODO 125), line-end compression
35
- (TODO 132), and class-based pair compression (2026-08-26) are
36
- applied; named mojikumi sets (詳細 etc.) are not modeled.
37
- - **Vertical mode**: Latin rotation is per glyph (not run-grouped);
38
- ruby placement is beside-column; keep options do not apply.
36
+ (TODO 132), and class-based pair compression are applied; named
37
+ mojikumi sets are modeled (TODO 144: MojikumiTable +
38
+ OverrideMojikumiAki parse and round-trip) but not yet APPLIED to
39
+ layout the built-in class-based aki rules stand in.
40
+ - **Vertical mode**: Latin runs rotate as one group per segment
41
+ (TODO 142); ruby placement is beside-column; keep options do
42
+ not apply.
39
43
 
40
44
  ### Structural features
41
45
  - **Endnotes** (TODO 117): reference markers render and endnote TEXT
@@ -56,6 +60,7 @@ this list reflects the current state.
56
60
 
57
61
  - Hyphenation dictionary integration
58
62
  - Shape-mode text wrap contours (side-aware)
59
- - Named mojikumi sets (詳細 etc.)
63
+ - Apply named mojikumi sets to CJK layout (consume TODO 144's model)
64
+ - NextColumn wrap via column-jump chaining
60
65
  - ToBinding / RTL binding alignment
61
- - Vertical-mode keep options and run-grouped Latin rotation
66
+ - Vertical-mode keep options
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Idml
4
+ module Elements
5
+ # One aki override (per `OverrideMojikumiAkiType_TypeDef`):
6
+ # spacing between the Target and Side character classes, as
7
+ # minimum / desired / maximum.
8
+ class OverrideMojikumiAki < Lutaml::Model::Serializable
9
+ attribute :target_mojikumi_class, :integer
10
+ attribute :side_mojikumi_class, :integer
11
+ attribute :side_is_after_target, :boolean
12
+ attribute :minimum, :float
13
+ attribute :desired, :float
14
+ attribute :maximum, :float
15
+ attribute :compression_priority, :integer
16
+ attribute :aki_does_not_float, :boolean
17
+
18
+ xml do
19
+ root "OverrideMojikumiAkiType"
20
+ map_attribute "TargetMojikumiClass", to: :target_mojikumi_class
21
+ map_attribute "SideMojikumiClass", to: :side_mojikumi_class
22
+ map_attribute "SideIsAfterTarget", to: :side_is_after_target
23
+ map_attribute "Minimum", to: :minimum
24
+ map_attribute "Desired", to: :desired
25
+ map_attribute "Maximum", to: :maximum
26
+ map_attribute "CompressionPriority", to: :compression_priority
27
+ map_attribute "AkiDoesNotFloat", to: :aki_does_not_float
28
+ end
29
+ end
30
+
31
+ # `<OverrideMojikumiAkiList>` — the per-class-pair override
32
+ # entries of a named mojikumi set.
33
+ class OverrideMojikumiAkiList < Lutaml::Model::Serializable
34
+ attribute :override_mojikumi_aki, OverrideMojikumiAki,
35
+ collection: true
36
+
37
+ xml do
38
+ root "OverrideMojikumiAkiList"
39
+ map_element "OverrideMojikumiAkiType",
40
+ to: :override_mojikumi_aki
41
+ end
42
+ end
43
+
44
+ # `<Properties>` inside a MojikumiTable — carries the aki
45
+ # override list.
46
+ class MojikumiTableProperties < Lutaml::Model::Serializable
47
+ attribute :override_mojikumi_aki_list, OverrideMojikumiAkiList,
48
+ collection: true
49
+
50
+ xml do
51
+ root "Properties"
52
+ map_element "OverrideMojikumiAkiList",
53
+ to: :override_mojikumi_aki_list
54
+ end
55
+ end
56
+
57
+ # Typed model of `<MojikumiTable>` (TODO 144) — a named
58
+ # mojikumi set declared at the designmap level. Named sets are
59
+ # modeled (parsed and round-tripped) but not yet APPLIED: the
60
+ # renderer keeps using the built-in class-based aki rules (see
61
+ # TODO.pdf/61).
62
+ class MojikumiTable < Lutaml::Model::Serializable
63
+ attribute :self_attr, :string
64
+ attribute :name, :string
65
+ attribute :based_on_mojikumi_set, :string
66
+ attribute :properties, MojikumiTableProperties, collection: true
67
+
68
+ xml do
69
+ root "MojikumiTable"
70
+ map_attribute "Self", to: :self_attr
71
+ map_attribute "Name", to: :name
72
+ map_attribute "BasedOnMojikumiSet", to: :based_on_mojikumi_set
73
+ map_element "Properties", to: :properties
74
+ end
75
+
76
+ # Aki overrides in document order, flattened across the
77
+ # Properties > OverrideMojikumiAkiList chain.
78
+ def aki_overrides
79
+ properties.flat_map do |prop|
80
+ prop.override_mojikumi_aki_list.flat_map(&:override_mojikumi_aki)
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
data/lib/idml/elements.rb CHANGED
@@ -90,6 +90,10 @@ module Idml
90
90
  autoload :MasterSpreadObject, "idml/elements/master_spread_object"
91
91
  autoload :MixedInk, "idml/elements/mixed_ink"
92
92
  autoload :MixedInkGroup, "idml/elements/mixed_ink_group"
93
+ autoload :MojikumiTable, "idml/elements/mojikumi_table"
94
+ autoload :MojikumiTableProperties, "idml/elements/mojikumi_table"
95
+ autoload :OverrideMojikumiAki, "idml/elements/mojikumi_table"
96
+ autoload :OverrideMojikumiAkiList, "idml/elements/mojikumi_table"
93
97
  autoload :MojikumiUiPreference, "idml/elements/pref_mojikumi_ui_preference"
94
98
  autoload :ObjectExportOption, "idml/elements/object_export_option"
95
99
  autoload :ObjectStyle, "idml/elements/object_style"
@@ -54,6 +54,8 @@ module Idml
54
54
  Idml::Elements::HyperlinkPageDestination, collection: true
55
55
  attribute :hyperlink_url_destination,
56
56
  Idml::Elements::HyperlinkURLDestination, collection: true
57
+ attribute :mojikumi_table, Idml::Elements::MojikumiTable,
58
+ collection: true
57
59
 
58
60
  xml do
59
61
  root "Document"
@@ -99,6 +101,7 @@ module Idml
99
101
  to: :hyperlink_page_destination
100
102
  map_element "HyperlinkURLDestination",
101
103
  to: :hyperlink_url_destination
104
+ map_element "MojikumiTable", to: :mojikumi_table
102
105
  end
103
106
  end
104
107
  end
@@ -332,13 +332,60 @@ module Idml
332
332
  emit_upright_glyph(canvas, glyph, run, context, size)
333
333
  end
334
334
  else
335
- positioned.each do |glyph|
336
- emit_vertical_glyph(canvas, glyph, run, context, size)
337
- end
335
+ emit_vertical_stack(canvas, positioned, run, context, size)
338
336
  end
339
337
  end
340
338
  private_class_method :emit_vertical_run
341
339
 
340
+ # Vertical-stack emission: CJK glyphs stand upright per
341
+ # glyph; consecutive non-CJK glyphs rotate as ONE group
342
+ # (the whole Latin word sideways, as InDesign does). The
343
+ # group's string renders as a single text op inside one
344
+ # rotated graphics state — the font's advances land each
345
+ # glyph exactly where per-glyph rotation placed it. A group
346
+ # never spans columns (x reset) and shares the run's
347
+ # styling, so one text op is lossless.
348
+ def self.emit_vertical_stack(canvas, positioned, run, context,
349
+ size)
350
+ segment = []
351
+ positioned.each do |glyph|
352
+ if TextEngine::CjkLayout.cjk?(glyph.codepoint)
353
+ flush_vertical_segment(canvas, segment, run, context, size)
354
+ emit_upright_glyph(canvas, glyph, run, context, size)
355
+ else
356
+ if !segment.empty? && segment.last.x != glyph.x
357
+ flush_vertical_segment(canvas, segment, run, context, size)
358
+ end
359
+ segment << glyph
360
+ end
361
+ end
362
+ flush_vertical_segment(canvas, segment, run, context, size)
363
+ end
364
+ private_class_method :emit_vertical_stack
365
+
366
+ def self.flush_vertical_segment(canvas, segment, run, context,
367
+ size)
368
+ return if segment.empty?
369
+
370
+ text = segment.map { |g| [g.codepoint].pack("U") }.join
371
+ first = segment.first
372
+ canvas.save_graphics_state do
373
+ # 90° clockwise: exact matrix (rotate would emit
374
+ # cos/sin float noise like 6.1e-17).
375
+ canvas.concat(0, -1, 1, 0, first.x, first.y)
376
+ text_kwargs = CharacterStyle.text_kwargs(
377
+ run,
378
+ {
379
+ at: [0, 0],
380
+ font: font_for_run(run, context),
381
+ size: size,
382
+ },
383
+ )
384
+ canvas.text(text, **text_kwargs)
385
+ end
386
+ end
387
+ private_class_method :flush_vertical_segment
388
+
342
389
  def self.emit_upright_glyph(canvas, positioned, run, context,
343
390
  size)
344
391
  text = [positioned.codepoint].pack("U")
@@ -361,43 +408,6 @@ module Idml
361
408
  end
362
409
  private_class_method :vertical_fits?
363
410
 
364
- # Emits one upright glyph at its vertical position with the
365
- # run's character styling.
366
- # Emits one glyph in vertical mode: CJK upright; Latin
367
- # (non-CJK) rotated 90° clockwise per the vertical-writing
368
- # convention, via a graphics-state transform.
369
- def self.emit_vertical_glyph(canvas, positioned, run, context,
370
- size)
371
- text = [positioned.codepoint].pack("U")
372
- if TextEngine::CjkLayout.cjk?(positioned.codepoint)
373
- text_kwargs = CharacterStyle.text_kwargs(
374
- run,
375
- {
376
- at: [positioned.x, positioned.y],
377
- font: font_for_run(run, context),
378
- size: size,
379
- },
380
- )
381
- canvas.text(text, **text_kwargs)
382
- else
383
- canvas.save_graphics_state do
384
- # 90° clockwise: exact matrix (rotate would emit
385
- # cos/sin float noise like 6.1e-17).
386
- canvas.concat(0, -1, 1, 0, positioned.x, positioned.y)
387
- text_kwargs = CharacterStyle.text_kwargs(
388
- run,
389
- {
390
- at: [0, 0],
391
- font: font_for_run(run, context),
392
- size: size,
393
- },
394
- )
395
- canvas.text(text, **text_kwargs)
396
- end
397
- end
398
- end
399
- private_class_method :emit_vertical_glyph
400
-
401
411
  # Emits the run's ruby alongside its vertical glyphs:
402
412
  # stacked top-to-bottom beside the column — right side by
403
413
  # default, left for Below* RubyPosition values (the
@@ -881,6 +891,10 @@ module Idml
881
891
  context, layout_frame, cursor_y, run
882
892
  )
883
893
  run_wrap -= wrap_reduction
894
+ cursor_y, run_wrap, wrap_shift = skip_below_jump_object(
895
+ context, layout_frame, cursor_y, run, run_wrap, wrap_shift,
896
+ wrap_reduction, bottom_limit
897
+ )
884
898
  positioned, next_y = layout_run(
885
899
  canvas, run, paragraph, context, layout_frame, font,
886
900
  run_wrap, cursor_y, space_before,
@@ -946,6 +960,42 @@ module Idml
946
960
  end
947
961
  private_class_method :render_footnote_entries
948
962
 
963
+ # JumpObjectTextWrap blocks the full column width: when the
964
+ # run's band is fully blocked, move the cursor below the
965
+ # object's bottom edge and re-measure once. InDesign's
966
+ # semantics — text flows under the object, never beside it.
967
+ # Returns the (possibly skipped) cursor and re-measured
968
+ # wrap geometry.
969
+ def self.skip_below_jump_object(context, layout_frame, cursor_y,
970
+ run, run_wrap, wrap_shift,
971
+ wrap_reduction, bottom_limit)
972
+ min_width = run.point_size || DEFAULT_SIZE
973
+ return [cursor_y, run_wrap, wrap_shift] if run_wrap >= min_width
974
+
975
+ skip_y = text_wrap_jump_below(context, layout_frame, cursor_y, run)
976
+ return [cursor_y, run_wrap, wrap_shift] unless skip_y
977
+ return [cursor_y, run_wrap, wrap_shift] if skip_y >= cursor_y
978
+ return [cursor_y, run_wrap, wrap_shift] if skip_y <= bottom_limit
979
+
980
+ reduction, shift = text_wrap_adjust(context, layout_frame,
981
+ skip_y, run)
982
+ [skip_y, [run_wrap + wrap_reduction - reduction, 0].max, shift]
983
+ end
984
+ private_class_method :skip_below_jump_object
985
+
986
+ def self.text_wrap_jump_below(context, layout_frame, cursor_y, run)
987
+ resolver = context.text_wrap_resolver
988
+ return nil unless resolver
989
+
990
+ size = run.point_size || DEFAULT_SIZE
991
+ frame_x = layout_frame.x + (layout_frame.inset_left || 0)
992
+ frame_right = layout_frame.x + layout_frame.width -
993
+ (layout_frame.inset_right || 0)
994
+ resolver.jump_contour_bottom(cursor_y, size, frame_x,
995
+ frame_right)
996
+ end
997
+ private_class_method :text_wrap_jump_below
998
+
949
999
  # Computes the text-wrap adjustment for a run at its current y
950
1000
  # position: [width_reduction, x_shift]. The reduction narrows
951
1001
  # the wrap width; the shift moves wrapped lines right past a
@@ -18,7 +18,7 @@ module Idml
18
18
  class TextWrapResolver
19
19
  # A wrap contour: a PDF-coordinate rectangle the text avoids.
20
20
  Contour = Struct.new(
21
- :x, :y, :width, :height, :inverse, :side,
21
+ :x, :y, :width, :height, :inverse, :side, :jump,
22
22
  keyword_init: true
23
23
  )
24
24
 
@@ -86,10 +86,34 @@ module Idml
86
86
 
87
87
  return [0.0, 0.0] if overlap.zero?
88
88
 
89
+ # JumpObject: text never flows beside the object — the full
90
+ # frame width is blocked and the renderer skips the run
91
+ # below the object's bottom edge.
92
+ return [frame_right - frame_x, 0.0] if contour.jump
93
+
89
94
  side_adjustment(contour, overlap, frame_x, frame_right)
90
95
  end
91
96
  private :box_adjustment
92
97
 
98
+ # Bottom edge of the lowest jump contour overlapping the given
99
+ # band — where text resumes below a JumpObject. nil when no
100
+ # jump contour blocks the band.
101
+ def jump_contour_bottom(line_y, line_height, frame_x, frame_right)
102
+ bottoms = @contours.filter_map do |contour|
103
+ next unless box_contour?(contour) && contour.jump
104
+ next unless y_overlap?(contour, line_y, line_height) &&
105
+ x_overlap?(contour, frame_x, frame_right)
106
+
107
+ contour.y
108
+ end
109
+ bottoms.min
110
+ end
111
+
112
+ def box_contour?(contour)
113
+ !contour.is_a?(WrapContour::Shape)
114
+ end
115
+ private :box_contour?
116
+
93
117
  def side_adjustment(contour, overlap, frame_x, frame_right)
94
118
  case contour.side
95
119
  when "LeftSide"
@@ -165,7 +189,8 @@ module Idml
165
189
  Contour.new(
166
190
  x: rect[:x], y: rect[:y],
167
191
  width: rect[:width], height: rect[:height],
168
- side: pref&.text_wrap_side
192
+ side: pref&.text_wrap_side,
193
+ jump: pref&.text_wrap_mode == "JumpObjectTextWrap"
169
194
  )
170
195
  end
171
196
  private_class_method :box_contour
data/lib/idml/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Idml
4
- VERSION = "0.10.7"
4
+ VERSION = "0.10.8"
5
5
  end
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.10.7
4
+ version: 0.10.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose
@@ -205,6 +205,9 @@ files:
205
205
  - TODO.pdf/14-page-item-element-models.md
206
206
  - TODO.pdf/140-cap-xheight-first-baselines.md
207
207
  - TODO.pdf/141-perf-hundred-pages.md
208
+ - TODO.pdf/142-vertical-latin-run-groups.md
209
+ - TODO.pdf/143-jump-object-below.md
210
+ - TODO.pdf/144-mojikumi-table-model.md
208
211
  - TODO.pdf/15-wire-spread-children.md
209
212
  - TODO.pdf/16-typed-model-pipeline.md
210
213
  - TODO.pdf/17-shape-rendering.md
@@ -348,6 +351,7 @@ files:
348
351
  - lib/idml/elements/master_spread_object.rb
349
352
  - lib/idml/elements/mixed_ink.rb
350
353
  - lib/idml/elements/mixed_ink_group.rb
354
+ - lib/idml/elements/mojikumi_table.rb
351
355
  - lib/idml/elements/object_export_option.rb
352
356
  - lib/idml/elements/object_style.rb
353
357
  - lib/idml/elements/object_style_content_effects_category_settings.rb