idml 0.9.1 → 0.9.2
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/.github/workflows/release.yml +5 -3
- data/TODO.pdf/104-table-schema-completion.md +16 -6
- data/TODO.pdf/116-justification-last-line.md +31 -0
- data/TODO.pdf/117-endnote-support.md +45 -0
- data/lib/idml/elements/endnote.rb +22 -0
- data/lib/idml/elements/endnote_range.rb +21 -0
- data/lib/idml/elements/story_inner.rb +5 -0
- data/lib/idml/elements/table.rb +369 -1
- data/lib/idml/elements.rb +2 -0
- data/lib/idml/render/footnote.rb +10 -2
- data/lib/idml/render/renderers/text_frame_renderer.rb +19 -8
- data/lib/idml/text_engine/justifier.rb +16 -5
- data/lib/idml/version.rb +1 -1
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: eb1bde51604723b865996a34842c6a5216b3c0ce4f55947902aa9dd92358ed25
|
|
4
|
+
data.tar.gz: a1e6ed580c3d0fee769287d3619c33fa6e18ed79ee332d1aa0a7976b1352b760
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 989af27c2ad974dac8d370e335e923b70727a0c32991fe67011c2231cd5b526fdf59e73d571df8423ae69e9e27a5fa03dd69cf94a732ec76138cb34188af0792
|
|
7
|
+
data.tar.gz: d3daaccd0d51e4a78b825f5ea2f7baf6a3c23c11df1c33eb793b649c23b18bac2255de8e3fc3e3e7d62addac871b77f20879931dac73d6f14fec6fe54c10caea
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
1
|
+
# Managed by Cimas; trusted-publishing change is intentional (2026-08-18):
|
|
2
|
+
# publish via RubyGems OIDC Trusted Publishing instead of the API key
|
|
3
|
+
# (the API-key path is blocked by rubygems.org MFA OTP demands).
|
|
4
|
+
# See https://github.com/metanorma/ci — the reusable workflow uses its
|
|
5
|
+
# OIDC path whenever the rubygems-api-key secret is not passed.
|
|
3
6
|
name: release
|
|
4
7
|
|
|
5
8
|
on:
|
|
@@ -20,6 +23,5 @@ jobs:
|
|
|
20
23
|
with:
|
|
21
24
|
next_version: ${{ github.event.inputs.next_version }}
|
|
22
25
|
secrets:
|
|
23
|
-
rubygems-api-key: ${{ secrets.METANORMA_CI_RUBYGEMS_API_KEY }}
|
|
24
26
|
pat_token: ${{ secrets.METANORMA_CI_PAT_TOKEN }}
|
|
25
27
|
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
# TODO PDF 104: Schema-faithful Table model completion
|
|
2
2
|
|
|
3
|
-
## Status:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
## Status: COMPLETE — implemented 2026-08-18
|
|
4
|
+
|
|
5
|
+
All 171 Table_Object attributes from
|
|
6
|
+
`reference-docs/schemas/package/Stories/Story.rnc` are declared on
|
|
7
|
+
`Elements::Table` (the prior rendering-relevant subset plus the 155
|
|
8
|
+
remaining: border tints/gaps/overprints, default row/column strokes,
|
|
9
|
+
alternating fills, cell insets, diagonal lines, caption settings,
|
|
10
|
+
…), generated with `scripts/rnc_to_lutaml.rb` in schema order.
|
|
11
|
+
|
|
12
|
+
Drift defense: `spec/idml/elements/table_spec.rb` reads the RNC at
|
|
13
|
+
spec time and asserts a Table built with every schema attribute
|
|
14
|
+
round-trips every attribute — any attribute dropped from the model
|
|
15
|
+
fails the spec.
|
|
16
|
+
|
|
17
|
+
The renderer still consults only the rendering-relevant subset; the
|
|
18
|
+
rest are carried for round-trip and downstream-tool fidelity.
|
|
9
19
|
|
|
10
20
|
## Problem
|
|
11
21
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# TODO PDF 116: Justified-text last-line handling
|
|
2
|
+
|
|
3
|
+
## Status: COMPLETE — implemented 2026-08-18
|
|
4
|
+
|
|
5
|
+
## Problem
|
|
6
|
+
|
|
7
|
+
`TextEngine::Justifier` spread slack across inter-word spaces for
|
|
8
|
+
`:justified` paragraphs on EVERY line, including each paragraph's
|
|
9
|
+
final line — InDesign (and standard typography) leaves the last line
|
|
10
|
+
of a justified paragraph ragged. Every fully-justified paragraph
|
|
11
|
+
rendered with its final line stretched across the full column width.
|
|
12
|
+
|
|
13
|
+
## What was done
|
|
14
|
+
|
|
15
|
+
- `Justifier.justify` takes `last_line:`; when true, a `:justified`
|
|
16
|
+
line falls back to left alignment (no space stretching). All other
|
|
17
|
+
alignments unchanged.
|
|
18
|
+
- `TextFrameRenderer.layout_run` passes `last_line:` true for the
|
|
19
|
+
final line of the paragraph's FINAL run (`paragraph_last:` flag
|
|
20
|
+
threaded from `render_runs_for_paragraph`, which knows the run
|
|
21
|
+
list). Mid-paragraph run breaks still justify — only the true
|
|
22
|
+
paragraph-final line goes ragged.
|
|
23
|
+
- Footnote layout (`Render::Footnote.layout_paragraph`) applies the
|
|
24
|
+
same rule for the final line of the final run.
|
|
25
|
+
|
|
26
|
+
## Known limitations
|
|
27
|
+
|
|
28
|
+
- Justification adjusts inter-word spaces only; letter spacing and
|
|
29
|
+
glyph scaling (Minimum/Maximum/DesiredGlyphScaling, tracking) are
|
|
30
|
+
not applied. ToBinding / RTL binding alignment remains mapped to
|
|
31
|
+
left.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# TODO PDF 117: Endnote support
|
|
2
|
+
|
|
3
|
+
## Status: OPEN (modeling COMPLETE 2026-08-18; rendering OPEN pending
|
|
4
|
+
a real fixture)
|
|
5
|
+
|
|
6
|
+
## Problem
|
|
7
|
+
|
|
8
|
+
IDML endnotes use a reference architecture unlike footnotes: the
|
|
9
|
+
main story carries `<Endnote Self="..." EndnoteTextRange="..."/>`
|
|
10
|
+
plus `<EndnoteRange SourceEndnote="..."/>` markers (both at Story
|
|
11
|
+
level, per Story.rnc), while the endnote TEXT lives in a separate
|
|
12
|
+
story flagged `IsEndnoteStory="true"`. Documents with endnotes
|
|
13
|
+
(scholarly publishing) currently drop endnote text entirely.
|
|
14
|
+
|
|
15
|
+
## What is done (2026-08-18)
|
|
16
|
+
|
|
17
|
+
- `Elements::Endnote` (Self, EndnoteTextRange) and
|
|
18
|
+
`Elements::EndnoteRange` (Self, SourceEndnote) — schema-faithful
|
|
19
|
+
models, wired into `StoryInner` (`endnote`, `endnote_range`
|
|
20
|
+
collections). Round-trip + parse specs.
|
|
21
|
+
- `StoryInner#is_endnote_story` already parsed, so endnote stories
|
|
22
|
+
are identifiable.
|
|
23
|
+
|
|
24
|
+
## Design for rendering (needs a real InDesign fixture to validate)
|
|
25
|
+
|
|
26
|
+
1. Marker: story-level `Endnote`/`EndnoteRange` pairs delimit the
|
|
27
|
+
anchor range; marker position requires story text-offset
|
|
28
|
+
bookkeeping the extraction layer doesn't currently track (unlike
|
|
29
|
+
footnotes, which sit inside a CSR). A range-aware extraction is
|
|
30
|
+
the prerequisite.
|
|
31
|
+
2. Endnote text: resolve `EndnoteTextRange` → the endnote story
|
|
32
|
+
(IsEndnoteStory) → its paragraphs.
|
|
33
|
+
3. Placement: per EndnoteOption Scope — end of story / end of
|
|
34
|
+
section / end of document; end-of-story is the tractable default
|
|
35
|
+
(append after the referencing story's last paragraph).
|
|
36
|
+
4. Numbering: endnotes number separately from footnotes
|
|
37
|
+
(FootnoteOption vs EndnoteOption StartAt/Prefix/Suffix — the
|
|
38
|
+
Endnote preference object is not yet modeled in Preferences).
|
|
39
|
+
|
|
40
|
+
## Why rendering is deferred
|
|
41
|
+
|
|
42
|
+
The marker-position machinery (text-range resolution) cannot be
|
|
43
|
+
validated without a real fixture; blind implementation risks wrong
|
|
44
|
+
anchor placement on production files. Schema modeling + round-trip
|
|
45
|
+
is complete and verified.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Idml
|
|
4
|
+
module Elements
|
|
5
|
+
# `<Endnote>` — a story-level endnote reference. The endnote's
|
|
6
|
+
# TEXT lives in a separate story flagged `IsEndnoteStory="true"`;
|
|
7
|
+
# this element points at it via `EndnoteTextRange` (schema:
|
|
8
|
+
# Endnote_Object in Stories/Story.rnc — Self plus the range
|
|
9
|
+
# reference; no inline content). Rendering design in
|
|
10
|
+
# TODO.pdf/117-endnote-support.md.
|
|
11
|
+
class Endnote < Lutaml::Model::Serializable
|
|
12
|
+
attribute :self_attr, :string
|
|
13
|
+
attribute :endnote_text_range, :string
|
|
14
|
+
|
|
15
|
+
xml do
|
|
16
|
+
root "Endnote"
|
|
17
|
+
map_attribute "Self", to: :self_attr
|
|
18
|
+
map_attribute "EndnoteTextRange", to: :endnote_text_range
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Idml
|
|
4
|
+
module Elements
|
|
5
|
+
# `<EndnoteRange>` — marks the text range in the main story that
|
|
6
|
+
# an endnote references, linking back via `SourceEndnote`
|
|
7
|
+
# (schema: EndnoteRange_Object in Stories/Story.rnc). Pairs with
|
|
8
|
+
# Elements::Endnote; rendering design in
|
|
9
|
+
# TODO.pdf/117-endnote-support.md.
|
|
10
|
+
class EndnoteRange < Lutaml::Model::Serializable
|
|
11
|
+
attribute :self_attr, :string
|
|
12
|
+
attribute :source_endnote, :string
|
|
13
|
+
|
|
14
|
+
xml do
|
|
15
|
+
root "EndnoteRange"
|
|
16
|
+
map_attribute "Self", to: :self_attr
|
|
17
|
+
map_attribute "SourceEndnote", to: :source_endnote
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -313,6 +313,9 @@ module Idml
|
|
|
313
313
|
attribute :content, Idml::Elements::Content, collection: true
|
|
314
314
|
attribute :xml_element, Idml::Elements::XmlElement, collection: true
|
|
315
315
|
attribute :footnote, Idml::Elements::Footnote, collection: true
|
|
316
|
+
attribute :endnote, Idml::Elements::Endnote, collection: true
|
|
317
|
+
attribute :endnote_range, Idml::Elements::EndnoteRange,
|
|
318
|
+
collection: true
|
|
316
319
|
|
|
317
320
|
xml do
|
|
318
321
|
root "Story"
|
|
@@ -678,6 +681,8 @@ module Idml
|
|
|
678
681
|
map_element "Content", to: :content
|
|
679
682
|
map_element "XMLElement", to: :xml_element
|
|
680
683
|
map_element "Footnote", to: :footnote
|
|
684
|
+
map_element "Endnote", to: :endnote
|
|
685
|
+
map_element "EndnoteRange", to: :endnote_range
|
|
681
686
|
end
|
|
682
687
|
|
|
683
688
|
def text_content
|
data/lib/idml/elements/table.rb
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
module Idml
|
|
4
4
|
module Elements
|
|
5
5
|
# `<Table>` — a table page item. Carries geometry, body/header
|
|
6
|
-
# row counts, column layout, and border styling.
|
|
6
|
+
# row counts, column layout, and border styling. Declares every
|
|
7
|
+
# attribute of Table_Object in Stories/Story.rnc (171 schema
|
|
8
|
+
# attributes). Two child
|
|
7
9
|
# collections hold the table's content:
|
|
8
10
|
#
|
|
9
11
|
# - `row` — schema-faithful `<Row>` siblings (real IDML).
|
|
@@ -43,6 +45,167 @@ module Idml
|
|
|
43
45
|
attribute :right_border_stroke_weight, :float
|
|
44
46
|
attribute :right_border_stroke_color, :string
|
|
45
47
|
|
|
48
|
+
# The remaining Table_Object attributes (border tints/gaps/
|
|
49
|
+
# overprints, default row/column strokes, alternating fills,
|
|
50
|
+
# cell insets, diagonal lines, caption settings, …) in schema
|
|
51
|
+
# order — generated by `scripts/rnc_to_lutaml.rb` from
|
|
52
|
+
# reference-docs/schemas/package/Stories/Story.rnc.
|
|
53
|
+
attribute :top_border_stroke_type, :string
|
|
54
|
+
attribute :top_border_stroke_tint, :float
|
|
55
|
+
attribute :top_border_stroke_overprint, :boolean
|
|
56
|
+
attribute :top_border_stroke_gap_color, :string
|
|
57
|
+
attribute :top_border_stroke_gap_tint, :float
|
|
58
|
+
attribute :top_border_stroke_gap_overprint, :boolean
|
|
59
|
+
attribute :left_border_stroke_type, :string
|
|
60
|
+
attribute :left_border_stroke_tint, :float
|
|
61
|
+
attribute :left_border_stroke_overprint, :boolean
|
|
62
|
+
attribute :left_border_stroke_gap_color, :string
|
|
63
|
+
attribute :left_border_stroke_gap_tint, :float
|
|
64
|
+
attribute :left_border_stroke_gap_overprint, :boolean
|
|
65
|
+
attribute :bottom_border_stroke_type, :string
|
|
66
|
+
attribute :bottom_border_stroke_tint, :float
|
|
67
|
+
attribute :bottom_border_stroke_overprint, :boolean
|
|
68
|
+
attribute :bottom_border_stroke_gap_color, :string
|
|
69
|
+
attribute :bottom_border_stroke_gap_tint, :float
|
|
70
|
+
attribute :bottom_border_stroke_gap_overprint, :boolean
|
|
71
|
+
attribute :right_border_stroke_type, :string
|
|
72
|
+
attribute :right_border_stroke_tint, :float
|
|
73
|
+
attribute :right_border_stroke_overprint, :boolean
|
|
74
|
+
attribute :right_border_stroke_gap_color, :string
|
|
75
|
+
attribute :right_border_stroke_gap_tint, :float
|
|
76
|
+
attribute :right_border_stroke_gap_overprint, :boolean
|
|
77
|
+
attribute :space_before, :float
|
|
78
|
+
attribute :space_after, :float
|
|
79
|
+
attribute :skip_first_alternating_stroke_rows, :integer
|
|
80
|
+
attribute :skip_last_alternating_stroke_rows, :integer
|
|
81
|
+
attribute :start_row_stroke_count, :integer
|
|
82
|
+
attribute :start_row_stroke_color, :string
|
|
83
|
+
attribute :start_row_stroke_weight, :float
|
|
84
|
+
attribute :start_row_stroke_type, :string
|
|
85
|
+
attribute :start_row_stroke_tint, :float
|
|
86
|
+
attribute :start_row_stroke_gap_overprint, :boolean
|
|
87
|
+
attribute :start_row_stroke_gap_color, :string
|
|
88
|
+
attribute :start_row_stroke_gap_tint, :float
|
|
89
|
+
attribute :start_row_stroke_overprint, :boolean
|
|
90
|
+
attribute :end_row_stroke_count, :integer
|
|
91
|
+
attribute :end_row_stroke_color, :string
|
|
92
|
+
attribute :end_row_stroke_weight, :float
|
|
93
|
+
attribute :end_row_stroke_type, :string
|
|
94
|
+
attribute :end_row_stroke_tint, :float
|
|
95
|
+
attribute :end_row_stroke_overprint, :boolean
|
|
96
|
+
attribute :end_row_stroke_gap_color, :string
|
|
97
|
+
attribute :end_row_stroke_gap_tint, :float
|
|
98
|
+
attribute :end_row_stroke_gap_overprint, :boolean
|
|
99
|
+
attribute :skip_first_alternating_stroke_columns, :integer
|
|
100
|
+
attribute :skip_last_alternating_stroke_columns, :integer
|
|
101
|
+
attribute :start_column_stroke_count, :integer
|
|
102
|
+
attribute :start_column_stroke_color, :string
|
|
103
|
+
attribute :start_column_stroke_weight, :float
|
|
104
|
+
attribute :start_column_stroke_type, :string
|
|
105
|
+
attribute :start_column_stroke_tint, :float
|
|
106
|
+
attribute :start_column_stroke_overprint, :boolean
|
|
107
|
+
attribute :start_column_stroke_gap_color, :string
|
|
108
|
+
attribute :start_column_stroke_gap_tint, :float
|
|
109
|
+
attribute :start_column_stroke_gap_overprint, :boolean
|
|
110
|
+
attribute :end_column_stroke_count, :integer
|
|
111
|
+
attribute :end_column_stroke_color, :string
|
|
112
|
+
attribute :end_column_stroke_weight, :float
|
|
113
|
+
attribute :end_column_line_style, :string
|
|
114
|
+
attribute :end_column_stroke_tint, :float
|
|
115
|
+
attribute :end_column_stroke_overprint, :boolean
|
|
116
|
+
attribute :end_column_stroke_gap_color, :string
|
|
117
|
+
attribute :end_column_stroke_gap_tint, :float
|
|
118
|
+
attribute :end_column_stroke_gap_overprint, :boolean
|
|
119
|
+
attribute :column_fills_priority, :boolean
|
|
120
|
+
attribute :skip_first_alternating_fill_rows, :integer
|
|
121
|
+
attribute :skip_last_alternating_fill_rows, :integer
|
|
122
|
+
attribute :start_row_fill_color, :string
|
|
123
|
+
attribute :start_row_fill_count, :integer
|
|
124
|
+
attribute :start_row_fill_tint, :float
|
|
125
|
+
attribute :start_row_fill_overprint, :boolean
|
|
126
|
+
attribute :end_row_fill_count, :integer
|
|
127
|
+
attribute :end_row_fill_color, :string
|
|
128
|
+
attribute :end_row_fill_tint, :float
|
|
129
|
+
attribute :end_row_fill_overprint, :boolean
|
|
130
|
+
attribute :skip_first_alternating_fill_columns, :integer
|
|
131
|
+
attribute :skip_last_alternating_fill_columns, :integer
|
|
132
|
+
attribute :start_column_fill_count, :integer
|
|
133
|
+
attribute :start_column_fill_color, :string
|
|
134
|
+
attribute :start_column_fill_tint, :float
|
|
135
|
+
attribute :start_column_fill_overprint, :boolean
|
|
136
|
+
attribute :end_column_fill_count, :integer
|
|
137
|
+
attribute :end_column_fill_color, :string
|
|
138
|
+
attribute :end_column_fill_tint, :float
|
|
139
|
+
attribute :end_column_fill_overprint, :boolean
|
|
140
|
+
attribute :break_headers, :string
|
|
141
|
+
attribute :break_footers, :string
|
|
142
|
+
attribute :skip_first_header, :boolean
|
|
143
|
+
attribute :skip_last_footer, :boolean
|
|
144
|
+
attribute :stroke_order, :string
|
|
145
|
+
attribute :default_row_stroke_weight, :float
|
|
146
|
+
attribute :default_row_stroke_type, :string
|
|
147
|
+
attribute :default_row_stroke_color, :string
|
|
148
|
+
attribute :default_row_stroke_tint, :float
|
|
149
|
+
attribute :default_row_stroke_overprint, :boolean
|
|
150
|
+
attribute :default_row_stroke_gap_color, :string
|
|
151
|
+
attribute :default_row_stroke_gap_tint, :float
|
|
152
|
+
attribute :default_row_stroke_gap_overprint, :boolean
|
|
153
|
+
attribute :default_column_stroke_weight, :float
|
|
154
|
+
attribute :default_column_stroke_type, :string
|
|
155
|
+
attribute :default_column_stroke_color, :string
|
|
156
|
+
attribute :default_column_stroke_tint, :float
|
|
157
|
+
attribute :default_column_stroke_overprint, :boolean
|
|
158
|
+
attribute :default_column_stroke_gap_color, :string
|
|
159
|
+
attribute :default_column_stroke_gap_tint, :float
|
|
160
|
+
attribute :default_column_stroke_gap_overprint, :boolean
|
|
161
|
+
attribute :top_inset, :float
|
|
162
|
+
attribute :left_inset, :float
|
|
163
|
+
attribute :bottom_inset, :float
|
|
164
|
+
attribute :right_inset, :float
|
|
165
|
+
attribute :fill_tint, :float
|
|
166
|
+
attribute :overprint_fill, :boolean
|
|
167
|
+
attribute :top_left_diagonal_line, :boolean
|
|
168
|
+
attribute :top_right_diagonal_line, :boolean
|
|
169
|
+
attribute :diagonal_line_in_front, :boolean
|
|
170
|
+
attribute :diagonal_line_stroke_weight, :float
|
|
171
|
+
attribute :diagonal_line_stroke_type, :string
|
|
172
|
+
attribute :diagonal_line_stroke_color, :string
|
|
173
|
+
attribute :diagonal_line_stroke_tint, :float
|
|
174
|
+
attribute :diagonal_line_stroke_overprint, :boolean
|
|
175
|
+
attribute :diagonal_line_stroke_gap_color, :string
|
|
176
|
+
attribute :diagonal_line_stroke_gap_tint, :float
|
|
177
|
+
attribute :diagonal_line_stroke_gap_overprint, :boolean
|
|
178
|
+
attribute :clip_content_to_cell, :boolean
|
|
179
|
+
attribute :first_baseline_offset, :string
|
|
180
|
+
attribute :vertical_justification, :string
|
|
181
|
+
attribute :paragraph_spacing_limit, :float
|
|
182
|
+
attribute :minimum_first_baseline_offset, :float
|
|
183
|
+
attribute :rotation_angle, :float
|
|
184
|
+
attribute :writing_direction, :boolean
|
|
185
|
+
attribute :minimum_height, :float
|
|
186
|
+
attribute :maximum_height, :float
|
|
187
|
+
attribute :keep_with_next_row, :boolean
|
|
188
|
+
attribute :start_row, :string
|
|
189
|
+
attribute :auto_grow, :boolean
|
|
190
|
+
attribute :num_header_columns, :integer
|
|
191
|
+
attribute :header_columns_position, :string
|
|
192
|
+
attribute :caption_paragraph_count, :integer
|
|
193
|
+
attribute :caption_position, :string
|
|
194
|
+
attribute :graphic_left_inset, :float
|
|
195
|
+
attribute :graphic_top_inset, :float
|
|
196
|
+
attribute :graphic_right_inset, :float
|
|
197
|
+
attribute :graphic_bottom_inset, :float
|
|
198
|
+
attribute :clip_content_to_graphic_cell, :boolean
|
|
199
|
+
attribute :text_top_inset, :float
|
|
200
|
+
attribute :text_left_inset, :float
|
|
201
|
+
attribute :text_bottom_inset, :float
|
|
202
|
+
attribute :text_right_inset, :float
|
|
203
|
+
attribute :clip_content_to_text_cell, :boolean
|
|
204
|
+
attribute :single_row_height, :float
|
|
205
|
+
attribute :applied_table_style, :string
|
|
206
|
+
attribute :display_collapsed, :boolean
|
|
207
|
+
attribute :display_order, :string
|
|
208
|
+
|
|
46
209
|
attribute :table_row, Idml::Elements::TableRow, collection: true
|
|
47
210
|
attribute :cell, Idml::Elements::Cell, collection: true
|
|
48
211
|
attribute :row, Idml::Elements::Row, collection: true
|
|
@@ -75,6 +238,211 @@ module Idml
|
|
|
75
238
|
to: :bottom_border_stroke_color
|
|
76
239
|
map_attribute "RightBorderStrokeWeight", to: :right_border_stroke_weight
|
|
77
240
|
map_attribute "RightBorderStrokeColor", to: :right_border_stroke_color
|
|
241
|
+
map_attribute "TopBorderStrokeType", to: :top_border_stroke_type
|
|
242
|
+
map_attribute "TopBorderStrokeTint", to: :top_border_stroke_tint
|
|
243
|
+
map_attribute "TopBorderStrokeOverprint",
|
|
244
|
+
to: :top_border_stroke_overprint
|
|
245
|
+
map_attribute "TopBorderStrokeGapColor",
|
|
246
|
+
to: :top_border_stroke_gap_color
|
|
247
|
+
map_attribute "TopBorderStrokeGapTint", to: :top_border_stroke_gap_tint
|
|
248
|
+
map_attribute "TopBorderStrokeGapOverprint",
|
|
249
|
+
to: :top_border_stroke_gap_overprint
|
|
250
|
+
map_attribute "LeftBorderStrokeType", to: :left_border_stroke_type
|
|
251
|
+
map_attribute "LeftBorderStrokeTint", to: :left_border_stroke_tint
|
|
252
|
+
map_attribute "LeftBorderStrokeOverprint",
|
|
253
|
+
to: :left_border_stroke_overprint
|
|
254
|
+
map_attribute "LeftBorderStrokeGapColor",
|
|
255
|
+
to: :left_border_stroke_gap_color
|
|
256
|
+
map_attribute "LeftBorderStrokeGapTint",
|
|
257
|
+
to: :left_border_stroke_gap_tint
|
|
258
|
+
map_attribute "LeftBorderStrokeGapOverprint",
|
|
259
|
+
to: :left_border_stroke_gap_overprint
|
|
260
|
+
map_attribute "BottomBorderStrokeType", to: :bottom_border_stroke_type
|
|
261
|
+
map_attribute "BottomBorderStrokeTint", to: :bottom_border_stroke_tint
|
|
262
|
+
map_attribute "BottomBorderStrokeOverprint",
|
|
263
|
+
to: :bottom_border_stroke_overprint
|
|
264
|
+
map_attribute "BottomBorderStrokeGapColor",
|
|
265
|
+
to: :bottom_border_stroke_gap_color
|
|
266
|
+
map_attribute "BottomBorderStrokeGapTint",
|
|
267
|
+
to: :bottom_border_stroke_gap_tint
|
|
268
|
+
map_attribute "BottomBorderStrokeGapOverprint",
|
|
269
|
+
to: :bottom_border_stroke_gap_overprint
|
|
270
|
+
map_attribute "RightBorderStrokeType", to: :right_border_stroke_type
|
|
271
|
+
map_attribute "RightBorderStrokeTint", to: :right_border_stroke_tint
|
|
272
|
+
map_attribute "RightBorderStrokeOverprint",
|
|
273
|
+
to: :right_border_stroke_overprint
|
|
274
|
+
map_attribute "RightBorderStrokeGapColor",
|
|
275
|
+
to: :right_border_stroke_gap_color
|
|
276
|
+
map_attribute "RightBorderStrokeGapTint",
|
|
277
|
+
to: :right_border_stroke_gap_tint
|
|
278
|
+
map_attribute "RightBorderStrokeGapOverprint",
|
|
279
|
+
to: :right_border_stroke_gap_overprint
|
|
280
|
+
map_attribute "SpaceBefore", to: :space_before
|
|
281
|
+
map_attribute "SpaceAfter", to: :space_after
|
|
282
|
+
map_attribute "SkipFirstAlternatingStrokeRows",
|
|
283
|
+
to: :skip_first_alternating_stroke_rows
|
|
284
|
+
map_attribute "SkipLastAlternatingStrokeRows",
|
|
285
|
+
to: :skip_last_alternating_stroke_rows
|
|
286
|
+
map_attribute "StartRowStrokeCount", to: :start_row_stroke_count
|
|
287
|
+
map_attribute "StartRowStrokeColor", to: :start_row_stroke_color
|
|
288
|
+
map_attribute "StartRowStrokeWeight", to: :start_row_stroke_weight
|
|
289
|
+
map_attribute "StartRowStrokeType", to: :start_row_stroke_type
|
|
290
|
+
map_attribute "StartRowStrokeTint", to: :start_row_stroke_tint
|
|
291
|
+
map_attribute "StartRowStrokeGapOverprint",
|
|
292
|
+
to: :start_row_stroke_gap_overprint
|
|
293
|
+
map_attribute "StartRowStrokeGapColor", to: :start_row_stroke_gap_color
|
|
294
|
+
map_attribute "StartRowStrokeGapTint", to: :start_row_stroke_gap_tint
|
|
295
|
+
map_attribute "StartRowStrokeOverprint", to: :start_row_stroke_overprint
|
|
296
|
+
map_attribute "EndRowStrokeCount", to: :end_row_stroke_count
|
|
297
|
+
map_attribute "EndRowStrokeColor", to: :end_row_stroke_color
|
|
298
|
+
map_attribute "EndRowStrokeWeight", to: :end_row_stroke_weight
|
|
299
|
+
map_attribute "EndRowStrokeType", to: :end_row_stroke_type
|
|
300
|
+
map_attribute "EndRowStrokeTint", to: :end_row_stroke_tint
|
|
301
|
+
map_attribute "EndRowStrokeOverprint", to: :end_row_stroke_overprint
|
|
302
|
+
map_attribute "EndRowStrokeGapColor", to: :end_row_stroke_gap_color
|
|
303
|
+
map_attribute "EndRowStrokeGapTint", to: :end_row_stroke_gap_tint
|
|
304
|
+
map_attribute "EndRowStrokeGapOverprint",
|
|
305
|
+
to: :end_row_stroke_gap_overprint
|
|
306
|
+
map_attribute "SkipFirstAlternatingStrokeColumns",
|
|
307
|
+
to: :skip_first_alternating_stroke_columns
|
|
308
|
+
map_attribute "SkipLastAlternatingStrokeColumns",
|
|
309
|
+
to: :skip_last_alternating_stroke_columns
|
|
310
|
+
map_attribute "StartColumnStrokeCount", to: :start_column_stroke_count
|
|
311
|
+
map_attribute "StartColumnStrokeColor", to: :start_column_stroke_color
|
|
312
|
+
map_attribute "StartColumnStrokeWeight", to: :start_column_stroke_weight
|
|
313
|
+
map_attribute "StartColumnStrokeType", to: :start_column_stroke_type
|
|
314
|
+
map_attribute "StartColumnStrokeTint", to: :start_column_stroke_tint
|
|
315
|
+
map_attribute "StartColumnStrokeOverprint",
|
|
316
|
+
to: :start_column_stroke_overprint
|
|
317
|
+
map_attribute "StartColumnStrokeGapColor",
|
|
318
|
+
to: :start_column_stroke_gap_color
|
|
319
|
+
map_attribute "StartColumnStrokeGapTint",
|
|
320
|
+
to: :start_column_stroke_gap_tint
|
|
321
|
+
map_attribute "StartColumnStrokeGapOverprint",
|
|
322
|
+
to: :start_column_stroke_gap_overprint
|
|
323
|
+
map_attribute "EndColumnStrokeCount", to: :end_column_stroke_count
|
|
324
|
+
map_attribute "EndColumnStrokeColor", to: :end_column_stroke_color
|
|
325
|
+
map_attribute "EndColumnStrokeWeight", to: :end_column_stroke_weight
|
|
326
|
+
map_attribute "EndColumnLineStyle", to: :end_column_line_style
|
|
327
|
+
map_attribute "EndColumnStrokeTint", to: :end_column_stroke_tint
|
|
328
|
+
map_attribute "EndColumnStrokeOverprint",
|
|
329
|
+
to: :end_column_stroke_overprint
|
|
330
|
+
map_attribute "EndColumnStrokeGapColor",
|
|
331
|
+
to: :end_column_stroke_gap_color
|
|
332
|
+
map_attribute "EndColumnStrokeGapTint", to: :end_column_stroke_gap_tint
|
|
333
|
+
map_attribute "EndColumnStrokeGapOverprint",
|
|
334
|
+
to: :end_column_stroke_gap_overprint
|
|
335
|
+
map_attribute "ColumnFillsPriority", to: :column_fills_priority
|
|
336
|
+
map_attribute "SkipFirstAlternatingFillRows",
|
|
337
|
+
to: :skip_first_alternating_fill_rows
|
|
338
|
+
map_attribute "SkipLastAlternatingFillRows",
|
|
339
|
+
to: :skip_last_alternating_fill_rows
|
|
340
|
+
map_attribute "StartRowFillColor", to: :start_row_fill_color
|
|
341
|
+
map_attribute "StartRowFillCount", to: :start_row_fill_count
|
|
342
|
+
map_attribute "StartRowFillTint", to: :start_row_fill_tint
|
|
343
|
+
map_attribute "StartRowFillOverprint", to: :start_row_fill_overprint
|
|
344
|
+
map_attribute "EndRowFillCount", to: :end_row_fill_count
|
|
345
|
+
map_attribute "EndRowFillColor", to: :end_row_fill_color
|
|
346
|
+
map_attribute "EndRowFillTint", to: :end_row_fill_tint
|
|
347
|
+
map_attribute "EndRowFillOverprint", to: :end_row_fill_overprint
|
|
348
|
+
map_attribute "SkipFirstAlternatingFillColumns",
|
|
349
|
+
to: :skip_first_alternating_fill_columns
|
|
350
|
+
map_attribute "SkipLastAlternatingFillColumns",
|
|
351
|
+
to: :skip_last_alternating_fill_columns
|
|
352
|
+
map_attribute "StartColumnFillCount", to: :start_column_fill_count
|
|
353
|
+
map_attribute "StartColumnFillColor", to: :start_column_fill_color
|
|
354
|
+
map_attribute "StartColumnFillTint", to: :start_column_fill_tint
|
|
355
|
+
map_attribute "StartColumnFillOverprint",
|
|
356
|
+
to: :start_column_fill_overprint
|
|
357
|
+
map_attribute "EndColumnFillCount", to: :end_column_fill_count
|
|
358
|
+
map_attribute "EndColumnFillColor", to: :end_column_fill_color
|
|
359
|
+
map_attribute "EndColumnFillTint", to: :end_column_fill_tint
|
|
360
|
+
map_attribute "EndColumnFillOverprint", to: :end_column_fill_overprint
|
|
361
|
+
map_attribute "BreakHeaders", to: :break_headers
|
|
362
|
+
map_attribute "BreakFooters", to: :break_footers
|
|
363
|
+
map_attribute "SkipFirstHeader", to: :skip_first_header
|
|
364
|
+
map_attribute "SkipLastFooter", to: :skip_last_footer
|
|
365
|
+
map_attribute "StrokeOrder", to: :stroke_order
|
|
366
|
+
map_attribute "DefaultRowStrokeWeight", to: :default_row_stroke_weight
|
|
367
|
+
map_attribute "DefaultRowStrokeType", to: :default_row_stroke_type
|
|
368
|
+
map_attribute "DefaultRowStrokeColor", to: :default_row_stroke_color
|
|
369
|
+
map_attribute "DefaultRowStrokeTint", to: :default_row_stroke_tint
|
|
370
|
+
map_attribute "DefaultRowStrokeOverprint",
|
|
371
|
+
to: :default_row_stroke_overprint
|
|
372
|
+
map_attribute "DefaultRowStrokeGapColor",
|
|
373
|
+
to: :default_row_stroke_gap_color
|
|
374
|
+
map_attribute "DefaultRowStrokeGapTint",
|
|
375
|
+
to: :default_row_stroke_gap_tint
|
|
376
|
+
map_attribute "DefaultRowStrokeGapOverprint",
|
|
377
|
+
to: :default_row_stroke_gap_overprint
|
|
378
|
+
map_attribute "DefaultColumnStrokeWeight",
|
|
379
|
+
to: :default_column_stroke_weight
|
|
380
|
+
map_attribute "DefaultColumnStrokeType", to: :default_column_stroke_type
|
|
381
|
+
map_attribute "DefaultColumnStrokeColor",
|
|
382
|
+
to: :default_column_stroke_color
|
|
383
|
+
map_attribute "DefaultColumnStrokeTint", to: :default_column_stroke_tint
|
|
384
|
+
map_attribute "DefaultColumnStrokeOverprint",
|
|
385
|
+
to: :default_column_stroke_overprint
|
|
386
|
+
map_attribute "DefaultColumnStrokeGapColor",
|
|
387
|
+
to: :default_column_stroke_gap_color
|
|
388
|
+
map_attribute "DefaultColumnStrokeGapTint",
|
|
389
|
+
to: :default_column_stroke_gap_tint
|
|
390
|
+
map_attribute "DefaultColumnStrokeGapOverprint",
|
|
391
|
+
to: :default_column_stroke_gap_overprint
|
|
392
|
+
map_attribute "TopInset", to: :top_inset
|
|
393
|
+
map_attribute "LeftInset", to: :left_inset
|
|
394
|
+
map_attribute "BottomInset", to: :bottom_inset
|
|
395
|
+
map_attribute "RightInset", to: :right_inset
|
|
396
|
+
map_attribute "FillTint", to: :fill_tint
|
|
397
|
+
map_attribute "OverprintFill", to: :overprint_fill
|
|
398
|
+
map_attribute "TopLeftDiagonalLine", to: :top_left_diagonal_line
|
|
399
|
+
map_attribute "TopRightDiagonalLine", to: :top_right_diagonal_line
|
|
400
|
+
map_attribute "DiagonalLineInFront", to: :diagonal_line_in_front
|
|
401
|
+
map_attribute "DiagonalLineStrokeWeight",
|
|
402
|
+
to: :diagonal_line_stroke_weight
|
|
403
|
+
map_attribute "DiagonalLineStrokeType", to: :diagonal_line_stroke_type
|
|
404
|
+
map_attribute "DiagonalLineStrokeColor", to: :diagonal_line_stroke_color
|
|
405
|
+
map_attribute "DiagonalLineStrokeTint", to: :diagonal_line_stroke_tint
|
|
406
|
+
map_attribute "DiagonalLineStrokeOverprint",
|
|
407
|
+
to: :diagonal_line_stroke_overprint
|
|
408
|
+
map_attribute "DiagonalLineStrokeGapColor",
|
|
409
|
+
to: :diagonal_line_stroke_gap_color
|
|
410
|
+
map_attribute "DiagonalLineStrokeGapTint",
|
|
411
|
+
to: :diagonal_line_stroke_gap_tint
|
|
412
|
+
map_attribute "DiagonalLineStrokeGapOverprint",
|
|
413
|
+
to: :diagonal_line_stroke_gap_overprint
|
|
414
|
+
map_attribute "ClipContentToCell", to: :clip_content_to_cell
|
|
415
|
+
map_attribute "FirstBaselineOffset", to: :first_baseline_offset
|
|
416
|
+
map_attribute "VerticalJustification", to: :vertical_justification
|
|
417
|
+
map_attribute "ParagraphSpacingLimit", to: :paragraph_spacing_limit
|
|
418
|
+
map_attribute "MinimumFirstBaselineOffset",
|
|
419
|
+
to: :minimum_first_baseline_offset
|
|
420
|
+
map_attribute "RotationAngle", to: :rotation_angle
|
|
421
|
+
map_attribute "WritingDirection", to: :writing_direction
|
|
422
|
+
map_attribute "MinimumHeight", to: :minimum_height
|
|
423
|
+
map_attribute "MaximumHeight", to: :maximum_height
|
|
424
|
+
map_attribute "KeepWithNextRow", to: :keep_with_next_row
|
|
425
|
+
map_attribute "StartRow", to: :start_row
|
|
426
|
+
map_attribute "AutoGrow", to: :auto_grow
|
|
427
|
+
map_attribute "NumHeaderColumns", to: :num_header_columns
|
|
428
|
+
map_attribute "HeaderColumnsPosition", to: :header_columns_position
|
|
429
|
+
map_attribute "CaptionParagraphCount", to: :caption_paragraph_count
|
|
430
|
+
map_attribute "CaptionPosition", to: :caption_position
|
|
431
|
+
map_attribute "GraphicLeftInset", to: :graphic_left_inset
|
|
432
|
+
map_attribute "GraphicTopInset", to: :graphic_top_inset
|
|
433
|
+
map_attribute "GraphicRightInset", to: :graphic_right_inset
|
|
434
|
+
map_attribute "GraphicBottomInset", to: :graphic_bottom_inset
|
|
435
|
+
map_attribute "ClipContentToGraphicCell",
|
|
436
|
+
to: :clip_content_to_graphic_cell
|
|
437
|
+
map_attribute "TextTopInset", to: :text_top_inset
|
|
438
|
+
map_attribute "TextLeftInset", to: :text_left_inset
|
|
439
|
+
map_attribute "TextBottomInset", to: :text_bottom_inset
|
|
440
|
+
map_attribute "TextRightInset", to: :text_right_inset
|
|
441
|
+
map_attribute "ClipContentToTextCell", to: :clip_content_to_text_cell
|
|
442
|
+
map_attribute "SingleRowHeight", to: :single_row_height
|
|
443
|
+
map_attribute "AppliedTableStyle", to: :applied_table_style
|
|
444
|
+
map_attribute "DisplayCollapsed", to: :display_collapsed
|
|
445
|
+
map_attribute "DisplayOrder", to: :display_order
|
|
78
446
|
map_element "TableRow", to: :table_row
|
|
79
447
|
map_element "Cell", to: :cell
|
|
80
448
|
map_element "Row", to: :row
|
data/lib/idml/elements.rb
CHANGED
|
@@ -43,6 +43,8 @@ module Idml
|
|
|
43
43
|
autoload :DocumentPreference, "idml/elements/pref_document_preference"
|
|
44
44
|
autoload :DottedStrokeStyle, "idml/elements/dotted_stroke_style"
|
|
45
45
|
autoload :DropShadowSetting, "idml/elements/drop_shadow_setting"
|
|
46
|
+
autoload :Endnote, "idml/elements/endnote"
|
|
47
|
+
autoload :EndnoteRange, "idml/elements/endnote_range"
|
|
46
48
|
autoload :EPubExportPreference, "idml/elements/pref_e_pub_export_preference"
|
|
47
49
|
autoload :EPubFixedLayoutExportPreference,
|
|
48
50
|
"idml/elements/pref_e_pub_fixed_layout_export_preference"
|
data/lib/idml/render/footnote.rb
CHANGED
|
@@ -128,10 +128,11 @@ module Idml
|
|
|
128
128
|
size: size)
|
|
129
129
|
lines = TextEngine::LineBreaker.break(glyphs: glyphs,
|
|
130
130
|
frame_width: wrap_width)
|
|
131
|
-
lines.
|
|
131
|
+
lines.each_with_index do |line, index|
|
|
132
132
|
TextEngine::Justifier.justify(
|
|
133
133
|
line: line, frame_width: wrap_width,
|
|
134
|
-
alignment: paragraph.alignment || :left
|
|
134
|
+
alignment: paragraph.alignment || :left,
|
|
135
|
+
last_line: last_line?(paragraph, run, index, lines)
|
|
135
136
|
)
|
|
136
137
|
end
|
|
137
138
|
leading = TextEngine::VerticalLayout.leading_for(
|
|
@@ -150,6 +151,13 @@ module Idml
|
|
|
150
151
|
end
|
|
151
152
|
private_class_method :layout_paragraph
|
|
152
153
|
|
|
154
|
+
# True for the final line of the footnote paragraph's final
|
|
155
|
+
# run — kept ragged under full justification.
|
|
156
|
+
def self.last_line?(paragraph, run, index, lines)
|
|
157
|
+
run.equal?(paragraph.runs.last) && index == lines.length - 1
|
|
158
|
+
end
|
|
159
|
+
private_class_method :last_line?
|
|
160
|
+
|
|
153
161
|
# Height to reserve at the frame bottom for the entries:
|
|
154
162
|
# separator gap + the measured paragraph stack.
|
|
155
163
|
def self.reserved_height(entries, font, frame, option = nil)
|
|
@@ -511,7 +511,8 @@ module Idml
|
|
|
511
511
|
canvas, run, paragraph, context, layout_frame, font,
|
|
512
512
|
run_wrap, cursor_y, space_before,
|
|
513
513
|
para_attrs[:first_line_indent], para_attrs[:left_indent],
|
|
514
|
-
char_cursor, bottom_limit
|
|
514
|
+
char_cursor, bottom_limit,
|
|
515
|
+
paragraph_last: run.equal?(runs.last)
|
|
515
516
|
)
|
|
516
517
|
char_cursor += positioned.length
|
|
517
518
|
cursor_y = next_y
|
|
@@ -712,7 +713,7 @@ module Idml
|
|
|
712
713
|
def self.layout_run(canvas, run, paragraph, context, layout_frame,
|
|
713
714
|
font, wrap_width, cursor_y, space_before,
|
|
714
715
|
first_line_indent, left_indent,
|
|
715
|
-
char_cursor, bottom_limit)
|
|
716
|
+
char_cursor, bottom_limit, paragraph_last: false)
|
|
716
717
|
size = run.point_size || DEFAULT_SIZE
|
|
717
718
|
glyphs = TextEngine::Shaper.shape(
|
|
718
719
|
text: run.text, font: font, size: size,
|
|
@@ -720,12 +721,7 @@ module Idml
|
|
|
720
721
|
lines = TextEngine::LineBreaker.break(
|
|
721
722
|
glyphs: glyphs, frame_width: wrap_width,
|
|
722
723
|
)
|
|
723
|
-
lines
|
|
724
|
-
TextEngine::Justifier.justify(
|
|
725
|
-
line: line, frame_width: wrap_width,
|
|
726
|
-
alignment: paragraph.alignment || :left
|
|
727
|
-
)
|
|
728
|
-
end
|
|
724
|
+
justify_lines(lines, paragraph, wrap_width, paragraph_last)
|
|
729
725
|
leading = leading_for(paragraph, size)
|
|
730
726
|
|
|
731
727
|
positioned, next_y = TextEngine::VerticalLayout.layout_block(
|
|
@@ -745,6 +741,21 @@ module Idml
|
|
|
745
741
|
end
|
|
746
742
|
private_class_method :layout_run
|
|
747
743
|
|
|
744
|
+
# Justifies the run's lines; only the final line of the
|
|
745
|
+
# paragraph's final run stays ragged under full
|
|
746
|
+
# justification.
|
|
747
|
+
def self.justify_lines(lines, paragraph, wrap_width,
|
|
748
|
+
paragraph_last)
|
|
749
|
+
lines.each_with_index do |line, index|
|
|
750
|
+
TextEngine::Justifier.justify(
|
|
751
|
+
line: line, frame_width: wrap_width,
|
|
752
|
+
alignment: paragraph.alignment || :left,
|
|
753
|
+
last_line: paragraph_last && index == lines.length - 1
|
|
754
|
+
)
|
|
755
|
+
end
|
|
756
|
+
end
|
|
757
|
+
private_class_method :justify_lines
|
|
758
|
+
|
|
748
759
|
# Emits the run's positioned lines (clipped at the bottom
|
|
749
760
|
# limit), recording positions and annotating the first line
|
|
750
761
|
# with the run's ruby when present.
|
|
@@ -4,19 +4,22 @@ module Idml
|
|
|
4
4
|
module TextEngine
|
|
5
5
|
# Distributes slack space within a line per the paragraph's
|
|
6
6
|
# alignment. Adjusts x_offset and optionally scales inter-word
|
|
7
|
-
# spaces for justified text.
|
|
7
|
+
# spaces for justified text. `last_line:` (the paragraph's final
|
|
8
|
+
# line) keeps ragged right under :justified, as InDesign does.
|
|
8
9
|
class Justifier
|
|
9
|
-
def self.justify(line:, frame_width:, alignment: :left
|
|
10
|
-
|
|
10
|
+
def self.justify(line:, frame_width:, alignment: :left,
|
|
11
|
+
last_line: false)
|
|
12
|
+
new(frame_width, alignment, last_line).justify(line)
|
|
11
13
|
end
|
|
12
14
|
|
|
13
|
-
def initialize(frame_width, alignment)
|
|
15
|
+
def initialize(frame_width, alignment, last_line)
|
|
14
16
|
@frame_width = frame_width
|
|
15
17
|
@alignment = alignment
|
|
18
|
+
@last_line = last_line
|
|
16
19
|
end
|
|
17
20
|
|
|
18
21
|
def justify(line)
|
|
19
|
-
case
|
|
22
|
+
case effective_alignment
|
|
20
23
|
when :left, :start then line.x_offset = 0
|
|
21
24
|
when :center, :middle
|
|
22
25
|
line.x_offset = (@frame_width - line.width) / 2
|
|
@@ -29,6 +32,14 @@ module Idml
|
|
|
29
32
|
|
|
30
33
|
private
|
|
31
34
|
|
|
35
|
+
# The paragraph's last line stays ragged under full
|
|
36
|
+
# justification.
|
|
37
|
+
def effective_alignment
|
|
38
|
+
return :left if @alignment == :justified && @last_line
|
|
39
|
+
|
|
40
|
+
@alignment
|
|
41
|
+
end
|
|
42
|
+
|
|
32
43
|
def justify_line(line)
|
|
33
44
|
spaces = line.glyphs.count(&:is_space)
|
|
34
45
|
slack = @frame_width - line.width
|
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.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose
|
|
@@ -173,6 +173,8 @@ files:
|
|
|
173
173
|
- TODO.pdf/114-text-wrap-around-shapes.md
|
|
174
174
|
- TODO.pdf/115-bullet-numbered-lists.md
|
|
175
175
|
- TODO.pdf/116-applied-style-resolution.md
|
|
176
|
+
- TODO.pdf/116-justification-last-line.md
|
|
177
|
+
- TODO.pdf/117-endnote-support.md
|
|
176
178
|
- TODO.pdf/12-idml-to-pdf-pipeline.md
|
|
177
179
|
- TODO.pdf/13-cjk-text-layout.md
|
|
178
180
|
- TODO.pdf/14-page-item-element-models.md
|
|
@@ -291,6 +293,8 @@ files:
|
|
|
291
293
|
- lib/idml/elements/document_object.rb
|
|
292
294
|
- lib/idml/elements/dotted_stroke_style.rb
|
|
293
295
|
- lib/idml/elements/drop_shadow_setting.rb
|
|
296
|
+
- lib/idml/elements/endnote.rb
|
|
297
|
+
- lib/idml/elements/endnote_range.rb
|
|
294
298
|
- lib/idml/elements/feather_setting.rb
|
|
295
299
|
- lib/idml/elements/fill_transparency_setting.rb
|
|
296
300
|
- lib/idml/elements/flex_layout_attribute_option.rb
|