asciidoctor-pdf 1.5.0.alpha.4 → 1.5.0.alpha.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +9 -1
- data/examples/edge-cases.adoc +60 -0
- data/lib/asciidoctor-pdf/asciidoctor_ext/section.rb +1 -1
- data/lib/asciidoctor-pdf/converter.rb +64 -31
- data/lib/asciidoctor-pdf/implicit_header_processor.rb +4 -0
- data/lib/asciidoctor-pdf/prawn_ext/extensions.rb +16 -10
- data/lib/asciidoctor-pdf/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ddd0f5ebfe16661dfd20e0ef1718ea6aaa7f9fb
|
4
|
+
data.tar.gz: 05a6512716b3f7f203c7ebb14e6774385eaca13a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83698c58c5acf41e3c38e8d0c4657afe51d2aa99001d2bc278a2faefa42227534d66353aa80760d0e6ab669c30b879384599025bf97c72da730878cef0655cbc
|
7
|
+
data.tar.gz: a30d39c1ae441ebe4a3e2042343b2a8bb75cbbac931a2e9d4622692283dc09d928195b9770b314b84e96cd92dc5f42c99ac870588e38c93d21ff7d494826c786
|
data/README.adoc
CHANGED
@@ -98,6 +98,11 @@ The {project-name} project is published in pre-release on RubyGems.org.
|
|
98
98
|
You can either install the pre-release version using the following command:
|
99
99
|
|
100
100
|
$ gem install --pre asciidoctor-pdf
|
101
|
+
|
102
|
+
If you want to syntax highlight source listings, you'll also want to install CodeRay or Pygments.
|
103
|
+
To be safe, go ahead and install both gems:
|
104
|
+
|
105
|
+
$ gem install coderay pygments.rb
|
101
106
|
|
102
107
|
Assuming all the required gems install properly, verify you can run the +asciidoctor-pdf+ script:
|
103
108
|
|
@@ -204,7 +209,10 @@ Converting to PDF is a simple as running the +./bin/asciidoctor-pdf+ script usin
|
|
204
209
|
$ ruby ./bin/asciidoctor-pdf example.adoc
|
205
210
|
|
206
211
|
When the script completes, you should see the file [file]_example.pdf_ in the same directory.
|
207
|
-
|
212
|
+
|
213
|
+
IMPORTANT: You'll need to the `coderay` gem installed to run this example since it uses the `source-highlighter` attribute with the value of `coderay`.
|
214
|
+
|
215
|
+
Open the [file]_example.pdf_ file with a PDF viewer to see the result.
|
208
216
|
|
209
217
|
.Example PDF document rendered in a PDF viewer
|
210
218
|
image::examples/example-pdf-screenshot.png[Screenshot of PDF document,width=800,scaledwidth=100%]
|
@@ -0,0 +1,60 @@
|
|
1
|
+
= Edge Cases
|
2
|
+
:doctype: book
|
3
|
+
|
4
|
+
== Long code listing
|
5
|
+
|
6
|
+
Here's a long listing block that spans multiple pages.
|
7
|
+
|
8
|
+
.Long listing
|
9
|
+
----
|
10
|
+
Line 1
|
11
|
+
Line 2
|
12
|
+
Line 3
|
13
|
+
Line 4
|
14
|
+
Line 5
|
15
|
+
Line 6
|
16
|
+
Line 7
|
17
|
+
Line 8
|
18
|
+
Line 9
|
19
|
+
Line 10
|
20
|
+
Line 11
|
21
|
+
Line 12
|
22
|
+
Line 13
|
23
|
+
Line 14
|
24
|
+
Line 15
|
25
|
+
Line 16
|
26
|
+
Line 17
|
27
|
+
Line 18
|
28
|
+
Line 19
|
29
|
+
Line 20
|
30
|
+
Line 21
|
31
|
+
Line 22
|
32
|
+
Line 23
|
33
|
+
Line 24
|
34
|
+
Line 25
|
35
|
+
Line 26
|
36
|
+
Line 27
|
37
|
+
Line 28
|
38
|
+
Line 29
|
39
|
+
Line 30
|
40
|
+
Line 31
|
41
|
+
Line 32
|
42
|
+
Line 33
|
43
|
+
Line 34
|
44
|
+
Line 35
|
45
|
+
Line 36
|
46
|
+
Line 37
|
47
|
+
Line 38
|
48
|
+
Line 39
|
49
|
+
Line 40
|
50
|
+
Line 41
|
51
|
+
Line 42
|
52
|
+
Line 43
|
53
|
+
Line 44
|
54
|
+
Line 45
|
55
|
+
Line 46
|
56
|
+
Line 47
|
57
|
+
Line 48
|
58
|
+
Line 49
|
59
|
+
Line 50
|
60
|
+
----
|
@@ -8,7 +8,7 @@ class Asciidoctor::Section
|
|
8
8
|
@is_numbered = true
|
9
9
|
@cached_numbered_title = %(#{sectnum} #{title})
|
10
10
|
@cached_formal_numbered_title = if slevel == 1 && @document.doctype == 'book'
|
11
|
-
%(Chapter #{@cached_numbered_title})
|
11
|
+
%(#{@document.attr 'chapter-label', 'Chapter'} #{@cached_numbered_title}).lstrip
|
12
12
|
else
|
13
13
|
@cached_numbered_title
|
14
14
|
end
|
@@ -8,14 +8,9 @@ require 'prawn/templates'
|
|
8
8
|
require_relative 'prawn_ext'
|
9
9
|
require_relative 'pdfmarks'
|
10
10
|
require_relative 'asciidoctor_ext'
|
11
|
-
require_relative 'implicit_header_processor'
|
12
11
|
require_relative 'theme_loader'
|
13
12
|
require_relative 'roman_numeral'
|
14
13
|
|
15
|
-
Asciidoctor::Extensions.register :pdf do
|
16
|
-
include_processor Asciidoctor::Pdf::ImplicitHeaderProcessor if @document.backend == 'pdf'
|
17
|
-
end
|
18
|
-
|
19
14
|
module Asciidoctor
|
20
15
|
module Pdf
|
21
16
|
class Converter < ::Prawn::Document
|
@@ -109,19 +104,33 @@ class Converter < ::Prawn::Document
|
|
109
104
|
layout_title_page doc
|
110
105
|
|
111
106
|
start_new_page
|
107
|
+
|
108
|
+
toc_start_page_num = page_number
|
109
|
+
num_toc_levels = (doc.attr 'toclevels', 2).to_i
|
110
|
+
if doc.attr? 'toc'
|
111
|
+
toc_page_nums = ()
|
112
|
+
dry_run do
|
113
|
+
toc_page_nums = layout_toc doc, num_toc_levels, 1
|
114
|
+
end
|
115
|
+
# reserve pages for the toc
|
116
|
+
toc_page_nums.each do
|
117
|
+
start_new_page
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
num_front_matter_pages = page_number - 1
|
112
122
|
font @theme.base_font_family, size: @theme.base_font_size
|
113
123
|
convert_content_for_block doc
|
114
124
|
|
115
|
-
num_toc_levels = (doc.attr 'toclevels', 2).to_i
|
116
125
|
toc_page_nums = if doc.attr? 'toc'
|
117
|
-
layout_toc doc, num_toc_levels
|
126
|
+
layout_toc doc, num_toc_levels, toc_start_page_num, num_front_matter_pages
|
118
127
|
else
|
119
128
|
(0..-1)
|
120
129
|
end
|
121
130
|
|
122
131
|
# TODO enable pagenums by default (perhaps upstream?)
|
123
|
-
stamp_page_numbers skip:
|
124
|
-
add_outline doc, num_toc_levels, toc_page_nums
|
132
|
+
stamp_page_numbers skip: num_front_matter_pages if doc.attr 'pagenums'
|
133
|
+
add_outline doc, num_toc_levels, toc_page_nums, num_front_matter_pages
|
125
134
|
catalog.data[:ViewerPreferences] = [:FitWindow]
|
126
135
|
|
127
136
|
layout_cover_page :back, doc
|
@@ -665,8 +674,18 @@ class Converter < ::Prawn::Document
|
|
665
674
|
theme_font :code do
|
666
675
|
if box_height
|
667
676
|
float do
|
668
|
-
|
669
|
-
|
677
|
+
# FIXME don't use border / border radius at page boundaries
|
678
|
+
# TODO move this logic to theme_fill_and_stroke_bounds
|
679
|
+
remaining_height = box_height - caption_height
|
680
|
+
i = 0
|
681
|
+
while remaining_height > 0
|
682
|
+
start_new_page if i > 0
|
683
|
+
fill_height = [remaining_height, cursor].min
|
684
|
+
bounding_box [0, cursor], width: bounds.width, height: fill_height do
|
685
|
+
theme_fill_and_stroke_bounds :code
|
686
|
+
end
|
687
|
+
remaining_height -= fill_height
|
688
|
+
i += 1
|
670
689
|
end
|
671
690
|
end
|
672
691
|
end
|
@@ -1074,37 +1093,44 @@ class Converter < ::Prawn::Document
|
|
1074
1093
|
end
|
1075
1094
|
end
|
1076
1095
|
|
1077
|
-
def layout_toc doc, num_levels = 2, toc_page_number = 2
|
1078
|
-
go_to_page toc_page_number
|
1079
|
-
start_new_page
|
1096
|
+
def layout_toc doc, num_levels = 2, toc_page_number = 2, num_front_matter_pages = 0
|
1097
|
+
go_to_page toc_page_number unless scratch? || page_number == toc_page_number
|
1080
1098
|
theme_font :heading, level: 2 do
|
1081
1099
|
layout_heading doc.attr('toc-title')
|
1082
1100
|
end
|
1083
1101
|
line_metrics = calc_line_metrics @theme.base_line_height
|
1084
1102
|
dot_width = width_of DotLeader
|
1085
1103
|
if num_levels > 0
|
1086
|
-
layout_toc_level doc.sections, num_levels, line_metrics, dot_width
|
1104
|
+
layout_toc_level doc.sections, num_levels, line_metrics, dot_width, num_front_matter_pages
|
1087
1105
|
end
|
1088
1106
|
toc_page_numbers = (toc_page_number..page_number)
|
1089
|
-
go_to_page page_count - 1
|
1107
|
+
go_to_page page_count - 1 unless scratch?
|
1090
1108
|
toc_page_numbers
|
1091
1109
|
end
|
1092
1110
|
|
1093
|
-
def layout_toc_level sections, num_levels, line_metrics, dot_width
|
1111
|
+
def layout_toc_level sections, num_levels, line_metrics, dot_width, num_front_matter_pages = 0
|
1094
1112
|
sections.each do |sect|
|
1095
1113
|
sect_title = sect.numbered_title
|
1096
|
-
|
1097
|
-
|
1114
|
+
# NOTE we do some cursor hacking here so the dots don't affect vertical alignment
|
1115
|
+
start_page_number = page_number
|
1098
1116
|
start_cursor = cursor
|
1099
1117
|
typeset_text %(<link anchor="#{sect.id}">#{sect_title}</link>), line_metrics, inline_format: true
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1118
|
+
# we only write the label if this is a dry run
|
1119
|
+
unless scratch?
|
1120
|
+
end_page_number = page_number
|
1121
|
+
end_cursor = cursor
|
1122
|
+
# TODO it would be convenient to have a cursor mark / placement utility that took page number into account
|
1123
|
+
go_to_page start_page_number if start_page_number != end_page_number
|
1124
|
+
move_cursor_to start_cursor
|
1125
|
+
sect_page_num = (sect.attr 'page_start') - num_front_matter_pages
|
1126
|
+
num_dots = ((bounds.width - (width_of %(#{sect_title} #{sect_page_num}), inline_format: true)) / dot_width).floor
|
1127
|
+
typeset_formatted_text [text: %(#{DotLeader * num_dots} #{sect_page_num}), anchor: sect.id], line_metrics, align: :right
|
1128
|
+
go_to_page end_page_number if start_page_number != end_page_number
|
1129
|
+
move_cursor_to end_cursor
|
1130
|
+
end
|
1105
1131
|
if sect.level < num_levels
|
1106
1132
|
indent @theme.horizontal_rhythm do
|
1107
|
-
layout_toc_level sect.sections, num_levels, line_metrics, dot_width
|
1133
|
+
layout_toc_level sect.sections, num_levels, line_metrics, dot_width, num_front_matter_pages
|
1108
1134
|
end
|
1109
1135
|
end
|
1110
1136
|
end
|
@@ -1145,13 +1171,20 @@ class Converter < ::Prawn::Document
|
|
1145
1171
|
end
|
1146
1172
|
|
1147
1173
|
# FIXME we are assuming we always have exactly one title page
|
1148
|
-
def add_outline doc, num_levels = 2, toc_page_nums = (0..-1)
|
1174
|
+
def add_outline doc, num_levels = 2, toc_page_nums = (0..-1), num_front_matter_pages = 0
|
1149
1175
|
front_matter_counter = RomanNumeral.new 0, :lower
|
1150
1176
|
|
1151
1177
|
page_num_labels = {}
|
1152
1178
|
|
1179
|
+
# FIXME account for cover page
|
1180
|
+
# cover page (i)
|
1181
|
+
#front_matter_counter.next!
|
1182
|
+
|
1153
1183
|
# title page (i)
|
1154
|
-
|
1184
|
+
# TODO same conditional logic as in layout_title_page; consolidate
|
1185
|
+
if doc.header? && !doc.noheader && !doc.notitle
|
1186
|
+
page_num_labels[0] = { P: ::PDF::Core::LiteralString.new(front_matter_counter.next!.to_s) }
|
1187
|
+
end
|
1155
1188
|
|
1156
1189
|
# toc pages (ii..?)
|
1157
1190
|
toc_page_nums.each do
|
@@ -1173,7 +1206,7 @@ class Converter < ::Prawn::Document
|
|
1173
1206
|
end
|
1174
1207
|
#page title: 'Credits', destination: (document.dest_top toc_page_nums.first + 1)
|
1175
1208
|
# QUESTION any way to get add_outline_level to invoke in the context of the outline?
|
1176
|
-
document.add_outline_level self, doc.sections, num_levels, page_num_labels, numbering_offset
|
1209
|
+
document.add_outline_level self, doc.sections, num_levels, page_num_labels, numbering_offset, num_front_matter_pages
|
1177
1210
|
end
|
1178
1211
|
|
1179
1212
|
catalog.data[:PageLabels] = state.store.ref Nums: page_num_labels.flatten
|
@@ -1182,17 +1215,17 @@ class Converter < ::Prawn::Document
|
|
1182
1215
|
end
|
1183
1216
|
|
1184
1217
|
# TODO only nest inside root node if doctype=article
|
1185
|
-
def add_outline_level outline, sections, num_levels, page_num_labels, numbering_offset
|
1218
|
+
def add_outline_level outline, sections, num_levels, page_num_labels, numbering_offset, num_front_matter_pages
|
1186
1219
|
sections.each do |sect|
|
1187
1220
|
sect_title = sanitize(sect.numbered_title formal: true)
|
1188
1221
|
sect_destination = sect.attr 'destination'
|
1189
|
-
sect_page_num = (sect.attr 'page_start') -
|
1222
|
+
sect_page_num = (sect.attr 'page_start') - num_front_matter_pages
|
1190
1223
|
page_num_labels[sect_page_num + numbering_offset] = { P: ::PDF::Core::LiteralString.new(sect_page_num.to_s) }
|
1191
1224
|
if (subsections = sect.sections).empty? || sect.level == num_levels
|
1192
1225
|
outline.page title: sect_title, destination: sect_destination
|
1193
1226
|
elsif sect.level < num_levels + 1
|
1194
1227
|
outline.section sect_title, { destination: sect_destination } do
|
1195
|
-
add_outline_level outline, subsections, num_levels, page_num_labels, numbering_offset
|
1228
|
+
add_outline_level outline, subsections, num_levels, page_num_labels, numbering_offset, num_front_matter_pages
|
1196
1229
|
end
|
1197
1230
|
end
|
1198
1231
|
end
|
@@ -480,14 +480,13 @@ module Extensions
|
|
480
480
|
def dry_run &block
|
481
481
|
scratch = get_scratch_document
|
482
482
|
scratch.start_new_page
|
483
|
+
start_page_number = scratch.page_number
|
483
484
|
start_y = scratch.y
|
484
485
|
scratch.font font_family, style: font_style, size: font_size do
|
485
486
|
scratch.instance_exec(&block)
|
486
487
|
end
|
487
|
-
|
488
|
-
|
489
|
-
#scratch.render_file 'scratch.pdf'
|
490
|
-
#height_of_content
|
488
|
+
whole_pages = scratch.page_number - start_page_number
|
489
|
+
[(whole_pages * bounds.height + (start_y - scratch.y)), whole_pages, (start_y - scratch.y)]
|
491
490
|
end
|
492
491
|
|
493
492
|
# Attempt to keep the objects generated in the block on the same page
|
@@ -495,15 +494,17 @@ module Extensions
|
|
495
494
|
# TODO short-circuit nested usage
|
496
495
|
def keep_together &block
|
497
496
|
available_space = cursor
|
498
|
-
|
499
|
-
|
497
|
+
total_height, _whole_pages, _remainder = dry_run(&block)
|
498
|
+
if total_height > available_space
|
500
499
|
start_new_page
|
500
|
+
started_new_page = true
|
501
501
|
else
|
502
502
|
started_new_page = false
|
503
503
|
end
|
504
|
+
|
504
505
|
# HACK yield doesn't work here on JRuby (at least not when called from AsciidoctorJ)
|
505
|
-
#yield
|
506
|
-
instance_exec(
|
506
|
+
#yield remainder, started_new_page
|
507
|
+
instance_exec(total_height, started_new_page, &block)
|
507
508
|
end
|
508
509
|
|
509
510
|
# Attempt to keep the objects generated in the block on the same page
|
@@ -517,15 +518,20 @@ module Extensions
|
|
517
518
|
end
|
518
519
|
end
|
519
520
|
|
521
|
+
=begin
|
520
522
|
def run_with_trial &block
|
521
523
|
available_space = cursor
|
522
|
-
|
524
|
+
whole_pages, remainder = dry_run(&block)
|
525
|
+
if whole_pages > 0 || remainder > available_space
|
523
526
|
started_new_page = true
|
524
527
|
else
|
525
528
|
started_new_page = false
|
526
529
|
end
|
527
|
-
yield
|
530
|
+
# HACK yield doesn't work here on JRuby (at least not when called from AsciidoctorJ)
|
531
|
+
#yield remainder, started_new_page
|
532
|
+
instance_exec(remainder, started_new_page, &block)
|
528
533
|
end
|
534
|
+
=end
|
529
535
|
end
|
530
536
|
end
|
531
537
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asciidoctor-pdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.0.alpha.
|
4
|
+
version: 1.5.0.alpha.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Allen
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-09-
|
12
|
+
date: 2014-09-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -149,6 +149,7 @@ files:
|
|
149
149
|
- data/themes/default-theme.yml
|
150
150
|
- examples/chronicles.adoc
|
151
151
|
- examples/chronicles.pdf
|
152
|
+
- examples/edge-cases.adoc
|
152
153
|
- examples/example-pdf-screenshot.png
|
153
154
|
- examples/example.adoc
|
154
155
|
- examples/example.pdf
|