prawn-manual_builder 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,55 +1,107 @@
1
- # encoding: utf-8
2
-
3
- require "coderay"
1
+ # frozen_string_literal: true
4
2
 
5
3
  module Prawn
6
4
  module ManualBuilder
7
- # Registers a to_prawn method on CodeRay. It returns an array of hashes to be
8
- # used with formatted_text.
9
- #
10
- # Usage:
11
- #
12
- # CodeRay.scan(string, :ruby).to_prawn
13
- #
14
- class PrawnEncoder < CodeRay::Encoders::Encoder
15
- register_for :to_prawn
16
-
17
- COLORS = { :default => "FFFFFF",
18
-
19
- :comment => "AEAEAE",
20
- :constant => "88A5D2",
21
- :instance_variable => "E8ED97",
22
- :integer => "C8FF0E",
23
- :float => "C8FF0E",
24
- :inline_delimiter => "EF804F", # #{} within a string
25
- :keyword => "FEE100",
26
-
27
- # BUG: There appear to be some problem with this token. Method
28
- # definitions are considered as ident tokens
29
- #
30
- :method => "FF5C00",
31
- :string => "56D65E",
32
- :symbol => "C8FF0E"
33
- }
34
-
35
- def setup(options)
36
- super
37
- @out = []
38
- @open = []
39
- end
5
+ class SyntaxHighlight
6
+ DEFAULT_STYLE = { color: 'FFFFFF' }.freeze
7
+ STRING_STYLE = { color: '56D65E' }.freeze
8
+ COMMENT_STYPE = { color: 'AEAEAE' }.freeze
9
+ CONSTANT_STYLE = { color: '88A5D2' }.freeze
10
+ IVAR_STYLE = { color: 'E8ED97' }.freeze
11
+ NUMBER_STYLE = { color: 'C8FF0E' }.freeze
12
+ EMBEXPR_STYLE = { color: 'EF804F' }.freeze
13
+ KEYWORD_STYLE = { color: 'FEE100' }.freeze
14
+ SYMBOL_STYLE = { color: 'C8FF0E' }.freeze
15
+ METHOD_STYLE = { color: 'FF5C00' }.freeze
40
16
 
41
- def text_token(text, kind)
42
- color = COLORS[kind] || COLORS[@open.last] || COLORS[:default]
43
-
44
- @out << {:text => text, :color => color}
17
+ def initialize(code)
18
+ @code = code
45
19
  end
46
20
 
47
- def begin_group(kind)
48
- @open << kind
21
+ def to_prawn
22
+ tokens.each_with_index.map do |token, index|
23
+ style =
24
+ case token.type
25
+ when :STRING_BEGIN, :STRING_CONTENT, :STRING_END, :HEREDOC_START, :HEREDOC_END
26
+ STRING_STYLE
27
+ when :COMMENT
28
+ COMMENT_STYPE
29
+ when :CONSTANT
30
+ CONSTANT_STYLE
31
+ when :INSTANCE_VARIABLE
32
+ IVAR_STYLE
33
+ when :INTEGER, :FLOAT, :INTEGER_RATIONAL, :INTEGER_IMAGINARY
34
+ NUMBER_STYLE
35
+ when :EMBEXPR_BEGIN, :EMBEXPR_END
36
+ EMBEXPR_STYLE
37
+ when /\AKEYWORD_/
38
+ KEYWORD_STYLE
39
+ when :SYMBOL_BEGIN, :LABEL
40
+ SYMBOL_STYLE
41
+ when :IDENTIFIER
42
+ case tokens[index - 1].type
43
+ when :SYMBOL_BEGIN
44
+ SYMBOL_STYLE
45
+ when :DOT
46
+ METHOD_STYLE
47
+ else
48
+ DEFAULT_STYLE
49
+ end
50
+ else
51
+ DEFAULT_STYLE
52
+ end
53
+ { text: token.value.gsub(' ', Prawn::Text::NBSP) }.merge(style)
54
+ end
55
+ .compact
56
+ .each_with_object([]) do |fragment, fragments|
57
+ if fragments.empty?
58
+ fragments << fragment
59
+ elsif fragments.last.reject { |k, _| k == :text} == fragment.reject { |k, _| k == :text } || fragment[:text].match?(/\A[#{Prawn::Text::NBSP}\s\t\r\n]*\z/)
60
+ fragments.last[:text] << fragment[:text]
61
+ else
62
+ fragments << fragment
63
+ end
64
+ end
49
65
  end
50
66
 
51
- def end_group(kind)
52
- @open.pop
67
+ private
68
+
69
+ attr_reader :code
70
+
71
+ def tokens
72
+ @tokens ||=
73
+ begin
74
+ result = Prism.lex(code)
75
+ tokens =
76
+ result.value
77
+ .map(&:first) # Only tokens
78
+
79
+ # 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)))
81
+
82
+ cursor = 0
83
+ # Add whitespace tokens
84
+ tokens
85
+ # Tokens are not sequential. Specifically, heredoc body is out of order.
86
+ # We don't want to add "backwards" whitespace tokens in that case.
87
+ .sort_by { |token| token.location.start_offset }
88
+ .each_cons(2)
89
+ .flat_map do |token, next_token|
90
+ if next_token.location.start_offset != token.location.end_offset
91
+ ws_location = Prism::Location.new(
92
+ result.source,
93
+ token.location.end_offset,
94
+ next_token.location.start_offset - token.location.end_offset
95
+ )
96
+ [
97
+ token,
98
+ Prism::Token.new(:PRAWN_WHITESPACE, ws_location.slice, ws_location)
99
+ ]
100
+ else
101
+ [token]
102
+ end
103
+ end
104
+ end
53
105
  end
54
106
  end
55
107
  end
@@ -0,0 +1,152 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+
5
+ module Prawn
6
+ module ManualBuilder
7
+ class TextRenderer
8
+ def initialize(doc, &text)
9
+ @doc = doc
10
+ @text = text
11
+ end
12
+
13
+ def render
14
+ return unless text
15
+
16
+ instance_eval(&text)
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :doc, :text
22
+
23
+ def header(str)
24
+ doc.font(HEADER_FONT, size: HEADER_FONT_SIZE) do
25
+ str.split(/\n\n+/).each do |paragraph|
26
+ doc.text(
27
+ paragraph.gsub(/\s+/," "),
28
+ align: :justify,
29
+ inline_format: true,
30
+ leading: LEADING,
31
+ color: DARK_GRAY)
32
+
33
+ doc.move_down(RHYTHM)
34
+ end
35
+ end
36
+
37
+ doc.move_down(RHYTHM)
38
+ end
39
+
40
+ def header_with_bg(header_text = [], header_options = { final_gap: false })
41
+ if header_text.is_a?(String)
42
+ header_text = [{ text: header_text }]
43
+ end
44
+ header_text = header_text.map { |fragment| { font: HEADER_FONT, size: HEADER_FONT_SIZE }.merge(fragment) }
45
+ text_height = doc.height_of_formatted(header_text, header_options)
46
+
47
+ doc.bounding_box(
48
+ [-doc.bounds.absolute_left, doc.cursor + PAGE_MARGIN],
49
+ width: doc.bounds.absolute_left + doc.bounds.absolute_right,
50
+ height: PAGE_MARGIN * 2 + text_height
51
+ ) do
52
+ doc.fill_color(LIGHT_GRAY)
53
+ doc.fill_rectangle(
54
+ [doc.bounds.left, doc.bounds.top],
55
+ doc.bounds.right,
56
+ doc.bounds.top - doc.bounds.bottom
57
+ )
58
+ doc.fill_color(BLACK)
59
+
60
+ doc.bounding_box(
61
+ [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
+ ) do
65
+ doc.formatted_text(header_text, header_options)
66
+ end
67
+ end
68
+
69
+ doc.stroke_color(GRAY)
70
+ doc.stroke_horizontal_line(-doc.bounds.absolute_left, doc.bounds.width + doc.bounds.absolute_right, at: doc.cursor)
71
+ doc.stroke_color(BLACK)
72
+
73
+ doc.move_down(RHYTHM * 3)
74
+ end
75
+
76
+ def prose(str)
77
+ doc.font(TEXT_FONT, size: TEXT_FONT_SIZE) do
78
+ extra_markup(str).split(/\n\n+/).each do |paragraph|
79
+ doc.text(
80
+ paragraph.gsub(/\s+/," "),
81
+ align: :justify,
82
+ inline_format: true,
83
+ leading: LEADING,
84
+ color: DARK_GRAY)
85
+
86
+ doc.move_down(RHYTHM)
87
+ end
88
+ end
89
+
90
+ doc.move_down(RHYTHM)
91
+ end
92
+
93
+ def list(*items)
94
+ doc.move_up(RHYTHM)
95
+
96
+ doc.font("DejaVu", size: 11) do
97
+ items.each do |li|
98
+ doc.float { doc.text("\u2022", size: doc.font_size * 1.25) }
99
+ doc.indent(RHYTHM) do
100
+ doc.text(
101
+ extra_markup(li).gsub(/\s+/, ' '),
102
+ inline_format: true,
103
+ color: DARK_GRAY,
104
+ leading: LEADING
105
+ )
106
+ end
107
+
108
+ doc.move_down(RHYTHM / 2)
109
+ end
110
+
111
+ doc.move_down(RHYTHM / 2)
112
+ end
113
+ end
114
+
115
+ def ordered_list(*items)
116
+ doc.move_up(RHYTHM)
117
+
118
+ doc.font("DejaVu", size: 11) do
119
+ counter_width = (1..items.size).to_a.map { |i| doc.width_of("#{i}.") }.max
120
+ space_width = doc.width_of(' ')
121
+ items.each_with_index do |li, i|
122
+ doc.float do
123
+ doc.bounding_box([0, doc.cursor], width: counter_width) do
124
+ doc.text("#{i + 1}.", color: DARK_GRAY, align: :right)
125
+ end
126
+ end
127
+ doc.indent(counter_width + space_width) do
128
+ doc.text(
129
+ extra_markup(li).gsub(/\s+/, ' '),
130
+ inline_format: true,
131
+ color: DARK_GRAY,
132
+ leading: LEADING
133
+ )
134
+ end
135
+
136
+ doc.move_down(RHYTHM / 2)
137
+ end
138
+
139
+ doc.move_down(RHYTHM / 2)
140
+ end
141
+ end
142
+
143
+ def extra_markup(str)
144
+ str
145
+ .gsub(/<code>([^<]+?)<\/code>/, '<font name="Iosevka"><b>\1</b></font>') # Process the <code> tags
146
+ .gsub(URI::Parser.new.make_regexp(%w[http https])) do |match|
147
+ %(<color rgb="#{BLUE}"><link href="#{match}">#{match.gsub('/', "/#{Prawn::Text::ZWSP}")}</link></color>) # Process the links
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Prawn
4
+ module ManualBuilder
5
+ VERSION = '0.4.0'
6
+ end
7
+ end
@@ -1,31 +1,40 @@
1
- require "enumerator"
2
-
3
1
  module Prawn
4
2
  module ManualBuilder
5
- def self.manual_dir=(dir)
6
- @manual_dir = dir
7
- end
3
+ DATADIR = File.dirname(__FILE__) + "/../../data"
4
+ NOT_SET = Object.new.freeze
8
5
 
9
- def self.manual_dir
10
- @manual_dir || Dir.pwd
11
- end
6
+ # Values used for the manual design:
12
7
 
13
- def self.document_class
14
- @document_class || Prawn::Document
15
- rescue NameError
16
- raise "Prawn::ManualBuilder.document_class was not set. "+
17
- "Either assign a custom document class, or make sure to install "+
18
- "and require the Prawn gem."
8
+ # Default margin
9
+ PAGE_MARGIN = 36
19
10
 
20
- end
11
+ # Additional indentation to keep the line measure with a reasonable size
12
+ INNER_MARGIN = 30
21
13
 
22
- DATADIR = File.dirname(__FILE__) + "/../../data"
14
+ # Vertical Rhythm settings
15
+ RHYTHM = 10
16
+ LEADING = 2
17
+
18
+ # Colors
19
+ BLACK = "000000"
20
+ LIGHT_GRAY = "F2F2F2"
21
+ GRAY = "DDDDDD"
22
+ DARK_GRAY = "333333"
23
+ BROWN = "A4441C"
24
+ ORANGE = "F28157"
25
+ LIGHT_GOLD = "FBFBBE"
26
+ DARK_GOLD = "EBE389"
27
+ BLUE = "0000D0"
28
+
29
+ HEADER_FONT = "DejaVu"
30
+ HEADER_FONT_SIZE = 18
31
+
32
+ CODE_FONT = 'Iosevka'
33
+ CODE_FONT_SIZE = 9
34
+
35
+ TEXT_FONT = 'DejaVu'
36
+ TEXT_FONT_SIZE = 10
23
37
  end
24
38
  end
25
39
 
26
- require_relative "manual_builder/example"
27
- require_relative "manual_builder/example_file"
28
- require_relative "manual_builder/example_section"
29
- require_relative "manual_builder/example_package"
30
- require_relative "manual_builder/syntax_highlight"
31
- require_relative "manual_builder/example"
40
+ require_relative "manual_builder/manual"
data.tar.gz.sig ADDED
Binary file
metadata CHANGED
@@ -1,34 +1,65 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prawn-manual_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
- - Felipe Doria
8
- - Gregory Brown
9
- autorequire:
7
+ - Alexander Mankuta
8
+ autorequire:
10
9
  bindir: bin
11
- cert_chain: []
12
- date: 2019-11-17 00:00:00.000000000 Z
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIC+jCCAeKgAwIBAgIBAzANBgkqhkiG9w0BAQsFADAjMSEwHwYDVQQDDBhhbGV4
14
+ L0RDPXBvaW50bGVzcy9EQz1vbmUwHhcNMjMxMTA5MTA1MzIxWhcNMjQxMTA4MTA1
15
+ MzIxWjAjMSEwHwYDVQQDDBhhbGV4L0RDPXBvaW50bGVzcy9EQz1vbmUwggEiMA0G
16
+ CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPOVLPGEK+eaP6zJfifrpWvPTg4qo3
17
+ XNJJPom80SwqX2hVCVsRDK4RYgKUQqKRQzHhlx14wZHwWLETBVbNDGX3uqyCnTWU
18
+ JUKh3ydiZShXpNHoV/NW7hhEYvNsDcBAjYTmbvXOhuYCo0Tz/0N2Oiun/0wIICtP
19
+ vytY9TY0/lklWjAbsqJjNOu3o8IYkJBAN/rU96E/6WhFwjnxLcTnV9RfFRXdjG5j
20
+ CughoB2xSwKX8gwbQ8fsnaZRmdyDGYNpz6sGF0zycfiLkTttbLA2nYATCALy98CH
21
+ nsyZNsTjb4WINCuY2yEDjwesw9f/ROkNC68EgQ5M+aMjp+D0WcYGfzojAgMBAAGj
22
+ OTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBRPgIwSVbeonua/
23
+ Ny/8576oxdUbrjANBgkqhkiG9w0BAQsFAAOCAQEAX28QLxNNz5EgaZZuQQUkbOXB
24
+ 4b5luBO22535+Vgj2jw7yjV8KKoGMWKrnB00ijgntqPEPXCzaPNibOcPZV5WfWVS
25
+ t0Ls8lWE/8kezPwV4SbRe4Y7C+D4J+oirs0L5PtpREV9CJ7kfdW/AN9MtvjjBFlb
26
+ jHquD/MiOOMyHtuO0FiTL265m10thcAUsbyi0MehKgGbtJ5fGceHvZDqDouvbMjT
27
+ hoijFk1oTY939JhjdcHuJzMiS2TrqIw8Dr5DkQu2vAjHpw0aOOWhlRjNJ7RHYJNm
28
+ QugXmCnHQxSKTmc7imKuotyMdRRKFh8UEFCLRsFtBbNxkXyNuB4xBMuUYodhEw==
29
+ -----END CERTIFICATE-----
30
+ date: 2024-02-11 00:00:00.000000000 Z
13
31
  dependencies:
14
32
  - !ruby/object:Gem::Dependency
15
- name: coderay
33
+ name: prawn
16
34
  requirement: !ruby/object:Gem::Requirement
17
35
  requirements:
18
36
  - - "~>"
19
37
  - !ruby/object:Gem::Version
20
- version: 1.0.7
38
+ version: 2.4.0
21
39
  type: :runtime
22
40
  prerelease: false
23
41
  version_requirements: !ruby/object:Gem::Requirement
24
42
  requirements:
25
43
  - - "~>"
26
44
  - !ruby/object:Gem::Version
27
- version: 1.0.7
45
+ version: 2.4.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: prism
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: 0.22.0
53
+ type: :runtime
54
+ prerelease: false
55
+ version_requirements: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: 0.22.0
28
60
  description: A tool for writing manuals for Prawn and Prawn accessories
29
61
  email:
30
- - felipe.doria@gmail.com
31
- - gregory.t.brown@gmail.com
62
+ - alex@pointless.one
32
63
  executables: []
33
64
  extensions: []
34
65
  extra_rdoc_files: []
@@ -38,22 +69,32 @@ files:
38
69
  - GPLv3
39
70
  - LICENSE
40
71
  - README.md
72
+ - data/fonts/DejaVuSans-Bold.ttf
73
+ - data/fonts/DejaVuSans-BoldOblique.ttf
74
+ - data/fonts/DejaVuSans-Oblique.ttf
41
75
  - data/fonts/DejaVuSans.ttf
42
- - data/fonts/Dustismo_Roman.ttf
43
- - data/fonts/gkai00mp.ttf
76
+ - data/fonts/Jigmo.ttf
77
+ - data/fonts/Jigmo2.ttf
78
+ - data/fonts/Jigmo3.ttf
79
+ - data/fonts/Panic+Sans.dfont
80
+ - data/fonts/iosevka-po-bold.ttf
81
+ - data/fonts/iosevka-po-regular.ttf
44
82
  - lib/prawn/manual_builder.rb
45
- - lib/prawn/manual_builder/example.rb
46
- - lib/prawn/manual_builder/example_file.rb
47
- - lib/prawn/manual_builder/example_package.rb
48
- - lib/prawn/manual_builder/example_section.rb
83
+ - lib/prawn/manual_builder/chapter.rb
84
+ - lib/prawn/manual_builder/manual.rb
85
+ - lib/prawn/manual_builder/part.rb
86
+ - lib/prawn/manual_builder/peritext.rb
87
+ - lib/prawn/manual_builder/section.rb
49
88
  - lib/prawn/manual_builder/syntax_highlight.rb
50
- homepage:
89
+ - lib/prawn/manual_builder/text_renderer.rb
90
+ - lib/prawn/manual_builder/version.rb
91
+ homepage:
51
92
  licenses:
52
93
  - PRAWN
53
94
  - GPL-2.0
54
95
  - GPL-3.0
55
96
  metadata: {}
56
- post_install_message:
97
+ post_install_message:
57
98
  rdoc_options: []
58
99
  require_paths:
59
100
  - lib
@@ -61,15 +102,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
61
102
  requirements:
62
103
  - - ">="
63
104
  - !ruby/object:Gem::Version
64
- version: 1.9.3
105
+ version: '2.7'
65
106
  required_rubygems_version: !ruby/object:Gem::Requirement
66
107
  requirements:
67
108
  - - ">="
68
109
  - !ruby/object:Gem::Version
69
110
  version: '0'
70
111
  requirements: []
71
- rubygems_version: 3.0.3
72
- signing_key:
112
+ rubygems_version: 3.5.3
113
+ signing_key:
73
114
  specification_version: 4
74
115
  summary: A tool for writing manuals for Prawn and Prawn accessories
75
116
  test_files: []
metadata.gz.sig ADDED
@@ -0,0 +1 @@
1
+ ����v��.%Y�a=�'^ó������M ��SJ�|�,U���~ef�Ii-$ĉ�s�7
Binary file
Binary file