asciidoctor-pdf 1.5.0.alpha.7 → 1.5.0.alpha.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/NOTICE.adoc +2 -2
- data/README.adoc +127 -128
- data/Rakefile +5 -4
- data/bin/asciidoctor-pdf +15 -2
- data/data/fonts/notoserif-regular-latin.ttf +0 -0
- data/data/themes/default-theme.yml +15 -13
- data/docs/theme-schema.json +114 -0
- data/docs/theming-guide.adoc +386 -132
- data/lib/asciidoctor-pdf/asciidoctor_ext.rb +2 -0
- data/lib/asciidoctor-pdf/asciidoctor_ext/image.rb +18 -0
- data/lib/asciidoctor-pdf/converter.rb +377 -221
- data/lib/asciidoctor-pdf/core_ext.rb +2 -0
- data/lib/asciidoctor-pdf/core_ext/array.rb +10 -4
- data/lib/asciidoctor-pdf/core_ext/numeric.rb +11 -0
- data/lib/asciidoctor-pdf/core_ext/ostruct.rb +1 -1
- data/lib/asciidoctor-pdf/formatted_text.rb +8 -0
- data/lib/asciidoctor-pdf/{prawn_ext/formatted_text → formatted_text}/formatter.rb +6 -9
- data/lib/asciidoctor-pdf/formatted_text/inline_destination_marker.rb +16 -0
- data/lib/asciidoctor-pdf/formatted_text/inline_image_arranger.rb +125 -0
- data/lib/asciidoctor-pdf/formatted_text/inline_image_renderer.rb +45 -0
- data/lib/asciidoctor-pdf/{prawn_ext/formatted_text → formatted_text}/parser.rb +252 -218
- data/lib/asciidoctor-pdf/{prawn_ext/formatted_text → formatted_text}/parser.treetop +18 -9
- data/lib/asciidoctor-pdf/{prawn_ext/formatted_text → formatted_text}/transform.rb +80 -69
- data/lib/asciidoctor-pdf/prawn_ext.rb +2 -2
- data/lib/asciidoctor-pdf/prawn_ext/extensions.rb +164 -35
- data/lib/asciidoctor-pdf/prawn_ext/formatted_text/fragment.rb +37 -0
- data/lib/asciidoctor-pdf/prawn_ext/images.rb +11 -9
- data/lib/asciidoctor-pdf/temporary_path.rb +9 -0
- data/lib/asciidoctor-pdf/theme_loader.rb +40 -33
- data/lib/asciidoctor-pdf/version.rb +1 -1
- metadata +30 -14
@@ -0,0 +1,37 @@
|
|
1
|
+
module Asciidoctor
|
2
|
+
module Prawn
|
3
|
+
module FormattedText
|
4
|
+
module Fragment
|
5
|
+
attr_reader :document
|
6
|
+
|
7
|
+
# Prevent fragment from being written by discarding the text.
|
8
|
+
def conceal
|
9
|
+
@text = ''
|
10
|
+
end
|
11
|
+
|
12
|
+
# Modify the built-in ascender write method to allow an override value to be
|
13
|
+
# specified using the format_state hash.
|
14
|
+
def ascender= val
|
15
|
+
@ascender = (format_state.key? :ascender) ? format_state[:ascender] : val
|
16
|
+
end
|
17
|
+
|
18
|
+
# Modify the built-in ascender write method to allow an override value to be
|
19
|
+
# specified using the format_state hash.
|
20
|
+
def descender= val
|
21
|
+
@descender = (format_state.key? :descender) ? format_state[:descender] : val
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class ::Prawn::Text::Formatted::Fragment
|
26
|
+
if ::RUBY_MIN_VERSION_2
|
27
|
+
prepend Fragment
|
28
|
+
else
|
29
|
+
# NOTE it's necessary to remove the accessor methods or else they won't get replaced
|
30
|
+
remove_method :ascender=
|
31
|
+
remove_method :descender=
|
32
|
+
include Fragment
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1,22 +1,24 @@
|
|
1
1
|
module Asciidoctor
|
2
2
|
module Prawn
|
3
3
|
module Images
|
4
|
+
class << self
|
5
|
+
def extended base
|
6
|
+
base.class.__send__ :alias_method, :_initial_image, :image
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
4
10
|
# Dispatch to suitable image method in Prawn based on file extension.
|
5
11
|
def image file, opts = {}
|
6
|
-
|
12
|
+
# FIXME handle case when SVG is a File or IO object
|
13
|
+
if ::String === file && (file.downcase.end_with? '.svg')
|
7
14
|
opts[:at] ||= bounds.top_left
|
8
|
-
svg ::IO.read
|
15
|
+
svg (::IO.read file), opts
|
9
16
|
else
|
10
|
-
|
17
|
+
_initial_image file, opts
|
11
18
|
end
|
12
19
|
end
|
13
20
|
end
|
14
|
-
end
|
15
|
-
end
|
16
21
|
|
17
|
-
|
18
|
-
class Document
|
19
|
-
alias :_builtin_image :image
|
20
|
-
include ::Asciidoctor::Prawn::Images
|
22
|
+
::Prawn::Document.extensions << Images
|
21
23
|
end
|
22
24
|
end
|
@@ -6,10 +6,18 @@ module Asciidoctor
|
|
6
6
|
module Pdf
|
7
7
|
class ThemeLoader
|
8
8
|
DataDir = ::File.expand_path(::File.join(::File.dirname(__FILE__), '..', '..', 'data'))
|
9
|
-
ThemesDir = ::File.join
|
10
|
-
FontsDir = ::File.join
|
11
|
-
HexColorValueRx = /_color: (?<quote>"|'|)#?(?<value>[A-Za-z0-9]{3,6})\k<quote>$/
|
9
|
+
ThemesDir = ::File.join DataDir, 'themes'
|
10
|
+
FontsDir = ::File.join DataDir, 'fonts'
|
12
11
|
|
12
|
+
VariableRx = /\$([a-z0-9_]+)/
|
13
|
+
LoneVariableRx = /^\$([a-z0-9_]+)$/
|
14
|
+
HexColorValueRx = /[_-]color: (?<quote>"|'|)#?(?<value>[A-Za-z0-9]{3,6})\k<quote>$/
|
15
|
+
MeasurementValueRx = /(?<=^| |\()(\d+(?:\.\d+)?)(in|mm|cm|pt)(?=$| |\))/
|
16
|
+
MultiplyDivideOpRx = /(-?\d+(?:\.\d+)?) *([*\/]) *(-?\d+(?:\.\d+)?)/
|
17
|
+
AddSubtractOpRx = /(-?\d+(?:\.\d+)?) *([+\-]) *(-?\d+(?:\.\d+)?)/
|
18
|
+
PrecisionFuncRx = /^(round|floor|ceil)\(/
|
19
|
+
|
20
|
+
# TODO implement white? & black? methods
|
13
21
|
module ColorValue; end
|
14
22
|
|
15
23
|
class HexColorValue < String
|
@@ -28,7 +36,7 @@ class ThemeLoader
|
|
28
36
|
def self.resolve_theme_file theme_name = nil, theme_path = nil
|
29
37
|
theme_name ||= 'default'
|
30
38
|
# if .yml extension is given, assume it's a full file name
|
31
|
-
if theme_name.end_with?
|
39
|
+
if (theme_name.end_with? '.yml')
|
32
40
|
# FIXME restrict to jail!
|
33
41
|
# QUESTION why are we not using expand_path in this case?
|
34
42
|
theme_path ? ::File.join(theme_path, theme_name) : theme_name
|
@@ -43,17 +51,17 @@ class ThemeLoader
|
|
43
51
|
end
|
44
52
|
|
45
53
|
def self.load_theme theme_name = nil, theme_path = nil
|
46
|
-
load_file(resolve_theme_file
|
54
|
+
load_file(resolve_theme_file theme_name, theme_path)
|
47
55
|
end
|
48
56
|
|
49
57
|
def self.load_file filename
|
50
|
-
data = ::IO.read(filename).each_line.map {|l| l.sub
|
51
|
-
self.new.load(::SafeYAML.load
|
58
|
+
data = ::IO.read(filename).each_line.map {|l| l.sub HexColorValueRx, '_color: \'\k<value>\'' }.join
|
59
|
+
self.new.load(::SafeYAML.load data)
|
52
60
|
end
|
53
61
|
|
54
62
|
def load hash
|
55
63
|
hash.inject(::OpenStruct.new) do |data, (key, val)|
|
56
|
-
process_entry
|
64
|
+
process_entry key, val, data
|
57
65
|
end
|
58
66
|
end
|
59
67
|
|
@@ -62,10 +70,10 @@ class ThemeLoader
|
|
62
70
|
def process_entry key, val, data
|
63
71
|
if key != 'font_catalog' && ::Hash === val
|
64
72
|
val.each do |key2, val2|
|
65
|
-
process_entry
|
73
|
+
process_entry %(#{key}_#{key2.tr '-', '_'}), val2, data
|
66
74
|
end
|
67
75
|
else
|
68
|
-
data[key] = key.end_with?
|
76
|
+
data[key] = (key.end_with? '_color') ? to_color(evaluate val, data) : (evaluate val, data)
|
69
77
|
end
|
70
78
|
data
|
71
79
|
end
|
@@ -73,9 +81,9 @@ class ThemeLoader
|
|
73
81
|
def evaluate expr, vars
|
74
82
|
case expr
|
75
83
|
when ::String
|
76
|
-
evaluate_math(expand_vars
|
84
|
+
evaluate_math(expand_vars expr, vars)
|
77
85
|
when ::Array
|
78
|
-
expr.map {|e| evaluate
|
86
|
+
expr.map {|e| evaluate e, vars }
|
79
87
|
else
|
80
88
|
expr
|
81
89
|
end
|
@@ -83,11 +91,11 @@ class ThemeLoader
|
|
83
91
|
|
84
92
|
# NOTE we assume expr is a String
|
85
93
|
def expand_vars expr, vars
|
86
|
-
if (idx = expr.index
|
87
|
-
if idx == 0 && expr
|
94
|
+
if (idx = (expr.index '$'))
|
95
|
+
if idx == 0 && LoneVariableRx =~ expr
|
88
96
|
vars[$1]
|
89
97
|
else
|
90
|
-
expr.gsub(
|
98
|
+
expr.gsub(VariableRx) { vars[$1] }
|
91
99
|
end
|
92
100
|
else
|
93
101
|
expr
|
@@ -98,9 +106,10 @@ class ThemeLoader
|
|
98
106
|
return expr if !(::String === expr) || ColorValue === expr
|
99
107
|
original = expr
|
100
108
|
# FIXME quick HACK to turn a single negative number into an expression
|
101
|
-
expr = %(1 - #{expr[1..-1]}) if expr.start_with?
|
109
|
+
expr = %(1 - #{expr[1..-1]}) if expr.start_with? '-'
|
102
110
|
# expand measurement values (e.g., 0.5in)
|
103
|
-
expr = expr.gsub(
|
111
|
+
expr = expr.gsub(MeasurementValueRx) {
|
112
|
+
# TODO extract to_pt method and use it here
|
104
113
|
val = $1.to_f
|
105
114
|
case $2
|
106
115
|
when 'in'
|
@@ -117,23 +126,21 @@ class ThemeLoader
|
|
117
126
|
val
|
118
127
|
}
|
119
128
|
while true
|
120
|
-
|
121
|
-
result = expr.gsub(/(-?\d+(?:\.\d+)?) *([*\/]) *(-?\d+(?:\.\d+)?)/) { $1.to_f.send($2.to_sym, $3.to_f) }
|
129
|
+
result = expr.gsub(MultiplyDivideOpRx) { $1.to_f.send $2.to_sym, $3.to_f }
|
122
130
|
unchanged = (result == expr)
|
123
131
|
expr = result
|
124
132
|
break if unchanged
|
125
133
|
end
|
126
134
|
while true
|
127
|
-
|
128
|
-
result = expr.gsub(/(-?\d+(?:\.\d+)?) *([+\-]) *(-?\d+(?:\.\d+)?)/) { $1.to_f.send($2.to_sym, $3.to_f) }
|
135
|
+
result = expr.gsub(AddSubtractOpRx) { $1.to_f.send $2.to_sym, $3.to_f }
|
129
136
|
unchanged = (result == expr)
|
130
137
|
expr = result
|
131
138
|
break if unchanged
|
132
139
|
end
|
133
|
-
if expr.end_with?
|
140
|
+
if (expr.end_with? ')') && PrecisionFuncRx =~ expr
|
134
141
|
op = $1
|
135
142
|
offset = op.length + 1
|
136
|
-
expr = expr[offset...-1].to_f.send
|
143
|
+
expr = expr[offset...-1].to_f.send op.to_sym
|
137
144
|
end
|
138
145
|
if expr == original
|
139
146
|
original
|
@@ -150,34 +157,34 @@ class ThemeLoader
|
|
150
157
|
when ::String
|
151
158
|
if value == 'transparent'
|
152
159
|
# FIXME should we have a TransparentColorValue class?
|
153
|
-
return HexColorValue.new
|
160
|
+
return HexColorValue.new value
|
154
161
|
elsif value.size == 6
|
155
|
-
return HexColorValue.new
|
162
|
+
return HexColorValue.new value.upcase
|
156
163
|
end
|
157
164
|
when ::Array
|
158
165
|
case value.size
|
159
166
|
# CMYK value
|
160
167
|
when 4
|
161
|
-
value = value.map
|
168
|
+
value = value.map do |e|
|
162
169
|
if ::Numeric === e
|
163
170
|
e = e * 100.0 unless e > 1
|
164
171
|
else
|
165
172
|
e = e.to_s.chomp('%').to_f
|
166
173
|
end
|
167
|
-
|
168
|
-
|
174
|
+
e == (int_e = e.to_i) ? int_e : e
|
175
|
+
end
|
169
176
|
case value
|
170
177
|
when [0, 0, 0, 0]
|
171
|
-
return HexColorValue.new
|
178
|
+
return HexColorValue.new 'FFFFFF'
|
172
179
|
when [100, 100, 100, 100]
|
173
|
-
return HexColorValue.new
|
180
|
+
return HexColorValue.new '000000'
|
174
181
|
else
|
175
182
|
value.extend CmykColorValue
|
176
183
|
return value
|
177
184
|
end
|
178
185
|
# RGB value
|
179
186
|
when 3
|
180
|
-
return HexColorValue.new
|
187
|
+
return HexColorValue.new value.map {|e| '%02X' % e}.join
|
181
188
|
# Nonsense array value; flatten to string
|
182
189
|
else
|
183
190
|
value = value.join
|
@@ -194,9 +201,9 @@ class ThemeLoader
|
|
194
201
|
value.each_char.map {|c| c * 2 }.join
|
195
202
|
else
|
196
203
|
# truncate or pad with leading zeros (e.g., ff -> 0000ff)
|
197
|
-
value[0..5].rjust
|
204
|
+
value[0..5].rjust 6, '0'
|
198
205
|
end
|
199
|
-
HexColorValue.new
|
206
|
+
HexColorValue.new value.upcase
|
200
207
|
end
|
201
208
|
end
|
202
209
|
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.8
|
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: 2015-
|
12
|
+
date: 2015-06-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -43,30 +43,36 @@ dependencies:
|
|
43
43
|
name: prawn
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- -
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 1.3.0
|
49
|
+
- - "<"
|
47
50
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
51
|
+
version: 3.0.0
|
49
52
|
type: :runtime
|
50
53
|
prerelease: false
|
51
54
|
version_requirements: !ruby/object:Gem::Requirement
|
52
55
|
requirements:
|
53
|
-
- -
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: 1.3.0
|
59
|
+
- - "<"
|
54
60
|
- !ruby/object:Gem::Version
|
55
|
-
version:
|
61
|
+
version: 3.0.0
|
56
62
|
- !ruby/object:Gem::Dependency
|
57
63
|
name: prawn-table
|
58
64
|
requirement: !ruby/object:Gem::Requirement
|
59
65
|
requirements:
|
60
66
|
- - '='
|
61
67
|
- !ruby/object:Gem::Version
|
62
|
-
version: 0.
|
68
|
+
version: 0.2.1
|
63
69
|
type: :runtime
|
64
70
|
prerelease: false
|
65
71
|
version_requirements: !ruby/object:Gem::Requirement
|
66
72
|
requirements:
|
67
73
|
- - '='
|
68
74
|
- !ruby/object:Gem::Version
|
69
|
-
version: 0.
|
75
|
+
version: 0.2.1
|
70
76
|
- !ruby/object:Gem::Dependency
|
71
77
|
name: prawn-templates
|
72
78
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,14 +93,14 @@ dependencies:
|
|
87
93
|
requirements:
|
88
94
|
- - '='
|
89
95
|
- !ruby/object:Gem::Version
|
90
|
-
version: 0.
|
96
|
+
version: 0.20.0
|
91
97
|
type: :runtime
|
92
98
|
prerelease: false
|
93
99
|
version_requirements: !ruby/object:Gem::Requirement
|
94
100
|
requirements:
|
95
101
|
- - '='
|
96
102
|
- !ruby/object:Gem::Version
|
97
|
-
version: 0.
|
103
|
+
version: 0.20.0
|
98
104
|
- !ruby/object:Gem::Dependency
|
99
105
|
name: prawn-icon
|
100
106
|
requirement: !ruby/object:Gem::Requirement
|
@@ -180,15 +186,27 @@ files:
|
|
180
186
|
- data/fonts/notoserif-italic-latin.ttf
|
181
187
|
- data/fonts/notoserif-regular-latin.ttf
|
182
188
|
- data/themes/default-theme.yml
|
189
|
+
- docs/theme-schema.json
|
183
190
|
- docs/theming-guide.adoc
|
184
191
|
- lib/asciidoctor-pdf.rb
|
185
192
|
- lib/asciidoctor-pdf/asciidoctor_ext.rb
|
193
|
+
- lib/asciidoctor-pdf/asciidoctor_ext/image.rb
|
186
194
|
- lib/asciidoctor-pdf/asciidoctor_ext/list.rb
|
187
195
|
- lib/asciidoctor-pdf/asciidoctor_ext/list_item.rb
|
188
196
|
- lib/asciidoctor-pdf/asciidoctor_ext/section.rb
|
189
197
|
- lib/asciidoctor-pdf/converter.rb
|
198
|
+
- lib/asciidoctor-pdf/core_ext.rb
|
190
199
|
- lib/asciidoctor-pdf/core_ext/array.rb
|
200
|
+
- lib/asciidoctor-pdf/core_ext/numeric.rb
|
191
201
|
- lib/asciidoctor-pdf/core_ext/ostruct.rb
|
202
|
+
- lib/asciidoctor-pdf/formatted_text.rb
|
203
|
+
- lib/asciidoctor-pdf/formatted_text/formatter.rb
|
204
|
+
- lib/asciidoctor-pdf/formatted_text/inline_destination_marker.rb
|
205
|
+
- lib/asciidoctor-pdf/formatted_text/inline_image_arranger.rb
|
206
|
+
- lib/asciidoctor-pdf/formatted_text/inline_image_renderer.rb
|
207
|
+
- lib/asciidoctor-pdf/formatted_text/parser.rb
|
208
|
+
- lib/asciidoctor-pdf/formatted_text/parser.treetop
|
209
|
+
- lib/asciidoctor-pdf/formatted_text/transform.rb
|
192
210
|
- lib/asciidoctor-pdf/implicit_header_processor.rb
|
193
211
|
- lib/asciidoctor-pdf/pdf_core_ext.rb
|
194
212
|
- lib/asciidoctor-pdf/pdf_core_ext/pdf_object.rb
|
@@ -196,13 +214,11 @@ files:
|
|
196
214
|
- lib/asciidoctor-pdf/prawn_ext.rb
|
197
215
|
- lib/asciidoctor-pdf/prawn_ext/coderay_encoder.rb
|
198
216
|
- lib/asciidoctor-pdf/prawn_ext/extensions.rb
|
199
|
-
- lib/asciidoctor-pdf/prawn_ext/formatted_text/
|
200
|
-
- lib/asciidoctor-pdf/prawn_ext/formatted_text/parser.rb
|
201
|
-
- lib/asciidoctor-pdf/prawn_ext/formatted_text/parser.treetop
|
202
|
-
- lib/asciidoctor-pdf/prawn_ext/formatted_text/transform.rb
|
217
|
+
- lib/asciidoctor-pdf/prawn_ext/formatted_text/fragment.rb
|
203
218
|
- lib/asciidoctor-pdf/prawn_ext/images.rb
|
204
219
|
- lib/asciidoctor-pdf/roman_numeral.rb
|
205
220
|
- lib/asciidoctor-pdf/sanitizer.rb
|
221
|
+
- lib/asciidoctor-pdf/temporary_path.rb
|
206
222
|
- lib/asciidoctor-pdf/theme_loader.rb
|
207
223
|
- lib/asciidoctor-pdf/version.rb
|
208
224
|
homepage: https://github.com/asciidoctor/asciidoctor-pdf
|