asciidoctor-pdf 1.5.0.beta.1 → 1.5.0.beta.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +26 -0
- data/README.adoc +2 -2
- data/asciidoctor-pdf.gemspec +3 -3
- data/bin/asciidoctor-pdf +1 -0
- data/data/fonts/ABOUT-mplus1mn-subset +24 -0
- data/data/fonts/ABOUT-mplus1p-subset +25 -0
- data/data/fonts/ABOUT-notoserif-subset +25 -0
- data/data/fonts/{LICENSE-mplus-testflight-58 → LICENSE-mplus} +2 -2
- data/data/fonts/{LICENSE-noto-2015-06-05 → LICENSE-notoserif} +0 -0
- data/data/fonts/mplus1mn-bold-ascii.ttf +0 -0
- data/data/fonts/mplus1mn-bold-subset.ttf +0 -0
- data/data/fonts/mplus1mn-bold_italic-ascii.ttf +0 -0
- data/data/fonts/mplus1mn-bold_italic-subset.ttf +0 -0
- data/data/fonts/mplus1mn-italic-ascii.ttf +0 -0
- data/data/fonts/mplus1mn-italic-subset.ttf +0 -0
- data/data/fonts/mplus1mn-regular-ascii-conums.ttf +0 -0
- data/data/fonts/mplus1mn-regular-subset.ttf +0 -0
- data/data/fonts/mplus1p-regular-fallback.ttf +0 -0
- data/data/fonts/notoserif-bold-subset.ttf +0 -0
- data/data/fonts/notoserif-bold_italic-subset.ttf +0 -0
- data/data/fonts/notoserif-italic-subset.ttf +0 -0
- data/data/fonts/notoserif-regular-subset.ttf +0 -0
- data/data/themes/base-theme.yml +8 -1
- data/data/themes/default-theme.yml +22 -7
- data/data/themes/default-with-fallback-font-theme.yml +4 -4
- data/docs/theming-guide.adoc +459 -44
- data/lib/asciidoctor-pdf.rb +1 -0
- data/lib/asciidoctor-pdf/asciidoctor_ext.rb +1 -0
- data/lib/asciidoctor-pdf/asciidoctor_ext/abstract_block.rb +1 -0
- data/lib/asciidoctor-pdf/asciidoctor_ext/document.rb +1 -0
- data/lib/asciidoctor-pdf/asciidoctor_ext/image.rb +1 -0
- data/lib/asciidoctor-pdf/asciidoctor_ext/list.rb +1 -0
- data/lib/asciidoctor-pdf/asciidoctor_ext/list_item.rb +1 -0
- data/lib/asciidoctor-pdf/asciidoctor_ext/logging_shim.rb +1 -0
- data/lib/asciidoctor-pdf/asciidoctor_ext/section.rb +1 -0
- data/lib/asciidoctor-pdf/converter.rb +227 -137
- data/lib/asciidoctor-pdf/core_ext.rb +1 -0
- data/lib/asciidoctor-pdf/core_ext/array.rb +1 -0
- data/lib/asciidoctor-pdf/core_ext/hash.rb +1 -0
- data/lib/asciidoctor-pdf/core_ext/numeric.rb +1 -0
- data/lib/asciidoctor-pdf/core_ext/object.rb +1 -0
- data/lib/asciidoctor-pdf/core_ext/quantifiable_stdout.rb +1 -0
- data/lib/asciidoctor-pdf/core_ext/regexp.rb +1 -0
- data/lib/asciidoctor-pdf/core_ext/string.rb +1 -0
- data/lib/asciidoctor-pdf/formatted_text.rb +1 -0
- data/lib/asciidoctor-pdf/formatted_text/formatter.rb +1 -0
- data/lib/asciidoctor-pdf/formatted_text/inline_destination_marker.rb +1 -0
- data/lib/asciidoctor-pdf/formatted_text/inline_image_arranger.rb +2 -1
- data/lib/asciidoctor-pdf/formatted_text/inline_image_renderer.rb +1 -0
- data/lib/asciidoctor-pdf/formatted_text/inline_text_aligner.rb +1 -0
- data/lib/asciidoctor-pdf/formatted_text/parser.rb +19 -6
- data/lib/asciidoctor-pdf/formatted_text/parser.treetop +2 -3
- data/lib/asciidoctor-pdf/formatted_text/text_background_and_border_renderer.rb +1 -0
- data/lib/asciidoctor-pdf/formatted_text/transform.rb +51 -3
- data/lib/asciidoctor-pdf/implicit_header_processor.rb +1 -0
- data/lib/asciidoctor-pdf/index_catalog.rb +1 -0
- data/lib/asciidoctor-pdf/measurements.rb +1 -0
- data/lib/asciidoctor-pdf/pdf-core_ext.rb +1 -0
- data/lib/asciidoctor-pdf/pdf-core_ext/page.rb +26 -0
- data/lib/asciidoctor-pdf/pdf-core_ext/pdf_object.rb +1 -0
- data/lib/asciidoctor-pdf/pdfmark.rb +1 -0
- data/lib/asciidoctor-pdf/prawn-svg_ext.rb +1 -0
- data/lib/asciidoctor-pdf/prawn-svg_ext/interface.rb +1 -0
- data/lib/asciidoctor-pdf/prawn-table_ext.rb +1 -0
- data/lib/asciidoctor-pdf/prawn-table_ext/cell.rb +1 -0
- data/lib/asciidoctor-pdf/prawn-table_ext/cell/asciidoc.rb +1 -0
- data/lib/asciidoctor-pdf/prawn-table_ext/cell/text.rb +1 -0
- data/lib/asciidoctor-pdf/prawn-templates_ext.rb +1 -0
- data/lib/asciidoctor-pdf/prawn_ext.rb +1 -0
- data/lib/asciidoctor-pdf/prawn_ext/coderay_encoder.rb +6 -5
- data/lib/asciidoctor-pdf/prawn_ext/extensions.rb +11 -17
- data/lib/asciidoctor-pdf/prawn_ext/font/afm.rb +15 -8
- data/lib/asciidoctor-pdf/prawn_ext/formatted_text/fragment.rb +1 -0
- data/lib/asciidoctor-pdf/prawn_ext/images.rb +2 -1
- data/lib/asciidoctor-pdf/roman_numeral.rb +1 -0
- data/lib/asciidoctor-pdf/rouge_ext.rb +1 -0
- data/lib/asciidoctor-pdf/rouge_ext/formatters/prawn.rb +1 -0
- data/lib/asciidoctor-pdf/rouge_ext/themes/asciidoctor_pdf_default.rb +1 -0
- data/lib/asciidoctor-pdf/rouge_ext/themes/bw.rb +1 -0
- data/lib/asciidoctor-pdf/sanitizer.rb +1 -0
- data/lib/asciidoctor-pdf/temporary_path.rb +1 -0
- data/lib/asciidoctor-pdf/theme_loader.rb +13 -13
- data/lib/asciidoctor-pdf/ttfunk_ext.rb +1 -0
- data/lib/asciidoctor-pdf/version.rb +2 -1
- data/lib/asciidoctor/pdf.rb +1 -0
- data/lib/asciidoctor/pdf/version.rb +1 -0
- metadata +15 -15
- data/lib/asciidoctor-pdf/core_ext/ostruct.rb +0 -8
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Asciidoctor::PDF::FormattedText
|
2
3
|
module InlineImageArranger
|
3
4
|
include ::Asciidoctor::PDF::Measurements
|
@@ -66,7 +67,7 @@ module InlineImageArranger
|
|
66
67
|
svg_obj = ::Prawn::SVG::Interface.new ::File.read(image_path), doc,
|
67
68
|
at: doc.bounds.top_left,
|
68
69
|
width: image_w,
|
69
|
-
fallback_font_name: doc.
|
70
|
+
fallback_font_name: doc.fallback_svg_font_name,
|
70
71
|
enable_web_requests: doc.allow_uri_read,
|
71
72
|
enable_file_requests_with_root: (::File.dirname image_path)
|
72
73
|
svg_size = image_w ? svg_obj.document.sizing :
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# regenerate parser.rb using `tt parser.treetop`
|
2
3
|
# Autogenerated from a Treetop grammar. Edits may be lost.
|
3
4
|
|
@@ -433,11 +434,11 @@ module Markup
|
|
433
434
|
r8 = SyntaxNode.new(input, (index-1)...index) if r8 == true
|
434
435
|
r0 = r8
|
435
436
|
else
|
436
|
-
if (match_len = has_terminal?('
|
437
|
+
if (match_len = has_terminal?('key', false, index))
|
437
438
|
r9 = instantiate_node(SyntaxNode,input, index...(index + match_len))
|
438
439
|
@index += match_len
|
439
440
|
else
|
440
|
-
terminal_parse_failure('
|
441
|
+
terminal_parse_failure('key')
|
441
442
|
r9 = nil
|
442
443
|
end
|
443
444
|
if r9
|
@@ -455,19 +456,31 @@ module Markup
|
|
455
456
|
r10 = SyntaxNode.new(input, (index-1)...index) if r10 == true
|
456
457
|
r0 = r10
|
457
458
|
else
|
458
|
-
if (match_len = has_terminal?('
|
459
|
+
if (match_len = has_terminal?('sub', false, index))
|
459
460
|
r11 = instantiate_node(SyntaxNode,input, index...(index + match_len))
|
460
461
|
@index += match_len
|
461
462
|
else
|
462
|
-
terminal_parse_failure('
|
463
|
+
terminal_parse_failure('sub')
|
463
464
|
r11 = nil
|
464
465
|
end
|
465
466
|
if r11
|
466
467
|
r11 = SyntaxNode.new(input, (index-1)...index) if r11 == true
|
467
468
|
r0 = r11
|
468
469
|
else
|
469
|
-
|
470
|
-
|
470
|
+
if (match_len = has_terminal?('del', false, index))
|
471
|
+
r12 = instantiate_node(SyntaxNode,input, index...(index + match_len))
|
472
|
+
@index += match_len
|
473
|
+
else
|
474
|
+
terminal_parse_failure('del')
|
475
|
+
r12 = nil
|
476
|
+
end
|
477
|
+
if r12
|
478
|
+
r12 = SyntaxNode.new(input, (index-1)...index) if r12 == true
|
479
|
+
r0 = r12
|
480
|
+
else
|
481
|
+
@index = i0
|
482
|
+
r0 = nil
|
483
|
+
end
|
471
484
|
end
|
472
485
|
end
|
473
486
|
end
|
@@ -49,9 +49,8 @@ grammar Markup
|
|
49
49
|
|
50
50
|
rule tag_name
|
51
51
|
# QUESTION faster to do regex?
|
52
|
-
# QUESTION
|
53
|
-
|
54
|
-
'a' / 'strong' / 'em' / 'code' / 'color' / 'font' / 'span' / 'button' / 'sub' / 'sup' / 'del'
|
52
|
+
# QUESTION what about supporting hr?
|
53
|
+
'a' / 'strong' / 'em' / 'code' / 'color' / 'font' / 'span' / 'button' / 'key' / 'sup' / 'sub' / 'del'
|
55
54
|
end
|
56
55
|
|
57
56
|
rule void_tag_name
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Asciidoctor
|
2
3
|
module PDF
|
3
4
|
module FormattedText
|
@@ -14,6 +15,12 @@ class Transform
|
|
14
15
|
}
|
15
16
|
CharRefRx = /&(?:(#{CharEntityTable.keys * ?|})|#(?:(\d\d\d{0,4})|x([a-f\d][a-f\d][a-f\d]{0,3})));/
|
16
17
|
TextDecorationTable = { 'underline' => :underline, 'line-through' => :strikethrough }
|
18
|
+
ThemeKeyToFragmentProperty = {
|
19
|
+
'font_color' => :color,
|
20
|
+
'font_family' => :font,
|
21
|
+
'font_size' => :size,
|
22
|
+
'font_style' => :styles,
|
23
|
+
}
|
17
24
|
#DummyText = ?\u0000
|
18
25
|
|
19
26
|
def initialize(options = {})
|
@@ -45,18 +52,57 @@ class Transform
|
|
45
52
|
border_radius: monospaced_bg_or_border && theme.literal_border_radius,
|
46
53
|
callback: monospaced_bg_or_border && [TextBackgroundAndBorderRenderer],
|
47
54
|
}.compact,
|
55
|
+
key: {
|
56
|
+
color: theme.key_font_color,
|
57
|
+
font: theme.key_font_family || theme.literal_font_family,
|
58
|
+
size: theme.key_font_size,
|
59
|
+
styles: to_styles(theme.key_font_style),
|
60
|
+
background_color: (key_bg_color = theme.key_background_color),
|
61
|
+
border_width: (key_border_width = theme.key_border_width),
|
62
|
+
border_color: key_border_width && (theme.key_border_color || theme.base_border_color),
|
63
|
+
border_offset: (key_bg_or_border = key_bg_color || key_border_width) && theme.key_border_offset,
|
64
|
+
border_radius: key_bg_or_border && theme.key_border_radius,
|
65
|
+
callback: key_bg_or_border && [TextBackgroundAndBorderRenderer],
|
66
|
+
}.compact,
|
48
67
|
link: {
|
49
68
|
color: theme.link_font_color,
|
50
69
|
font: theme.link_font_family,
|
51
70
|
size: theme.link_font_size,
|
52
|
-
styles: to_styles(theme.link_font_style, theme.link_text_decoration)
|
71
|
+
styles: to_styles(theme.link_font_style, theme.link_text_decoration),
|
53
72
|
}.compact,
|
54
73
|
}
|
74
|
+
theme.each_pair.reduce @theme_settings do |accum, (key, val)|
|
75
|
+
if (key = key.to_s).start_with? 'role_'
|
76
|
+
role, key = (key.slice 5, key.length).split '_', 2
|
77
|
+
if (prop = ThemeKeyToFragmentProperty[key])
|
78
|
+
val = to_styles val if prop == :styles
|
79
|
+
(accum[role] ||= {})[prop] = val
|
80
|
+
end
|
81
|
+
end
|
82
|
+
accum
|
83
|
+
end
|
84
|
+
unless @theme_settings.key? 'big'
|
85
|
+
if (base_font_size_large = theme.base_font_size_large)
|
86
|
+
@theme_settings['big'] = { size: %(#{(base_font_size_large / theme.base_font_size.to_f).round 4}em) }
|
87
|
+
else
|
88
|
+
@theme_settings['big'] = { size: '1.1667em' }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
unless @theme_settings.key? 'small'
|
92
|
+
if (base_font_size_small = theme.base_font_size_small)
|
93
|
+
@theme_settings['small'] = { size: %(#{(base_font_size_small / theme.base_font_size.to_f).round 4}em) }
|
94
|
+
else
|
95
|
+
@theme_settings['small'] = { size: '0.8333em' }
|
96
|
+
end
|
97
|
+
end
|
55
98
|
else
|
56
99
|
@theme_settings = {
|
57
100
|
button: { font: 'Courier', styles: [:bold].to_set },
|
58
|
-
code: { font: 'Courier'
|
101
|
+
code: { font: 'Courier' },
|
102
|
+
key: { font: 'Courier', styles: [:italic].to_set },
|
59
103
|
link: { color: '0000FF' },
|
104
|
+
'big' => { size: '1.667em' },
|
105
|
+
'small' => { size: '0.8333em' },
|
60
106
|
}
|
61
107
|
end
|
62
108
|
end
|
@@ -146,7 +192,7 @@ class Transform
|
|
146
192
|
styles << :bold
|
147
193
|
when :em
|
148
194
|
styles << :italic
|
149
|
-
when :code, :button
|
195
|
+
when :code, :button, :key
|
150
196
|
# NOTE prefer old value, except for styles and callback, which should be combined
|
151
197
|
fragment.update(@theme_settings[tag_name]) {|k, oval, nval| k == :styles ? oval.merge(nval) : (k == :callback ? oval.union(nval) : oval) }
|
152
198
|
when :color
|
@@ -265,6 +311,8 @@ class Transform
|
|
265
311
|
styles << :underline
|
266
312
|
when 'line-through'
|
267
313
|
styles << :strikethrough
|
314
|
+
else
|
315
|
+
fragment.update(@theme_settings[class_name]) {|k, oval, nval| k == :styles ? oval.merge(nval) : oval } if @theme_settings.key? class_name
|
268
316
|
end
|
269
317
|
end if attrs.key?(:class)
|
270
318
|
fragment.delete(:styles) if styles.empty?
|
@@ -1,4 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
class PDF::Core::Page
|
3
|
+
InitialPageContent = %(q\n)
|
4
|
+
|
2
5
|
# Restore the new_content_stream method from PDF::Core::Page
|
3
6
|
#
|
4
7
|
# The prawn-templates gem relies on the new_content_stream method on
|
@@ -22,4 +25,27 @@ class PDF::Core::Page
|
|
22
25
|
def imported_page?
|
23
26
|
@imported_page
|
24
27
|
end unless method_defined? :imported_page?
|
28
|
+
|
29
|
+
# Record the page's current state as the tare content stream (i.e., empty, meaning no content has been written).
|
30
|
+
def tare_content_stream
|
31
|
+
@tare_content_stream = content.stream.filtered_stream
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns whether the current page is empty based on tare content stream (i.e., no content has been written).
|
35
|
+
# Returns false if a page has not yet been created.
|
36
|
+
def empty?
|
37
|
+
content.stream.filtered_stream == (@tare_content_stream ||= InitialPageContent) && document.page_number > 0
|
38
|
+
end
|
39
|
+
|
40
|
+
# Reset the content of the page.
|
41
|
+
# Note that this method may leave behind an orphaned background image.
|
42
|
+
def reset_content
|
43
|
+
unless content.stream.filtered_stream == InitialPageContent
|
44
|
+
resources[:XObject].clear
|
45
|
+
new_content = document.state.store[document.ref({})]
|
46
|
+
new_content << 'q' << ?\n
|
47
|
+
content.replace new_content
|
48
|
+
@tare_content_stream = InitialPageContent
|
49
|
+
end
|
50
|
+
end
|
25
51
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
######################################################################
|
2
3
|
#
|
3
4
|
# This file was copied from Prawn (manual/syntax_highlight.rb) and
|
@@ -68,11 +69,11 @@ class CodeRayEncoder < ::CodeRay::Encoders::Encoder
|
|
68
69
|
value: '336600'
|
69
70
|
}
|
70
71
|
|
71
|
-
LF =
|
72
|
-
NoBreakSpace =
|
73
|
-
InnerIndent =
|
74
|
-
GuardedIndent =
|
75
|
-
GuardedInnerIndent =
|
72
|
+
LF = ?\n
|
73
|
+
NoBreakSpace = ?\u00a0
|
74
|
+
InnerIndent = LF + ' '
|
75
|
+
GuardedIndent = ?\u00a0
|
76
|
+
GuardedInnerIndent = LF + GuardedIndent
|
76
77
|
|
77
78
|
def setup options
|
78
79
|
super
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
Prawn::Font::AFM.instance_variable_set :@hide_m17n_warning, true
|
2
3
|
|
3
4
|
require 'prawn/icon'
|
@@ -141,17 +142,6 @@ module Extensions
|
|
141
142
|
@y == @margin_box.absolute_top
|
142
143
|
end
|
143
144
|
|
144
|
-
# Returns whether the current page is empty (i.e., no content has been written).
|
145
|
-
# Returns false if a page has not yet been created.
|
146
|
-
#
|
147
|
-
def empty_page?
|
148
|
-
# if we are at the page top, assume we didn't write anything to the page
|
149
|
-
#at_page_top?
|
150
|
-
# ...or use more robust, low-level check (initial value of content is "q\n")
|
151
|
-
page_number > 0 && page.content.stream.filtered_stream == InitialPageContent
|
152
|
-
end
|
153
|
-
alias page_is_empty? empty_page?
|
154
|
-
|
155
145
|
# Returns whether the current page is the last page in the document.
|
156
146
|
#
|
157
147
|
def last_page?
|
@@ -313,6 +303,10 @@ module Extensions
|
|
313
303
|
::Prawn::Icon::FontData.load self, family
|
314
304
|
end
|
315
305
|
|
306
|
+
def resolve_legacy_icon_name name
|
307
|
+
::Prawn::Icon::Compatibility::SHIMS[%(fa-#{name})]
|
308
|
+
end
|
309
|
+
|
316
310
|
def calc_line_metrics line_height = 1, font = self.font, font_size = self.font_size
|
317
311
|
line_height_length = line_height * font_size
|
318
312
|
leading = line_height_length - font_size
|
@@ -726,9 +720,11 @@ module Extensions
|
|
726
720
|
|
727
721
|
# Import the specified page into the current document.
|
728
722
|
#
|
729
|
-
# By default, advance to the
|
723
|
+
# By default, advance to the next page afterwards, creating it if necessary.
|
730
724
|
# This behavior can be disabled by passing the option `advance: false`.
|
731
|
-
#
|
725
|
+
# However, due to how page creation works in Prawn, understand that advancing
|
726
|
+
# to the next page is necessary to prevent the size & layout of the imported
|
727
|
+
# page from affecting a newly created page.
|
732
728
|
def import_page file, opts = {}
|
733
729
|
prev_page_layout = page.layout
|
734
730
|
prev_page_size = page.size
|
@@ -758,7 +754,7 @@ module Extensions
|
|
758
754
|
else
|
759
755
|
image file, (options.merge position: :center, vposition: :center, fit: [bounds.width, bounds.height])
|
760
756
|
end
|
761
|
-
# NOTE advance to
|
757
|
+
# NOTE advance to newly created page just in case the image function threw off the cursor
|
762
758
|
go_to_page image_page_number
|
763
759
|
nil
|
764
760
|
end
|
@@ -787,9 +783,7 @@ module Extensions
|
|
787
783
|
# Start a new page without triggering the on_page_create callback
|
788
784
|
#
|
789
785
|
def start_new_page_discretely options = {}
|
790
|
-
perform_discretely
|
791
|
-
start_new_page options
|
792
|
-
end
|
786
|
+
perform_discretely { start_new_page options }
|
793
787
|
end
|
794
788
|
|
795
789
|
# Grouping
|