prawn 2.3.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Rakefile +2 -31
- data/lib/prawn.rb +1 -0
- data/lib/prawn/document.rb +20 -15
- data/lib/prawn/document/bounding_box.rb +10 -2
- data/lib/prawn/document/span.rb +2 -1
- data/lib/prawn/font.rb +6 -4
- data/lib/prawn/font_metric_cache.rb +7 -6
- data/lib/prawn/fonts/afm.rb +18 -16
- data/lib/prawn/fonts/ttf.rb +55 -29
- data/lib/prawn/graphics.rb +11 -11
- data/lib/prawn/graphics/color.rb +18 -16
- data/lib/prawn/graphics/join_style.rb +1 -1
- data/lib/prawn/graphics/patterns.rb +57 -49
- data/lib/prawn/graphics/transformation.rb +3 -3
- data/lib/prawn/grid.rb +36 -1
- data/lib/prawn/images.rb +29 -27
- data/lib/prawn/images/jpg.rb +4 -1
- data/lib/prawn/images/png.rb +2 -1
- data/lib/prawn/outline.rb +6 -5
- data/lib/prawn/repeater.rb +1 -1
- data/lib/prawn/security.rb +39 -36
- data/lib/prawn/text.rb +18 -18
- data/lib/prawn/text/box.rb +10 -9
- data/lib/prawn/text/formatted/arranger.rb +38 -19
- data/lib/prawn/text/formatted/box.rb +20 -15
- data/lib/prawn/text/formatted/line_wrap.rb +18 -16
- data/lib/prawn/text/formatted/parser.rb +28 -26
- data/lib/prawn/text/formatted/wrap.rb +15 -11
- data/lib/prawn/version.rb +1 -1
- data/lib/prawn/view.rb +2 -2
- data/manual/basic_concepts/measurement.rb +1 -1
- data/manual/bounding_box/canvas.rb +3 -3
- data/manual/bounding_box/nesting.rb +1 -1
- data/manual/document_and_page_options/background.rb +6 -2
- data/manual/document_and_page_options/document_and_page_options.rb +3 -3
- data/manual/document_and_page_options/print_scaling.rb +2 -1
- data/manual/graphics/common_lines.rb +1 -1
- data/manual/graphics/fill_and_stroke.rb +1 -1
- data/manual/graphics/fill_rules.rb +4 -3
- data/manual/graphics/helper.rb +11 -4
- data/manual/graphics/lines_and_curves.rb +1 -1
- data/manual/graphics/stroke_dash.rb +5 -5
- data/manual/graphics/translate.rb +2 -1
- data/manual/images/horizontal.rb +2 -2
- data/manual/images/scale.rb +3 -3
- data/manual/images/vertical.rb +6 -3
- data/manual/images/width_and_height.rb +3 -3
- data/manual/layout/content.rb +2 -2
- data/manual/outline/outline.rb +1 -1
- data/manual/security/permissions.rb +4 -2
- data/manual/security/security.rb +1 -1
- data/manual/text/alignment.rb +2 -2
- data/manual/text/column_box.rb +2 -2
- data/manual/text/font_style.rb +5 -2
- data/manual/text/formatted_callbacks.rb +17 -12
- data/manual/text/formatted_text.rb +7 -4
- data/manual/text/free_flowing_text.rb +3 -3
- data/manual/text/kerning_and_character_spacing.rb +4 -4
- data/manual/text/paragraph_indentation.rb +4 -5
- data/manual/text/rendering_and_color.rb +1 -1
- data/manual/text/right_to_left_text.rb +6 -6
- data/manual/text/rotation.rb +8 -3
- data/manual/text/text_box_extensions.rb +1 -1
- data/manual/text/text_box_overflow.rb +11 -9
- data/manual/text/win_ansi_charset.rb +9 -9
- data/prawn.gemspec +4 -10
- data/spec/prawn/document/bounding_box_spec.rb +82 -78
- data/spec/prawn/document/security_spec.rb +1 -1
- data/spec/prawn/document_span_spec.rb +14 -6
- data/spec/prawn/document_spec.rb +29 -26
- data/spec/prawn/font_spec.rb +16 -14
- data/spec/prawn/graphics_spec.rb +79 -44
- data/spec/prawn/images_spec.rb +13 -8
- data/spec/prawn/outline_spec.rb +127 -27
- data/spec/prawn/repeater_spec.rb +9 -8
- data/spec/prawn/soft_mask_spec.rb +1 -1
- data/spec/prawn/stamp_spec.rb +3 -2
- data/spec/prawn/text/box_spec.rb +57 -59
- data/spec/prawn/text/formatted/arranger_spec.rb +10 -10
- data/spec/prawn/text/formatted/box_spec.rb +8 -5
- data/spec/prawn/text/formatted/line_wrap_spec.rb +2 -1
- data/spec/prawn/text_draw_text_spec.rb +9 -8
- data/spec/prawn/text_spacing_spec.rb +2 -2
- data/spec/prawn/text_spec.rb +9 -9
- data/spec/prawn/text_with_inline_formatting_spec.rb +1 -1
- data/spec/prawn_manual_spec.rb +4 -4
- metadata +14 -98
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d64c2da1e4be48e40f4fa6fa4de35e04c75debf0119e8c59b3fba9d944c112db
|
4
|
+
data.tar.gz: 393bbdd1a5df657d5c6190d4bd10ecd7353522e714b2f60c8d9c5f70e5bc1ce9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4980639ca24796d577be790ed0f6fa85c985f1a6eb147e4c5db1df261c5d50afe8a466f06b65588b71a897e22e8d2b7b01daceed1714f6164124057154d2d28
|
7
|
+
data.tar.gz: e0fd560d4a80f2827736d599266bcb2e2fe19abedcde639520fba8bd19a2f12fe2cf0e8a60a91b87dbac4336d25c680f94b2341e5f9ce3d6d24f2e65f24e24a3
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/Rakefile
CHANGED
@@ -1,23 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require '
|
5
|
-
require 'yard'
|
6
|
-
require 'rubygems/package_task'
|
7
|
-
require 'rubocop/rake_task'
|
3
|
+
GEMSPEC = File.expand_path('prawn.gemspec', __dir__)
|
4
|
+
require 'prawn/dev/tasks'
|
8
5
|
|
9
6
|
task default: %i[spec rubocop]
|
10
7
|
|
11
|
-
desc 'Run all rspec files'
|
12
|
-
RSpec::Core::RakeTask.new('spec') do |c|
|
13
|
-
c.rspec_opts = '-t ~unresolved'
|
14
|
-
end
|
15
|
-
|
16
|
-
YARD::Rake::YardocTask.new do |t|
|
17
|
-
t.options = ['--output-dir', 'doc/html']
|
18
|
-
end
|
19
|
-
task docs: :yard
|
20
|
-
|
21
8
|
desc "Generate the 'Prawn by Example' manual"
|
22
9
|
task :manual do
|
23
10
|
puts 'Building manual...'
|
@@ -26,12 +13,6 @@ task :manual do
|
|
26
13
|
puts 'The Prawn manual is available at manual.pdf. Happy Prawning!'
|
27
14
|
end
|
28
15
|
|
29
|
-
spec = Gem::Specification.load 'prawn.gemspec'
|
30
|
-
Gem::PackageTask.new(spec) do |pkg|
|
31
|
-
pkg.need_zip = true
|
32
|
-
pkg.need_tar = true
|
33
|
-
end
|
34
|
-
|
35
16
|
desc 'Run a console with Prawn loaded'
|
36
17
|
task :console do
|
37
18
|
require 'irb'
|
@@ -42,13 +23,3 @@ task :console do
|
|
42
23
|
ARGV.clear
|
43
24
|
IRB.start
|
44
25
|
end
|
45
|
-
|
46
|
-
RuboCop::RakeTask.new
|
47
|
-
|
48
|
-
task :checksum do
|
49
|
-
require 'digest/sha2'
|
50
|
-
built_gem_path = "prawn-#{Prawn::VERSION}.gem"
|
51
|
-
checksum = Digest::SHA512.new.hexdigest(File.read(built_gem_path))
|
52
|
-
checksum_path = "checksums/#{built_gem_path}.sha512"
|
53
|
-
File.write(checksum_path, checksum)
|
54
|
-
end
|
data/lib/prawn.rb
CHANGED
data/lib/prawn/document.rb
CHANGED
@@ -98,6 +98,7 @@ module Prawn
|
|
98
98
|
|
99
99
|
# @private
|
100
100
|
def self.inherited(base)
|
101
|
+
super
|
101
102
|
extensions.each { |e| base.extensions << e }
|
102
103
|
end
|
103
104
|
|
@@ -570,11 +571,12 @@ module Prawn
|
|
570
571
|
opts = options.dup
|
571
572
|
start_count_at = opts.delete(:start_count_at).to_i
|
572
573
|
|
573
|
-
page_filter =
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
574
|
+
page_filter =
|
575
|
+
if opts.key?(:page_filter)
|
576
|
+
opts.delete(:page_filter)
|
577
|
+
else
|
578
|
+
:all
|
579
|
+
end
|
578
580
|
|
579
581
|
total_pages = opts.delete(:total_pages)
|
580
582
|
txtcolor = opts.delete(:color)
|
@@ -585,12 +587,13 @@ module Prawn
|
|
585
587
|
pseudopage = 0
|
586
588
|
(1..page_count).each do |p|
|
587
589
|
unless start_count
|
588
|
-
pseudopage =
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
590
|
+
pseudopage =
|
591
|
+
case start_count_at
|
592
|
+
when 0
|
593
|
+
1
|
594
|
+
else
|
595
|
+
start_count_at.to_i
|
596
|
+
end
|
594
597
|
end
|
595
598
|
if page_match?(page_filter, p)
|
596
599
|
go_to_page(p)
|
@@ -668,9 +671,9 @@ module Prawn
|
|
668
671
|
# and then restores the original values after the block has executed.
|
669
672
|
# -- I will remove the nodoc if/when this feature is a little less hacky
|
670
673
|
stored = {}
|
671
|
-
fields.each { |f| stored[f] =
|
674
|
+
fields.each { |f| stored[f] = public_send(f) }
|
672
675
|
yield
|
673
|
-
fields.each { |f|
|
676
|
+
fields.each { |f| public_send("#{f}=", stored[f]) }
|
674
677
|
end
|
675
678
|
|
676
679
|
# @group Extension API
|
@@ -737,8 +740,10 @@ module Prawn
|
|
737
740
|
|
738
741
|
# Treat :margin as CSS shorthand with 1-4 values.
|
739
742
|
positions = {
|
740
|
-
4 => [0, 1, 2, 3],
|
741
|
-
|
743
|
+
4 => [0, 1, 2, 3],
|
744
|
+
3 => [0, 1, 2, 1],
|
745
|
+
2 => [0, 1, 0, 1],
|
746
|
+
1 => [0, 0, 0, 0],
|
742
747
|
0 => []
|
743
748
|
}[margin.length]
|
744
749
|
|
@@ -173,7 +173,9 @@ module Prawn
|
|
173
173
|
init_bounding_box(block, hold_position: true) do |_|
|
174
174
|
# Canvas bbox acts like margin_box in that its parent bounds are unset.
|
175
175
|
@bounding_box = BoundingBox.new(
|
176
|
-
self,
|
176
|
+
self,
|
177
|
+
nil,
|
178
|
+
[0, page.dimensions[3]],
|
177
179
|
width: page.dimensions[2],
|
178
180
|
height: page.dimensions[3]
|
179
181
|
)
|
@@ -221,6 +223,12 @@ module Prawn
|
|
221
223
|
# is used for.
|
222
224
|
#
|
223
225
|
class BoundingBox
|
226
|
+
class NoReferenceBounds < StandardError
|
227
|
+
def initialize(message = "Can't find reference bounds: my parent is unset")
|
228
|
+
super
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
224
232
|
# @private
|
225
233
|
def initialize(document, parent, point, options = {})
|
226
234
|
unless options[:width]
|
@@ -504,7 +512,7 @@ module Prawn
|
|
504
512
|
#
|
505
513
|
def reference_bounds
|
506
514
|
if stretchy?
|
507
|
-
raise
|
515
|
+
raise NoReferenceBounds unless @parent
|
508
516
|
|
509
517
|
@parent.reference_bounds
|
510
518
|
else
|
data/lib/prawn/document/span.rb
CHANGED
data/lib/prawn/font.rb
CHANGED
@@ -318,10 +318,10 @@ module Prawn
|
|
318
318
|
return options.fetch(:format, 'ttf') if src.respond_to? :read
|
319
319
|
|
320
320
|
case src.to_s
|
321
|
-
when /\.ttf$/i
|
322
|
-
when /\.otf$/i
|
321
|
+
when /\.ttf$/i then 'ttf'
|
322
|
+
when /\.otf$/i then 'otf'
|
323
323
|
when /\.dfont$/i then 'dfont'
|
324
|
-
when /\.ttc$/i
|
324
|
+
when /\.ttc$/i then 'ttc'
|
325
325
|
else 'afm'
|
326
326
|
end
|
327
327
|
end
|
@@ -420,7 +420,7 @@ module Prawn
|
|
420
420
|
#
|
421
421
|
def eql?(other) #:nodoc:
|
422
422
|
self.class == other.class && name == other.name &&
|
423
|
-
family == other.family && size == other.
|
423
|
+
family == other.family && size == other.size
|
424
424
|
end
|
425
425
|
|
426
426
|
private
|
@@ -445,6 +445,8 @@ module Prawn
|
|
445
445
|
end
|
446
446
|
end
|
447
447
|
|
448
|
+
protected
|
449
|
+
|
448
450
|
def size
|
449
451
|
@document.font_size
|
450
452
|
end
|
@@ -22,12 +22,13 @@ module Prawn
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def width_of(string, options)
|
25
|
-
f =
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
f =
|
26
|
+
if options[:style]
|
27
|
+
# override style with :style => :bold
|
28
|
+
@document.find_font(@document.font.family, style: options[:style])
|
29
|
+
else
|
30
|
+
@document.font
|
31
|
+
end
|
31
32
|
|
32
33
|
encoded_string = f.normalize_encoding(string)
|
33
34
|
|
data/lib/prawn/fonts/afm.rb
CHANGED
@@ -31,16 +31,17 @@ module Prawn
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def self.metrics_path
|
34
|
-
@metrics_path ||=
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
34
|
+
@metrics_path ||=
|
35
|
+
if ENV['METRICS']
|
36
|
+
ENV['METRICS'].split(':')
|
37
|
+
else
|
38
|
+
[
|
39
|
+
'.', '/usr/lib/afm',
|
40
|
+
'/usr/local/lib/afm',
|
41
|
+
'/usr/openwin/lib/fonts/afm',
|
42
|
+
"#{Prawn::DATADIR}/fonts"
|
43
|
+
]
|
44
|
+
end
|
44
45
|
end
|
45
46
|
|
46
47
|
attr_reader :attributes #:nodoc:
|
@@ -88,7 +89,7 @@ module Prawn
|
|
88
89
|
|
89
90
|
if options[:kerning]
|
90
91
|
strings, numbers = kern(string).partition { |e| e.is_a?(String) }
|
91
|
-
total_kerning_offset = numbers.
|
92
|
+
total_kerning_offset = numbers.sum
|
92
93
|
(unscaled_width_of(strings.join) - total_kerning_offset) * scale
|
93
94
|
else
|
94
95
|
unscaled_width_of(string) * scale
|
@@ -176,7 +177,7 @@ module Prawn
|
|
176
177
|
rescue NoMethodError
|
177
178
|
raise Prawn::Errors::UnknownFont,
|
178
179
|
"Couldn't find the font: #{file} in any of:\n" +
|
179
|
-
|
180
|
+
self.class.metrics_path.join("\n")
|
180
181
|
end
|
181
182
|
|
182
183
|
def parse_afm(file_name)
|
@@ -220,9 +221,10 @@ module Prawn
|
|
220
221
|
|
221
222
|
# process data parsed from AFM file to build tables which
|
222
223
|
# will be used when measuring and kerning text
|
223
|
-
data[:glyph_table] =
|
224
|
-
|
225
|
-
|
224
|
+
data[:glyph_table] =
|
225
|
+
(0..255).map do |i|
|
226
|
+
data[:glyph_widths][Encoding::WinAnsi::CHARACTERS[i]].to_i
|
227
|
+
end
|
226
228
|
|
227
229
|
character_hash = Hash[
|
228
230
|
Encoding::WinAnsi::CHARACTERS.zip(
|
@@ -281,7 +283,7 @@ module Prawn
|
|
281
283
|
end
|
282
284
|
|
283
285
|
def unscaled_width_of(string)
|
284
|
-
string.bytes.
|
286
|
+
string.bytes.reduce(0) do |s, r|
|
285
287
|
s + @glyph_table[r]
|
286
288
|
end
|
287
289
|
end
|
data/lib/prawn/fonts/ttf.rb
CHANGED
@@ -14,6 +14,29 @@ module Prawn
|
|
14
14
|
module Fonts
|
15
15
|
# @private
|
16
16
|
class TTF < Font
|
17
|
+
class Error < StandardError
|
18
|
+
DEFAULT_MESSAGE = 'TTF font error'
|
19
|
+
MESSAGE_WITH_FONT = 'TTF font error in font %<font>s'
|
20
|
+
|
21
|
+
def initialize(message = DEFAULT_MESSAGE, font: nil)
|
22
|
+
if font && message == DEFAULT_MESSAGE
|
23
|
+
super format(MESSAGE_WITH_FONT, font: font)
|
24
|
+
else
|
25
|
+
super message
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class NoUnicodeCMap < Error
|
31
|
+
DEFAULT_MESSAGE = 'No unicode cmap found in font'
|
32
|
+
MESSAGE_WITH_FONT = 'No unicode cmap found in font %<font>s'
|
33
|
+
end
|
34
|
+
|
35
|
+
class NoPostscriptName < Error
|
36
|
+
DEFAULT_MESSAGE = 'Can not detect a postscript name'
|
37
|
+
MESSAGE_WITH_FONT = 'Can not detect a postscript name in font %<font>s'
|
38
|
+
end
|
39
|
+
|
17
40
|
attr_reader :ttf, :subsets
|
18
41
|
|
19
42
|
def unicode?
|
@@ -41,15 +64,15 @@ module Prawn
|
|
41
64
|
def compute_width_of(string, options = {}) #:nodoc:
|
42
65
|
scale = (options[:size] || size) / 1000.0
|
43
66
|
if options[:kerning]
|
44
|
-
kern(string).
|
67
|
+
kern(string).reduce(0) do |s, r|
|
45
68
|
if r.is_a?(Numeric)
|
46
69
|
s - r
|
47
70
|
else
|
48
|
-
r.
|
71
|
+
r.reduce(s) { |a, e| a + character_width_by_code(e) }
|
49
72
|
end
|
50
73
|
end * scale
|
51
74
|
else
|
52
|
-
string.codepoints.
|
75
|
+
string.codepoints.reduce(0) do |s, r|
|
53
76
|
s + character_width_by_code(r)
|
54
77
|
end * scale
|
55
78
|
end
|
@@ -82,7 +105,7 @@ module Prawn
|
|
82
105
|
|
83
106
|
if options[:kerning]
|
84
107
|
last_subset = nil
|
85
|
-
kern(text).
|
108
|
+
kern(text).reduce([]) do |result, element|
|
86
109
|
if element.is_a?(Numeric)
|
87
110
|
unless result.last[1].is_a?(Array)
|
88
111
|
result.last[1] = [result.last[1]]
|
@@ -136,10 +159,11 @@ module Prawn
|
|
136
159
|
end
|
137
160
|
|
138
161
|
def cap_height
|
139
|
-
@cap_height ||=
|
140
|
-
|
141
|
-
|
142
|
-
|
162
|
+
@cap_height ||=
|
163
|
+
begin
|
164
|
+
height = @ttf.os2.exists? && @ttf.os2.cap_height || 0
|
165
|
+
height.zero? ? @ascender : height
|
166
|
+
end
|
143
167
|
end
|
144
168
|
|
145
169
|
def x_height
|
@@ -161,23 +185,24 @@ module Prawn
|
|
161
185
|
end
|
162
186
|
|
163
187
|
def pdf_flags
|
164
|
-
@pdf_flags ||=
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
188
|
+
@pdf_flags ||=
|
189
|
+
begin
|
190
|
+
flags = 0
|
191
|
+
flags |= 0x0001 if @ttf.postscript.fixed_pitch?
|
192
|
+
flags |= 0x0002 if serif?
|
193
|
+
flags |= 0x0008 if script?
|
194
|
+
flags |= 0x0040 if italic_angle != 0
|
195
|
+
# Assume the font contains at least some non-latin characters
|
196
|
+
flags | 0x0004
|
197
|
+
end
|
173
198
|
end
|
174
199
|
|
175
200
|
def normalize_encoding(text)
|
176
201
|
text.encode(::Encoding::UTF_8)
|
177
202
|
rescue StandardError => e
|
178
203
|
puts e
|
179
|
-
raise Prawn::Errors::IncompatibleStringEncoding,
|
180
|
-
"#{text.encoding} can not be transparently converted to UTF-8. " \
|
204
|
+
raise Prawn::Errors::IncompatibleStringEncoding,
|
205
|
+
"Encoding #{text.encoding} can not be transparently converted to UTF-8. " \
|
181
206
|
'Please ensure the encoding of the string you are attempting ' \
|
182
207
|
'to use is set correctly'
|
183
208
|
end
|
@@ -200,7 +225,7 @@ module Prawn
|
|
200
225
|
private
|
201
226
|
|
202
227
|
def cmap
|
203
|
-
(@cmap ||= @ttf.cmap.unicode.first) || raise(
|
228
|
+
(@cmap ||= @ttf.cmap.unicode.first) || raise(NoUnicodeCMap.new(font: name))
|
204
229
|
end
|
205
230
|
|
206
231
|
# +string+ must be UTF8-encoded.
|
@@ -275,7 +300,7 @@ module Prawn
|
|
275
300
|
# if their font name is more than 33 bytes long. Strange. But true.
|
276
301
|
basename = font.name.postscript_name[0, 33].delete("\0")
|
277
302
|
|
278
|
-
raise
|
303
|
+
raise NoPostscriptName.new(font: font) if basename.nil?
|
279
304
|
|
280
305
|
fontfile = @document.ref!(Length1: font_content.size)
|
281
306
|
fontfile.stream << font_content
|
@@ -313,7 +338,7 @@ module Prawn
|
|
313
338
|
map = @subsets[subset].to_unicode_map
|
314
339
|
|
315
340
|
ranges = [[]]
|
316
|
-
map.keys.sort.
|
341
|
+
map.keys.sort.reduce('') do |_s, code|
|
317
342
|
ranges << [] if ranges.last.length >= 100
|
318
343
|
unicode = map[code]
|
319
344
|
ranges.last << format(
|
@@ -323,13 +348,14 @@ module Prawn
|
|
323
348
|
)
|
324
349
|
end
|
325
350
|
|
326
|
-
range_blocks =
|
327
|
-
s
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
351
|
+
range_blocks =
|
352
|
+
ranges.reduce(+'') do |s, list|
|
353
|
+
s << format(
|
354
|
+
"%<lenght>d beginbfchar\n%<list>s\nendbfchar\n",
|
355
|
+
lenght: list.length,
|
356
|
+
list: list.join("\n")
|
357
|
+
)
|
358
|
+
end
|
333
359
|
|
334
360
|
to_unicode_cmap = UNICODE_CMAP_TEMPLATE % range_blocks.strip
|
335
361
|
|