prawn-manual_builder 0.4.0 → 0.5.0
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
- checksums.yaml.gz.sig +0 -0
- data/lib/prawn/manual_builder/chapter.rb +70 -62
- data/lib/prawn/manual_builder/manual.rb +37 -41
- data/lib/prawn/manual_builder/part.rb +10 -10
- data/lib/prawn/manual_builder/peritext.rb +4 -5
- data/lib/prawn/manual_builder/section.rb +2 -1
- data/lib/prawn/manual_builder/syntax_highlight.rb +41 -40
- data/lib/prawn/manual_builder/text_renderer.rb +24 -17
- data/lib/prawn/manual_builder/version.rb +1 -1
- data/lib/prawn/manual_builder.rb +18 -13
- data.tar.gz.sig +0 -0
- metadata +30 -19
- metadata.gz.sig +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e3f537a2d1b80a3ebfa551d2ab5c17bdb4bbf5f6dbdc5e14a558e6b906b425c4
|
|
4
|
+
data.tar.gz: '095b7efe84500c1755f8b1f41013b285215fc829b26203f054b2a709dde04e49'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ab1d759eb9ce4bd0c418d31c52969c9c87c171e689022268e41f1bb51632b79a3cd6bbecebc8142422deeb9dd6f1c8acd4ed6f3cfc7e9fbc6a1608b3ca13fe3c
|
|
7
|
+
data.tar.gz: d5bb6ffcede9882741e563427b4a34e71d139fa1306a25b6e3230f8352c1fddc5192fc1be085778642d6d2a964b399569bcd9d5491ba3c8b4e6e20a27c996e8b
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require 'prism'
|
|
4
4
|
require_relative 'part'
|
|
5
5
|
require_relative 'text_renderer'
|
|
6
|
-
require_relative
|
|
6
|
+
require_relative 'syntax_highlight'
|
|
7
7
|
|
|
8
8
|
module Prawn
|
|
9
9
|
module ManualBuilder
|
|
@@ -14,12 +14,12 @@ module Prawn
|
|
|
14
14
|
if block
|
|
15
15
|
instance_eval(&block)
|
|
16
16
|
else
|
|
17
|
-
warn
|
|
17
|
+
warn("Chapter defined in #{__FILE__} has no content")
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
self.auto_render = true
|
|
21
21
|
at_exit do
|
|
22
|
-
if
|
|
22
|
+
if auto_render
|
|
23
23
|
execute_example
|
|
24
24
|
end
|
|
25
25
|
end
|
|
@@ -35,10 +35,10 @@ module Prawn
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def text(&block)
|
|
38
|
-
if
|
|
39
|
-
@text
|
|
40
|
-
else
|
|
38
|
+
if block_given?
|
|
41
39
|
@text = block
|
|
40
|
+
else
|
|
41
|
+
@text
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
|
|
@@ -48,11 +48,12 @@ module Prawn
|
|
|
48
48
|
elsif source != NOT_SET && block_given?
|
|
49
49
|
raise ArgumentError, "Example can't be specified both as a block and as a string"
|
|
50
50
|
else
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
@example =
|
|
52
|
+
if source == NOT_SET
|
|
53
|
+
block
|
|
54
|
+
else
|
|
55
|
+
source
|
|
56
|
+
end
|
|
56
57
|
@example_axes = axes
|
|
57
58
|
@eval_example = eval
|
|
58
59
|
@standalone_example = standalone
|
|
@@ -86,13 +87,13 @@ module Prawn
|
|
|
86
87
|
TextRenderer.new(doc, &text).render
|
|
87
88
|
end
|
|
88
89
|
|
|
90
|
+
return unless example
|
|
91
|
+
|
|
89
92
|
example_source(doc)
|
|
90
93
|
|
|
91
94
|
if eval_example? && !standalone_example?
|
|
92
95
|
eval_example(doc)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
unless eval_example?
|
|
96
|
+
else
|
|
96
97
|
standalone_example(doc)
|
|
97
98
|
end
|
|
98
99
|
end
|
|
@@ -111,7 +112,7 @@ module Prawn
|
|
|
111
112
|
parse_result = Prism.parse(source)
|
|
112
113
|
|
|
113
114
|
block =
|
|
114
|
-
Prism::Pattern.new(
|
|
115
|
+
Prism::Pattern.new('CallNode[name: :example, block: BlockNode]')
|
|
115
116
|
.scan(parse_result.value)
|
|
116
117
|
.find { |node| node.block.location.start_line == block_source_line }
|
|
117
118
|
&.block
|
|
@@ -130,7 +131,7 @@ module Prawn
|
|
|
130
131
|
end
|
|
131
132
|
|
|
132
133
|
def chapter_header(doc)
|
|
133
|
-
raise
|
|
134
|
+
raise Error, 'Title is not set' unless title
|
|
134
135
|
|
|
135
136
|
header_options = {
|
|
136
137
|
leading: 6,
|
|
@@ -143,12 +144,10 @@ module Prawn
|
|
|
143
144
|
if manual.root_path && example
|
|
144
145
|
rel_path = Pathname.new(path).relative_path_from(manual.root_path)
|
|
145
146
|
|
|
146
|
-
header_text.
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
{ text: "#{rel_path.basename}", color: ORANGE, font: 'Iosevka', size: HEADER_FONT_SIZE * 0.75 },
|
|
151
|
-
]
|
|
147
|
+
header_text.push(
|
|
148
|
+
{ text: "\n" },
|
|
149
|
+
{ text: "#{rel_path.dirname}/", color: BROWN, font: 'Iosevka', size: HEADER_FONT_SIZE * 0.75 },
|
|
150
|
+
{ text: rel_path.basename.to_s, color: ORANGE, font: 'Iosevka', size: HEADER_FONT_SIZE * 0.75 },
|
|
152
151
|
)
|
|
153
152
|
end
|
|
154
153
|
|
|
@@ -168,25 +167,26 @@ module Prawn
|
|
|
168
167
|
def eval_example(doc)
|
|
169
168
|
old_new_page_callback = doc.new_page_callback
|
|
170
169
|
crossed_page = false
|
|
171
|
-
doc.new_page_callback =
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
doc
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
170
|
+
doc.new_page_callback =
|
|
171
|
+
lambda do |doc|
|
|
172
|
+
# Reset bounding box on new page
|
|
173
|
+
doc.bounds = Prawn::Document::BoundingBox.new(
|
|
174
|
+
doc,
|
|
175
|
+
nil,
|
|
176
|
+
[0, doc.page.dimensions[3]],
|
|
177
|
+
width: doc.page.dimensions[2],
|
|
178
|
+
height: doc.page.dimensions[3],
|
|
179
|
+
)
|
|
180
|
+
setup_example_area(doc)
|
|
181
|
+
crossed_page = true
|
|
182
|
+
end
|
|
183
183
|
|
|
184
184
|
preserving_doc_settings(doc) do
|
|
185
185
|
doc.save_graphics_state do
|
|
186
186
|
doc.bounding_box(
|
|
187
187
|
[-doc.bounds.absolute_left, doc.cursor],
|
|
188
188
|
width: doc.page.dimensions[2],
|
|
189
|
-
height: doc.y
|
|
189
|
+
height: doc.y,
|
|
190
190
|
) do
|
|
191
191
|
doc.start_new_page if new_page_example?
|
|
192
192
|
setup_example_area(doc) unless crossed_page
|
|
@@ -197,15 +197,15 @@ module Prawn
|
|
|
197
197
|
else
|
|
198
198
|
doc.instance_eval(example, path)
|
|
199
199
|
end
|
|
200
|
-
rescue => e
|
|
201
|
-
puts
|
|
200
|
+
rescue StandardError => e
|
|
201
|
+
puts("Error evaluating example: #{e.message}")
|
|
202
202
|
puts
|
|
203
|
-
puts
|
|
203
|
+
puts('---- Source: ----')
|
|
204
204
|
puts
|
|
205
|
-
puts
|
|
205
|
+
puts(example)
|
|
206
206
|
puts
|
|
207
|
-
puts
|
|
208
|
-
puts
|
|
207
|
+
puts('---- Backtrace: ----')
|
|
208
|
+
puts(e.backtrace)
|
|
209
209
|
end
|
|
210
210
|
end
|
|
211
211
|
end
|
|
@@ -221,22 +221,26 @@ module Prawn
|
|
|
221
221
|
doc.stroke_color(GRAY)
|
|
222
222
|
doc.line_width(line_width)
|
|
223
223
|
|
|
224
|
-
doc.stroke_rectangle(
|
|
224
|
+
doc.stroke_rectangle(
|
|
225
|
+
[line_width / 2, doc.bounds.top - (line_width / 2)], doc.bounds.width - line_width,
|
|
226
|
+
doc.bounds.height - line_width,
|
|
227
|
+
)
|
|
225
228
|
|
|
226
|
-
# We're
|
|
229
|
+
# We're resetting fonts for the example so we have to add it again
|
|
227
230
|
example_title_font = '_ManualExampleTitle'
|
|
228
231
|
doc.font_families.update(
|
|
229
232
|
example_title_font => {
|
|
230
233
|
normal: "#{Prawn::ManualBuilder::DATADIR}/fonts/DejaVuSans-Bold.ttf",
|
|
231
234
|
bold: "#{Prawn::ManualBuilder::DATADIR}/fonts/DejaVuSans-Bold.ttf",
|
|
232
|
-
}
|
|
235
|
+
},
|
|
236
|
+
)
|
|
233
237
|
example_title = 'Example Output'
|
|
234
|
-
text = [{text: example_title, font: example_title_font, size: text_size, styles: [:bold], color: 'ffffff'}]
|
|
238
|
+
text = [{ text: example_title, font: example_title_font, size: text_size, styles: [:bold], color: 'ffffff' }]
|
|
235
239
|
h = doc.height_of_formatted(text, { final_gap: false })
|
|
236
240
|
|
|
237
241
|
doc.bounding_box(
|
|
238
|
-
[line_width, doc.bounds.top - (line_width - h) / 2 * 1.25],
|
|
239
|
-
width: doc.bounds.width - line_width * 2
|
|
242
|
+
[line_width, doc.bounds.top - ((line_width - h) / 2 * 1.25)],
|
|
243
|
+
width: doc.bounds.width - (line_width * 2),
|
|
240
244
|
) do
|
|
241
245
|
doc.formatted_text(text, align: :right)
|
|
242
246
|
end
|
|
@@ -246,48 +250,52 @@ module Prawn
|
|
|
246
250
|
doc,
|
|
247
251
|
doc.bounds,
|
|
248
252
|
[PAGE_MARGIN, doc.bounds.top - PAGE_MARGIN],
|
|
249
|
-
width: doc.bounds.width - PAGE_MARGIN * 2,
|
|
250
|
-
height: doc.bounds.height - PAGE_MARGIN * 2
|
|
251
|
-
|
|
253
|
+
width: doc.bounds.width - (PAGE_MARGIN * 2),
|
|
254
|
+
height: doc.bounds.height - (PAGE_MARGIN * 2),
|
|
255
|
+
)
|
|
252
256
|
doc.move_cursor_to(doc.bounds.height)
|
|
253
257
|
|
|
254
258
|
doc.stroke_axis if example_axes?
|
|
255
259
|
end
|
|
256
260
|
|
|
257
261
|
# Used to generate the url for the example files
|
|
258
|
-
MANUAL_URL =
|
|
259
|
-
|
|
262
|
+
MANUAL_URL = 'https://github.com/prawnpdf/prawn/tree/master/manual'
|
|
263
|
+
private_constant :MANUAL_URL
|
|
260
264
|
|
|
261
265
|
# Renders a box with the link for the example file
|
|
262
266
|
def standalone_example(doc)
|
|
263
267
|
url = "#{MANUAL_URL}/#{Pathname(path).relative_path_from(manual.root_path)}"
|
|
264
268
|
|
|
265
269
|
reason = [
|
|
266
|
-
{
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
270
|
+
{
|
|
271
|
+
text: 'This code snippet was not evaluated inline. ' \
|
|
272
|
+
'You may see its output by running the ' \
|
|
273
|
+
"example file located here:\n",
|
|
274
|
+
color: DARK_GRAY,
|
|
275
|
+
font: 'DejaVu',
|
|
276
|
+
size: 11,
|
|
277
|
+
},
|
|
278
|
+
{ text: url.gsub('/', "/#{Prawn::Text::ZWSP}"), color: BLUE, link: url, font: 'DejaVu', size: 11 },
|
|
271
279
|
]
|
|
272
280
|
|
|
273
281
|
colored_box(
|
|
274
282
|
doc, reason,
|
|
275
283
|
fill_color: LIGHT_GOLD,
|
|
276
284
|
stroke_color: DARK_GOLD,
|
|
277
|
-
leading: LEADING * 3
|
|
285
|
+
leading: LEADING * 3,
|
|
278
286
|
)
|
|
279
287
|
end
|
|
280
288
|
|
|
281
289
|
def execute_example
|
|
282
290
|
if standalone_example?
|
|
283
|
-
if
|
|
284
|
-
eval(example
|
|
291
|
+
if example.is_a?(String)
|
|
292
|
+
TOPLEVEL_BINDING.eval(example)
|
|
285
293
|
else
|
|
286
294
|
Object.new.instance_eval(&example)
|
|
287
295
|
end
|
|
288
296
|
else
|
|
289
|
-
Prawn::Document.generate(
|
|
290
|
-
if
|
|
297
|
+
Prawn::Document.generate('example.pdf') do |doc|
|
|
298
|
+
if example.is_a?(String)
|
|
291
299
|
doc.instance_eval(example, path)
|
|
292
300
|
else
|
|
293
301
|
doc.instance_eval(&example)
|
|
@@ -19,47 +19,47 @@ module Prawn
|
|
|
19
19
|
instance_eval(&block) if block
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
attr_reader :root_path
|
|
22
|
+
attr_reader :root_path
|
|
23
|
+
attr_reader :content
|
|
23
24
|
|
|
24
25
|
def generate(filename = nil)
|
|
25
|
-
doc =
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
new_page_callback
|
|
26
|
+
doc =
|
|
27
|
+
Prawn::Document.new({ skip_page_creation: true, margin: PAGE_MARGIN }.merge(@document_options)) do
|
|
28
|
+
jigmo_file = "#{Prawn::ManualBuilder::DATADIR}/fonts/Jigmo.ttf"
|
|
29
|
+
jigmo2_file = "#{Prawn::ManualBuilder::DATADIR}/fonts/Jigmo2.ttf"
|
|
30
|
+
jigmo3_file = "#{Prawn::ManualBuilder::DATADIR}/fonts/Jigmo3.ttf"
|
|
31
|
+
dejavu_file = "#{Prawn::ManualBuilder::DATADIR}/fonts/DejaVuSans.ttf"
|
|
32
|
+
dejavu_bold_file = "#{Prawn::ManualBuilder::DATADIR}/fonts/DejaVuSans-Bold.ttf"
|
|
33
|
+
dejavu_italic_file = "#{Prawn::ManualBuilder::DATADIR}/fonts/DejaVuSans-Oblique.ttf"
|
|
34
|
+
dejavu_bold_italic_file = "#{Prawn::ManualBuilder::DATADIR}/fonts/DejaVuSans-BoldOblique.ttf"
|
|
35
|
+
iosevka_file = "#{Prawn::ManualBuilder::DATADIR}/fonts/iosevka-po-regular.ttf"
|
|
36
|
+
iosevka_bold_file = "#{Prawn::ManualBuilder::DATADIR}/fonts/iosevka-po-bold.ttf"
|
|
37
|
+
font_families.update(
|
|
38
|
+
'Jigmo' => { normal: jigmo_file },
|
|
39
|
+
'Jigmo2' => { normal: jigmo2_file },
|
|
40
|
+
'Jigmo3' => { normal: jigmo3_file },
|
|
41
|
+
'DejaVu' => {
|
|
42
|
+
normal: dejavu_file,
|
|
43
|
+
bold: dejavu_bold_file,
|
|
44
|
+
italic: dejavu_italic_file,
|
|
45
|
+
bold_italic: dejavu_bold_italic_file,
|
|
46
|
+
},
|
|
47
|
+
'Iosevka' => {
|
|
48
|
+
normal: iosevka_file,
|
|
49
|
+
bold: iosevka_bold_file,
|
|
50
|
+
},
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
class << self
|
|
54
|
+
attr_accessor :new_page_callback
|
|
55
|
+
|
|
56
|
+
def start_new_page(options = {})
|
|
57
|
+
super
|
|
58
|
+
|
|
59
|
+
new_page_callback&.call(self)
|
|
59
60
|
end
|
|
60
61
|
end
|
|
61
62
|
end
|
|
62
|
-
end
|
|
63
63
|
|
|
64
64
|
render_content(doc)
|
|
65
65
|
build_outline(doc)
|
|
@@ -70,10 +70,6 @@ module Prawn
|
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
-
protected
|
|
74
|
-
|
|
75
|
-
attr_reader :content
|
|
76
|
-
|
|
77
73
|
private
|
|
78
74
|
|
|
79
75
|
def title(title = NOT_SET)
|
|
@@ -109,7 +105,7 @@ module Prawn
|
|
|
109
105
|
def load_part(relative_path)
|
|
110
106
|
part_path = File.join(root_path, "#{relative_path}.rb")
|
|
111
107
|
if File.exist?(part_path)
|
|
112
|
-
part = eval(File.read(part_path),
|
|
108
|
+
part = TOPLEVEL_BINDING.eval(File.read(part_path), part_path)
|
|
113
109
|
if part.is_a?(Part)
|
|
114
110
|
part.auto_render = false
|
|
115
111
|
part.path = part_path
|
|
@@ -14,24 +14,24 @@ module Prawn
|
|
|
14
14
|
|
|
15
15
|
private
|
|
16
16
|
|
|
17
|
-
def colored_box(doc, box_text, options={})
|
|
17
|
+
def colored_box(doc, box_text, options = {})
|
|
18
18
|
options = {
|
|
19
19
|
fill_color: DARK_GRAY,
|
|
20
20
|
stroke_color: nil,
|
|
21
21
|
text_color: LIGHT_GRAY,
|
|
22
|
-
leading: LEADING
|
|
22
|
+
leading: LEADING,
|
|
23
23
|
}.merge(options)
|
|
24
24
|
|
|
25
25
|
text_options = {
|
|
26
26
|
leading: options[:leading],
|
|
27
|
-
fallback_fonts: [
|
|
27
|
+
fallback_fonts: %w[DejaVu Jigmo Jigmo2 Jigmo3],
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
box_height = 0
|
|
31
31
|
|
|
32
32
|
doc.bounding_box(
|
|
33
33
|
[INNER_MARGIN + RHYTHM, doc.cursor],
|
|
34
|
-
width: doc.bounds.width - (INNER_MARGIN + RHYTHM) * 2
|
|
34
|
+
width: doc.bounds.width - ((INNER_MARGIN + RHYTHM) * 2),
|
|
35
35
|
) do
|
|
36
36
|
box_height = doc.height_of_formatted(box_text, text_options)
|
|
37
37
|
end
|
|
@@ -43,17 +43,17 @@ module Prawn
|
|
|
43
43
|
|
|
44
44
|
doc.bounding_box(
|
|
45
45
|
[INNER_MARGIN + RHYTHM, doc.cursor],
|
|
46
|
-
width: doc.bounds.width - (INNER_MARGIN + RHYTHM) * 2
|
|
46
|
+
width: doc.bounds.width - ((INNER_MARGIN + RHYTHM) * 2),
|
|
47
47
|
) do
|
|
48
48
|
box_height = doc.height_of_formatted(box_text, text_options)
|
|
49
49
|
|
|
50
50
|
doc.fill_color(options[:fill_color])
|
|
51
51
|
doc.stroke_color(options[:stroke_color] || options[:fill_color])
|
|
52
52
|
doc.fill_and_stroke_rounded_rectangle(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
[doc.bounds.left - RHYTHM, doc.cursor],
|
|
54
|
+
doc.bounds.left + doc.bounds.right + (RHYTHM * 2),
|
|
55
|
+
box_height + (RHYTHM * 2),
|
|
56
|
+
5,
|
|
57
57
|
)
|
|
58
58
|
doc.fill_color(BLACK)
|
|
59
59
|
doc.stroke_color(BLACK)
|
|
@@ -69,7 +69,7 @@ module Prawn
|
|
|
69
69
|
def inner_box(doc, &block)
|
|
70
70
|
doc.bounding_box(
|
|
71
71
|
[INNER_MARGIN, doc.cursor],
|
|
72
|
-
width: doc.bounds.width - INNER_MARGIN * 2,
|
|
72
|
+
width: doc.bounds.width - (INNER_MARGIN * 2),
|
|
73
73
|
&block
|
|
74
74
|
)
|
|
75
75
|
end
|
|
@@ -7,23 +7,22 @@ require_relative 'text_renderer'
|
|
|
7
7
|
module Prawn
|
|
8
8
|
module ManualBuilder
|
|
9
9
|
class Peritext < Part
|
|
10
|
-
|
|
11
10
|
def initialize(&block)
|
|
12
11
|
super
|
|
13
12
|
|
|
14
13
|
if block
|
|
15
14
|
instance_eval(&block)
|
|
16
15
|
else
|
|
17
|
-
warn
|
|
16
|
+
warn("Peritext defined in #{__FILE__} has no content")
|
|
18
17
|
end
|
|
19
18
|
end
|
|
20
19
|
|
|
21
20
|
# DSL
|
|
22
21
|
def text(&block)
|
|
23
|
-
if
|
|
24
|
-
@text
|
|
25
|
-
else
|
|
22
|
+
if block_given?
|
|
26
23
|
@text = block
|
|
24
|
+
else
|
|
25
|
+
@text
|
|
27
26
|
end
|
|
28
27
|
end
|
|
29
28
|
|
|
@@ -19,46 +19,48 @@ module Prawn
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def to_prawn
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
when :IDENTIFIER
|
|
42
|
-
case tokens[index - 1].type
|
|
43
|
-
when :SYMBOL_BEGIN
|
|
22
|
+
fragments =
|
|
23
|
+
tokens.each_with_index.map { |token, index|
|
|
24
|
+
style =
|
|
25
|
+
case token.type
|
|
26
|
+
when :STRING_BEGIN, :STRING_CONTENT, :STRING_END, :HEREDOC_START, :HEREDOC_END
|
|
27
|
+
STRING_STYLE
|
|
28
|
+
when :COMMENT
|
|
29
|
+
COMMENT_STYPE
|
|
30
|
+
when :CONSTANT
|
|
31
|
+
CONSTANT_STYLE
|
|
32
|
+
when :INSTANCE_VARIABLE
|
|
33
|
+
IVAR_STYLE
|
|
34
|
+
when :INTEGER, :FLOAT, :INTEGER_RATIONAL, :INTEGER_IMAGINARY
|
|
35
|
+
NUMBER_STYLE
|
|
36
|
+
when :EMBEXPR_BEGIN, :EMBEXPR_END
|
|
37
|
+
EMBEXPR_STYLE
|
|
38
|
+
when /\AKEYWORD_/
|
|
39
|
+
KEYWORD_STYLE
|
|
40
|
+
when :SYMBOL_BEGIN, :LABEL
|
|
44
41
|
SYMBOL_STYLE
|
|
45
|
-
when :
|
|
46
|
-
|
|
42
|
+
when :IDENTIFIER
|
|
43
|
+
case tokens[index - 1].type
|
|
44
|
+
when :SYMBOL_BEGIN
|
|
45
|
+
SYMBOL_STYLE
|
|
46
|
+
when :DOT
|
|
47
|
+
METHOD_STYLE
|
|
48
|
+
else
|
|
49
|
+
DEFAULT_STYLE
|
|
50
|
+
end
|
|
47
51
|
else
|
|
48
52
|
DEFAULT_STYLE
|
|
49
53
|
end
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
{ text: token.value.gsub(' ', Prawn::Text::NBSP) }.merge(style)
|
|
54
|
-
end
|
|
55
|
-
.compact
|
|
56
|
-
.each_with_object([]) do |fragment, fragments|
|
|
54
|
+
{ text: token.value.gsub(' ', Prawn::Text::NBSP) }.merge(style)
|
|
55
|
+
}
|
|
56
|
+
fragments.each_with_object([]) do |fragment, fragments|
|
|
57
57
|
if fragments.empty?
|
|
58
58
|
fragments << fragment
|
|
59
|
-
elsif fragments.last.reject { |k, _| k == :text} == fragment.reject { |k, _| k == :text } ||
|
|
59
|
+
elsif fragments.last.reject { |k, _| k == :text } == fragment.reject { |k, _| k == :text } ||
|
|
60
|
+
fragment[:text].match?(/\A[#{Prawn::Text::NBSP}\s\t\r\n]*\z/o)
|
|
61
|
+
|
|
60
62
|
fragments.last[:text] << fragment[:text]
|
|
61
|
-
else
|
|
63
|
+
else # rubocop: disable Lint/DuplicateBranch
|
|
62
64
|
fragments << fragment
|
|
63
65
|
end
|
|
64
66
|
end
|
|
@@ -77,9 +79,8 @@ module Prawn
|
|
|
77
79
|
.map(&:first) # Only tokens
|
|
78
80
|
|
|
79
81
|
# Add a BOF token to be able to not miss the whitespace at the beginning
|
|
80
|
-
tokens.prepend(Prism::Token.new(:PRAWN_BOF, '', Prism::Location.new(result.source, 0, 0)))
|
|
82
|
+
tokens.prepend(Prism::Token.new(result.source, :PRAWN_BOF, '', Prism::Location.new(result.source, 0, 0)))
|
|
81
83
|
|
|
82
|
-
cursor = 0
|
|
83
84
|
# Add whitespace tokens
|
|
84
85
|
tokens
|
|
85
86
|
# Tokens are not sequential. Specifically, heredoc body is out of order.
|
|
@@ -87,18 +88,18 @@ module Prawn
|
|
|
87
88
|
.sort_by { |token| token.location.start_offset }
|
|
88
89
|
.each_cons(2)
|
|
89
90
|
.flat_map do |token, next_token|
|
|
90
|
-
if next_token.location.start_offset
|
|
91
|
+
if next_token.location.start_offset == token.location.end_offset
|
|
92
|
+
[token]
|
|
93
|
+
else
|
|
91
94
|
ws_location = Prism::Location.new(
|
|
92
95
|
result.source,
|
|
93
96
|
token.location.end_offset,
|
|
94
|
-
next_token.location.start_offset - token.location.end_offset
|
|
97
|
+
next_token.location.start_offset - token.location.end_offset,
|
|
95
98
|
)
|
|
96
99
|
[
|
|
97
100
|
token,
|
|
98
|
-
Prism::Token.new(:PRAWN_WHITESPACE, ws_location.slice, ws_location)
|
|
101
|
+
Prism::Token.new(result.source, :PRAWN_WHITESPACE, ws_location.slice, ws_location),
|
|
99
102
|
]
|
|
100
|
-
else
|
|
101
|
-
[token]
|
|
102
103
|
end
|
|
103
104
|
end
|
|
104
105
|
end
|
|
@@ -18,17 +18,19 @@ module Prawn
|
|
|
18
18
|
|
|
19
19
|
private
|
|
20
20
|
|
|
21
|
-
attr_reader :doc
|
|
21
|
+
attr_reader :doc
|
|
22
|
+
attr_reader :text
|
|
22
23
|
|
|
23
24
|
def header(str)
|
|
24
25
|
doc.font(HEADER_FONT, size: HEADER_FONT_SIZE) do
|
|
25
26
|
str.split(/\n\n+/).each do |paragraph|
|
|
26
27
|
doc.text(
|
|
27
|
-
paragraph.gsub(/\s+/,
|
|
28
|
+
paragraph.gsub(/\s+/, ' '),
|
|
28
29
|
align: :justify,
|
|
29
30
|
inline_format: true,
|
|
30
31
|
leading: LEADING,
|
|
31
|
-
color: DARK_GRAY
|
|
32
|
+
color: DARK_GRAY,
|
|
33
|
+
)
|
|
32
34
|
|
|
33
35
|
doc.move_down(RHYTHM)
|
|
34
36
|
end
|
|
@@ -47,27 +49,30 @@ module Prawn
|
|
|
47
49
|
doc.bounding_box(
|
|
48
50
|
[-doc.bounds.absolute_left, doc.cursor + PAGE_MARGIN],
|
|
49
51
|
width: doc.bounds.absolute_left + doc.bounds.absolute_right,
|
|
50
|
-
height: PAGE_MARGIN * 2 + text_height
|
|
52
|
+
height: (PAGE_MARGIN * 2) + text_height,
|
|
51
53
|
) do
|
|
52
54
|
doc.fill_color(LIGHT_GRAY)
|
|
53
55
|
doc.fill_rectangle(
|
|
54
56
|
[doc.bounds.left, doc.bounds.top],
|
|
55
57
|
doc.bounds.right,
|
|
56
|
-
doc.bounds.top - doc.bounds.bottom
|
|
58
|
+
doc.bounds.top - doc.bounds.bottom,
|
|
57
59
|
)
|
|
58
60
|
doc.fill_color(BLACK)
|
|
59
61
|
|
|
60
62
|
doc.bounding_box(
|
|
61
63
|
[PAGE_MARGIN + INNER_MARGIN, doc.bounds.top - PAGE_MARGIN],
|
|
62
|
-
width: doc.bounds.width - PAGE_MARGIN * 2 - INNER_MARGIN * 2,
|
|
63
|
-
height: text_height
|
|
64
|
+
width: doc.bounds.width - (PAGE_MARGIN * 2) - (INNER_MARGIN * 2),
|
|
65
|
+
height: text_height,
|
|
64
66
|
) do
|
|
65
67
|
doc.formatted_text(header_text, header_options)
|
|
66
68
|
end
|
|
67
69
|
end
|
|
68
70
|
|
|
69
71
|
doc.stroke_color(GRAY)
|
|
70
|
-
doc.stroke_horizontal_line(
|
|
72
|
+
doc.stroke_horizontal_line(
|
|
73
|
+
-doc.bounds.absolute_left, doc.bounds.width + doc.bounds.absolute_right,
|
|
74
|
+
at: doc.cursor,
|
|
75
|
+
)
|
|
71
76
|
doc.stroke_color(BLACK)
|
|
72
77
|
|
|
73
78
|
doc.move_down(RHYTHM * 3)
|
|
@@ -77,11 +82,12 @@ module Prawn
|
|
|
77
82
|
doc.font(TEXT_FONT, size: TEXT_FONT_SIZE) do
|
|
78
83
|
extra_markup(str).split(/\n\n+/).each do |paragraph|
|
|
79
84
|
doc.text(
|
|
80
|
-
paragraph.gsub(/\s+/,
|
|
85
|
+
paragraph.gsub(/\s+/, ' '),
|
|
81
86
|
align: :justify,
|
|
82
87
|
inline_format: true,
|
|
83
88
|
leading: LEADING,
|
|
84
|
-
color: DARK_GRAY
|
|
89
|
+
color: DARK_GRAY,
|
|
90
|
+
)
|
|
85
91
|
|
|
86
92
|
doc.move_down(RHYTHM)
|
|
87
93
|
end
|
|
@@ -93,7 +99,7 @@ module Prawn
|
|
|
93
99
|
def list(*items)
|
|
94
100
|
doc.move_up(RHYTHM)
|
|
95
101
|
|
|
96
|
-
doc.font(
|
|
102
|
+
doc.font('DejaVu', size: 11) do
|
|
97
103
|
items.each do |li|
|
|
98
104
|
doc.float { doc.text("\u2022", size: doc.font_size * 1.25) }
|
|
99
105
|
doc.indent(RHYTHM) do
|
|
@@ -101,7 +107,7 @@ module Prawn
|
|
|
101
107
|
extra_markup(li).gsub(/\s+/, ' '),
|
|
102
108
|
inline_format: true,
|
|
103
109
|
color: DARK_GRAY,
|
|
104
|
-
leading: LEADING
|
|
110
|
+
leading: LEADING,
|
|
105
111
|
)
|
|
106
112
|
end
|
|
107
113
|
|
|
@@ -115,7 +121,7 @@ module Prawn
|
|
|
115
121
|
def ordered_list(*items)
|
|
116
122
|
doc.move_up(RHYTHM)
|
|
117
123
|
|
|
118
|
-
doc.font(
|
|
124
|
+
doc.font('DejaVu', size: 11) do
|
|
119
125
|
counter_width = (1..items.size).to_a.map { |i| doc.width_of("#{i}.") }.max
|
|
120
126
|
space_width = doc.width_of(' ')
|
|
121
127
|
items.each_with_index do |li, i|
|
|
@@ -129,7 +135,7 @@ module Prawn
|
|
|
129
135
|
extra_markup(li).gsub(/\s+/, ' '),
|
|
130
136
|
inline_format: true,
|
|
131
137
|
color: DARK_GRAY,
|
|
132
|
-
leading: LEADING
|
|
138
|
+
leading: LEADING,
|
|
133
139
|
)
|
|
134
140
|
end
|
|
135
141
|
|
|
@@ -142,9 +148,10 @@ module Prawn
|
|
|
142
148
|
|
|
143
149
|
def extra_markup(str)
|
|
144
150
|
str
|
|
145
|
-
.gsub(
|
|
146
|
-
.gsub(URI::
|
|
147
|
-
|
|
151
|
+
.gsub(%r{<code>([^<]+?)</code>}, '<font name="Iosevka"><b>\1</b></font>') # Process the <code> tags
|
|
152
|
+
.gsub(URI::RFC2396_PARSER.make_regexp(%w[http https])) do |match|
|
|
153
|
+
# Process the links
|
|
154
|
+
%(<color rgb="#{BLUE}"><link href="#{match}">#{match.gsub('/', "/#{Prawn::Text::ZWSP}")}</link></color>)
|
|
148
155
|
end
|
|
149
156
|
end
|
|
150
157
|
end
|
data/lib/prawn/manual_builder.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Prawn
|
|
2
4
|
module ManualBuilder
|
|
3
|
-
DATADIR = File.
|
|
5
|
+
DATADIR = File.expand_path('../../data', __dir__)
|
|
4
6
|
NOT_SET = Object.new.freeze
|
|
5
7
|
|
|
6
8
|
# Values used for the manual design:
|
|
@@ -16,17 +18,17 @@ module Prawn
|
|
|
16
18
|
LEADING = 2
|
|
17
19
|
|
|
18
20
|
# Colors
|
|
19
|
-
BLACK =
|
|
20
|
-
LIGHT_GRAY =
|
|
21
|
-
GRAY =
|
|
22
|
-
DARK_GRAY =
|
|
23
|
-
BROWN =
|
|
24
|
-
ORANGE =
|
|
25
|
-
LIGHT_GOLD =
|
|
26
|
-
DARK_GOLD =
|
|
27
|
-
BLUE =
|
|
28
|
-
|
|
29
|
-
HEADER_FONT =
|
|
21
|
+
BLACK = '000000'
|
|
22
|
+
LIGHT_GRAY = 'F2F2F2'
|
|
23
|
+
GRAY = 'DDDDDD'
|
|
24
|
+
DARK_GRAY = '333333'
|
|
25
|
+
BROWN = 'A4441C'
|
|
26
|
+
ORANGE = 'F28157'
|
|
27
|
+
LIGHT_GOLD = 'FBFBBE'
|
|
28
|
+
DARK_GOLD = 'EBE389'
|
|
29
|
+
BLUE = '0000D0'
|
|
30
|
+
|
|
31
|
+
HEADER_FONT = 'DejaVu'
|
|
30
32
|
HEADER_FONT_SIZE = 18
|
|
31
33
|
|
|
32
34
|
CODE_FONT = 'Iosevka'
|
|
@@ -34,7 +36,10 @@ module Prawn
|
|
|
34
36
|
|
|
35
37
|
TEXT_FONT = 'DejaVu'
|
|
36
38
|
TEXT_FONT_SIZE = 10
|
|
39
|
+
|
|
40
|
+
class Error < StandardError
|
|
41
|
+
end
|
|
37
42
|
end
|
|
38
43
|
end
|
|
39
44
|
|
|
40
|
-
require_relative
|
|
45
|
+
require_relative 'manual_builder/manual'
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: prawn-manual_builder
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alexander Mankuta
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain:
|
|
11
10
|
- |
|
|
12
11
|
-----BEGIN CERTIFICATE-----
|
|
13
|
-
MIIC+
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
MIIC+jCCAeKgAwIBAgIBBDANBgkqhkiG9w0BAQsFADAjMSEwHwYDVQQDDBhhbGV4
|
|
13
|
+
L0RDPXBvaW50bGVzcy9EQz1vbmUwHhcNMjYwMTI4MTYxMjQyWhcNMjcwMTI4MTYx
|
|
14
|
+
MjQyWjAjMSEwHwYDVQQDDBhhbGV4L0RDPXBvaW50bGVzcy9EQz1vbmUwggEiMA0G
|
|
16
15
|
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPOVLPGEK+eaP6zJfifrpWvPTg4qo3
|
|
17
16
|
XNJJPom80SwqX2hVCVsRDK4RYgKUQqKRQzHhlx14wZHwWLETBVbNDGX3uqyCnTWU
|
|
18
17
|
JUKh3ydiZShXpNHoV/NW7hhEYvNsDcBAjYTmbvXOhuYCo0Tz/0N2Oiun/0wIICtP
|
|
@@ -20,14 +19,14 @@ cert_chain:
|
|
|
20
19
|
CughoB2xSwKX8gwbQ8fsnaZRmdyDGYNpz6sGF0zycfiLkTttbLA2nYATCALy98CH
|
|
21
20
|
nsyZNsTjb4WINCuY2yEDjwesw9f/ROkNC68EgQ5M+aMjp+D0WcYGfzojAgMBAAGj
|
|
22
21
|
OTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBRPgIwSVbeonua/
|
|
23
|
-
Ny/
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
Ny/8576oxdUbrjANBgkqhkiG9w0BAQsFAAOCAQEAJfmbANkMIQ/iPo+KShqeGQMy
|
|
23
|
+
LK8Xjs4GayLhBfg86b8ABSKy3ceXdq1rrflUeuMLJccUjLcb/uwDsI8QyDGZr98Z
|
|
24
|
+
y9M6UM06208DxLeTkVleil9dVc4NIppwrcUGbmDnj9pnXqJHi2dVwdolG7AcnNba
|
|
25
|
+
OvFWWQPEj5rKC5rOT23Sp2KBBpsW+LtyQ7lRk7ZD2+6m1JO/C5FhGa6K3vIobSdV
|
|
26
|
+
eaOD8BgDyA+inpftiavocKyheVKcguP+rO3ppATGrDHaoQTQzzDyMtKOqxI+pcP5
|
|
27
|
+
Ghw/wL48byl8XQlZD/XVLHXmT2t2ZKwSRaFE+srZbzdWCpxlmv5tdiPLe3DiFw==
|
|
29
28
|
-----END CERTIFICATE-----
|
|
30
|
-
date:
|
|
29
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
31
30
|
dependencies:
|
|
32
31
|
- !ruby/object:Gem::Dependency
|
|
33
32
|
name: prawn
|
|
@@ -49,14 +48,28 @@ dependencies:
|
|
|
49
48
|
requirements:
|
|
50
49
|
- - "~>"
|
|
51
50
|
- !ruby/object:Gem::Version
|
|
52
|
-
version:
|
|
51
|
+
version: '1.0'
|
|
53
52
|
type: :runtime
|
|
54
53
|
prerelease: false
|
|
55
54
|
version_requirements: !ruby/object:Gem::Requirement
|
|
56
55
|
requirements:
|
|
57
56
|
- - "~>"
|
|
58
57
|
- !ruby/object:Gem::Version
|
|
59
|
-
version:
|
|
58
|
+
version: '1.0'
|
|
59
|
+
- !ruby/object:Gem::Dependency
|
|
60
|
+
name: prawn-dev
|
|
61
|
+
requirement: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - "~>"
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: 0.6.0
|
|
66
|
+
type: :development
|
|
67
|
+
prerelease: false
|
|
68
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - "~>"
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: 0.6.0
|
|
60
73
|
description: A tool for writing manuals for Prawn and Prawn accessories
|
|
61
74
|
email:
|
|
62
75
|
- alex@pointless.one
|
|
@@ -88,13 +101,12 @@ files:
|
|
|
88
101
|
- lib/prawn/manual_builder/syntax_highlight.rb
|
|
89
102
|
- lib/prawn/manual_builder/text_renderer.rb
|
|
90
103
|
- lib/prawn/manual_builder/version.rb
|
|
91
|
-
homepage:
|
|
92
104
|
licenses:
|
|
93
105
|
- PRAWN
|
|
94
106
|
- GPL-2.0
|
|
95
107
|
- GPL-3.0
|
|
96
|
-
metadata:
|
|
97
|
-
|
|
108
|
+
metadata:
|
|
109
|
+
rubygems_mfa_required: 'true'
|
|
98
110
|
rdoc_options: []
|
|
99
111
|
require_paths:
|
|
100
112
|
- lib
|
|
@@ -109,8 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
109
121
|
- !ruby/object:Gem::Version
|
|
110
122
|
version: '0'
|
|
111
123
|
requirements: []
|
|
112
|
-
rubygems_version:
|
|
113
|
-
signing_key:
|
|
124
|
+
rubygems_version: 4.0.3
|
|
114
125
|
specification_version: 4
|
|
115
126
|
summary: A tool for writing manuals for Prawn and Prawn accessories
|
|
116
127
|
test_files: []
|
metadata.gz.sig
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
<���ڋu�u��K1�.���@�Fe���}�,�-B&P�L;�(�4���[�m�es�Ӭ��PAi6p�-�_��R&: 5�dqEZ�
|
|
2
|
+
p�t���0)l�sBi�c��R�e�&6�Ui�&/%n���l�Rٻ
|