squib 0.14.2 → 0.14.3.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +41 -41
  3. data/.travis.yml +19 -19
  4. data/CHANGELOG.md +366 -357
  5. data/CONTRIBUTING.md +40 -40
  6. data/Gemfile +2 -2
  7. data/LICENSE.txt +22 -22
  8. data/README.md +121 -121
  9. data/RELEASE TODO.md +21 -21
  10. data/Rakefile +48 -48
  11. data/appveyor.yml +24 -24
  12. data/bin/squib +4 -4
  13. data/lib/squib.rb +32 -32
  14. data/lib/squib/api/background.rb +15 -15
  15. data/lib/squib/api/data.rb +137 -137
  16. data/lib/squib/api/groups.rb +54 -54
  17. data/lib/squib/api/image.rb +49 -49
  18. data/lib/squib/api/save.rb +83 -83
  19. data/lib/squib/api/settings.rb +21 -21
  20. data/lib/squib/api/shapes.rb +124 -124
  21. data/lib/squib/api/text.rb +25 -25
  22. data/lib/squib/api/text_embed.rb +71 -71
  23. data/lib/squib/api/units.rb +27 -27
  24. data/lib/squib/args/arg_loader.rb +126 -126
  25. data/lib/squib/args/box.rb +55 -55
  26. data/lib/squib/args/card_range.rb +32 -32
  27. data/lib/squib/args/color_validator.rb +12 -12
  28. data/lib/squib/args/coords.rb +35 -35
  29. data/lib/squib/args/csv_opts.rb +25 -25
  30. data/lib/squib/args/dir_validator.rb +16 -16
  31. data/lib/squib/args/draw.rb +92 -92
  32. data/lib/squib/args/embed_adjust.rb +25 -25
  33. data/lib/squib/args/embed_key.rb +17 -17
  34. data/lib/squib/args/hand_special.rb +37 -37
  35. data/lib/squib/args/import.rb +40 -40
  36. data/lib/squib/args/input_file.rb +37 -37
  37. data/lib/squib/args/paint.rb +44 -44
  38. data/lib/squib/args/paragraph.rb +116 -116
  39. data/lib/squib/args/save_batch.rb +63 -63
  40. data/lib/squib/args/scale_box.rb +53 -53
  41. data/lib/squib/args/sheet.rb +172 -172
  42. data/lib/squib/args/showcase_special.rb +38 -38
  43. data/lib/squib/args/sprue_file.rb +44 -44
  44. data/lib/squib/args/svg_special.rb +37 -37
  45. data/lib/squib/args/transform.rb +61 -61
  46. data/lib/squib/args/typographer.rb +119 -119
  47. data/lib/squib/args/unit_conversion.rb +29 -29
  48. data/lib/squib/builtin/layouts/economy.yml +85 -85
  49. data/lib/squib/builtin/layouts/fantasy.yml +101 -101
  50. data/lib/squib/builtin/layouts/hand.yml +62 -62
  51. data/lib/squib/builtin/layouts/party.yml +94 -94
  52. data/lib/squib/builtin/layouts/playing-card.yml +35 -35
  53. data/lib/squib/builtin/layouts/tuck_box.yml +46 -46
  54. data/lib/squib/builtin/projects/advanced/.gitignore +4 -4
  55. data/lib/squib/builtin/projects/advanced/ABOUT.md +19 -19
  56. data/lib/squib/builtin/projects/advanced/Gemfile +11 -11
  57. data/lib/squib/builtin/projects/advanced/Guardfile +21 -21
  58. data/lib/squib/builtin/projects/advanced/IDEAS.md +22 -22
  59. data/lib/squib/builtin/projects/advanced/PLAYTESTING.md +26 -26
  60. data/lib/squib/builtin/projects/advanced/Rakefile +27 -27
  61. data/lib/squib/builtin/projects/advanced/config.yml +53 -49
  62. data/lib/squib/builtin/projects/advanced/docs/PNP NOTES.md +3 -3
  63. data/lib/squib/builtin/projects/advanced/docs/RULES.md +21 -21
  64. data/lib/squib/builtin/projects/advanced/img/example.svg +60 -60
  65. data/lib/squib/builtin/projects/advanced/layouts/deck.yml +27 -27
  66. data/lib/squib/builtin/projects/advanced/src/deck.rb +34 -34
  67. data/lib/squib/builtin/projects/advanced/src/version.rb +3 -3
  68. data/lib/squib/builtin/projects/basic/.gitignore +4 -4
  69. data/lib/squib/builtin/projects/basic/ABOUT.md +19 -19
  70. data/lib/squib/builtin/projects/basic/Gemfile +3 -3
  71. data/lib/squib/builtin/projects/basic/IDEAS.md +22 -22
  72. data/lib/squib/builtin/projects/basic/PLAYTESTING.md +26 -26
  73. data/lib/squib/builtin/projects/basic/PNP NOTES.md +3 -3
  74. data/lib/squib/builtin/projects/basic/RULES.md +21 -21
  75. data/lib/squib/builtin/projects/basic/Rakefile +7 -7
  76. data/lib/squib/builtin/projects/basic/config.yml +53 -49
  77. data/lib/squib/builtin/projects/basic/deck.rb +6 -6
  78. data/lib/squib/builtin/sprues/a4_euro_card.yml +42 -42
  79. data/lib/squib/builtin/sprues/a4_poker_card_8up.yml +40 -40
  80. data/lib/squib/builtin/sprues/a4_poker_card_9up.yml +42 -42
  81. data/lib/squib/builtin/sprues/a4_usa_card.yml +42 -42
  82. data/lib/squib/builtin/sprues/drivethrucards_1up.yml +10 -10
  83. data/lib/squib/builtin/sprues/letter_poker_card_9up.yml +25 -25
  84. data/lib/squib/builtin/sprues/letter_poker_foldable_8up.yml +52 -52
  85. data/lib/squib/builtin/sprues/printplaygames_18up.yml +68 -68
  86. data/lib/squib/card.rb +75 -75
  87. data/lib/squib/commands/cli.rb +39 -39
  88. data/lib/squib/commands/data/template_option.rb +109 -109
  89. data/lib/squib/commands/make_sprue.rb +275 -275
  90. data/lib/squib/commands/new.rb +77 -77
  91. data/lib/squib/conf.rb +144 -139
  92. data/lib/squib/constants.rb +17 -17
  93. data/lib/squib/deck.rb +116 -116
  94. data/lib/squib/graphics/background.rb +14 -14
  95. data/lib/squib/graphics/cairo_context_wrapper.rb +113 -113
  96. data/lib/squib/graphics/embedding_utils.rb +28 -28
  97. data/lib/squib/graphics/gradient_regex.rb +47 -47
  98. data/lib/squib/graphics/hand.rb +42 -42
  99. data/lib/squib/graphics/image.rb +129 -108
  100. data/lib/squib/graphics/save_doc.rb +61 -61
  101. data/lib/squib/graphics/save_images.rb +52 -52
  102. data/lib/squib/graphics/save_pdf.rb +90 -90
  103. data/lib/squib/graphics/save_sprue.rb +204 -204
  104. data/lib/squib/graphics/shapes.rb +143 -143
  105. data/lib/squib/graphics/showcase.rb +85 -85
  106. data/lib/squib/graphics/text.rb +174 -174
  107. data/lib/squib/import/data_frame.rb +108 -108
  108. data/lib/squib/layout_parser.rb +138 -138
  109. data/lib/squib/progress.rb +38 -38
  110. data/lib/squib/sample_helpers.rb +34 -34
  111. data/lib/squib/sprues/crop_line.rb +28 -28
  112. data/lib/squib/sprues/crop_line_dash.rb +35 -35
  113. data/lib/squib/sprues/invalid_sprue_definition.rb +9 -9
  114. data/lib/squib/sprues/sprue.rb +203 -203
  115. data/lib/squib/sprues/sprue_schema.rb +48 -48
  116. data/lib/squib/version.rb +10 -10
  117. data/samples/autoscale_font/_autoscale_font.rb +29 -29
  118. data/samples/backend/_backend.rb +26 -26
  119. data/samples/basic.rb +19 -19
  120. data/samples/bug256/_bug256.rb +13 -0
  121. data/samples/build_groups/build_groups.rb +36 -36
  122. data/samples/colors/_colors.rb +38 -38
  123. data/samples/colors/_gradients.rb +34 -34
  124. data/samples/config/config_text_markup.rb +20 -20
  125. data/samples/config/custom_config.rb +18 -18
  126. data/samples/data/_csv.rb +33 -33
  127. data/samples/data/_excel.rb +55 -55
  128. data/samples/data/_yaml.rb +12 -12
  129. data/samples/hello_world.rb +6 -6
  130. data/samples/images/_cairo_access.rb +39 -39
  131. data/samples/images/_images.rb +104 -104
  132. data/samples/images/_more_load_images.rb +102 -102
  133. data/samples/intro/01_hello.rb +8 -8
  134. data/samples/intro/02_options.rb +14 -14
  135. data/samples/intro/03_layout.rb +11 -11
  136. data/samples/intro/04_arrays.rb +15 -15
  137. data/samples/intro/05_excel.rb +14 -14
  138. data/samples/layouts/builtin_layouts.rb +97 -97
  139. data/samples/layouts/layouts.rb +71 -71
  140. data/samples/project/src/characters.rb +8 -8
  141. data/samples/project/src/skills.rb +7 -7
  142. data/samples/proofs/_tgc_proofs.rb +16 -16
  143. data/samples/ranges/_ranges.rb +64 -64
  144. data/samples/saves/_hand.rb +23 -23
  145. data/samples/saves/_portrait_landscape.rb +23 -23
  146. data/samples/saves/_save_pdf.rb +29 -29
  147. data/samples/saves/_saves.rb +51 -51
  148. data/samples/saves/_showcase.rb +25 -25
  149. data/samples/shapes/_draw_shapes.rb +60 -60
  150. data/samples/shapes/_proofs.rb +22 -22
  151. data/samples/sprues/_advanced_sprues.rb +24 -24
  152. data/samples/sprues/_builtin_sprues.rb +21 -21
  153. data/samples/sprues/_fold_sheet.rb +27 -27
  154. data/samples/sprues/_hex_tiles.rb +15 -15
  155. data/samples/sprues/_mints.rb +11 -11
  156. data/samples/sprues/_sprue_example.rb +11 -11
  157. data/samples/text/_embed_text.rb +128 -128
  158. data/samples/text/_text.rb +47 -47
  159. data/samples/text/_text_options.rb +102 -102
  160. data/samples/text/bug134.rb +14 -14
  161. data/samples/units/_units.rb +32 -32
  162. data/squib.gemspec +52 -52
  163. metadata +51 -48
@@ -1,38 +1,38 @@
1
- require 'cairo'
2
- require_relative 'arg_loader'
3
- require_relative 'dir_validator'
4
-
5
- module Squib
6
- # @api private
7
- module Args
8
-
9
- class ShowcaseSpecial
10
- include ArgLoader
11
- include DirValidator
12
-
13
- def self.parameters
14
- { scale: 0.85,
15
- offset: 1.1,
16
- reflect_offset: 15,
17
- reflect_percent: 0.25,
18
- reflect_strength: 0.2,
19
- face: :left,
20
- }
21
- end
22
-
23
- def self.expanding_parameters
24
- [] # none of them
25
- end
26
-
27
- def self.params_with_units
28
- [ :reflect_offset ]
29
- end
30
-
31
- def face_right?
32
- @face.to_s.strip.downcase == 'right'
33
- end
34
-
35
- end
36
-
37
- end
38
- end
1
+ require 'cairo'
2
+ require_relative 'arg_loader'
3
+ require_relative 'dir_validator'
4
+
5
+ module Squib
6
+ # @api private
7
+ module Args
8
+
9
+ class ShowcaseSpecial
10
+ include ArgLoader
11
+ include DirValidator
12
+
13
+ def self.parameters
14
+ { scale: 0.85,
15
+ offset: 1.1,
16
+ reflect_offset: 15,
17
+ reflect_percent: 0.25,
18
+ reflect_strength: 0.2,
19
+ face: :left,
20
+ }
21
+ end
22
+
23
+ def self.expanding_parameters
24
+ [] # none of them
25
+ end
26
+
27
+ def self.params_with_units
28
+ [ :reflect_offset ]
29
+ end
30
+
31
+ def face_right?
32
+ @face.to_s.strip.downcase == 'right'
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+ end
@@ -1,44 +1,44 @@
1
- require_relative 'arg_loader'
2
-
3
- module Squib
4
- # @api private
5
- module Args
6
- class SprueFile
7
- include ArgLoader
8
-
9
- def initialize(dsl_method_default = {})
10
- @dsl_method_default = dsl_method_default
11
- end
12
-
13
- def self.parameters
14
- {
15
- sprue: nil
16
- }
17
- end
18
-
19
- def self.expanding_parameters
20
- []
21
- end
22
-
23
- def self.params_with_units
24
- [] # none of them
25
- end
26
-
27
- def validate_template_file(arg)
28
- return nil if arg.nil?
29
-
30
- thefile = File.exist?(arg) ? arg : builtin(arg)
31
- raise "File #{File.expand_path(arg)} does not exist!" unless
32
- File.exist? thefile
33
-
34
- File.expand_path(thefile)
35
- end
36
-
37
- private
38
-
39
- def builtin(file)
40
- "#{File.dirname(__FILE__)}/../builtin/sprues/#{file}"
41
- end
42
- end
43
- end
44
- end
1
+ require_relative 'arg_loader'
2
+
3
+ module Squib
4
+ # @api private
5
+ module Args
6
+ class SprueFile
7
+ include ArgLoader
8
+
9
+ def initialize(dsl_method_default = {})
10
+ @dsl_method_default = dsl_method_default
11
+ end
12
+
13
+ def self.parameters
14
+ {
15
+ sprue: nil
16
+ }
17
+ end
18
+
19
+ def self.expanding_parameters
20
+ []
21
+ end
22
+
23
+ def self.params_with_units
24
+ [] # none of them
25
+ end
26
+
27
+ def validate_template_file(arg)
28
+ return nil if arg.nil?
29
+
30
+ thefile = File.exist?(arg) ? arg : builtin(arg)
31
+ raise "File #{File.expand_path(arg)} does not exist!" unless
32
+ File.exist? thefile
33
+
34
+ File.expand_path(thefile)
35
+ end
36
+
37
+ private
38
+
39
+ def builtin(file)
40
+ "#{File.dirname(__FILE__)}/../builtin/sprues/#{file}"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,37 +1,37 @@
1
- require_relative 'arg_loader'
2
-
3
- module Squib
4
- # @api private
5
- module Args
6
-
7
- class SvgSpecial
8
- include ArgLoader
9
-
10
- def self.parameters
11
- { data: nil, id: nil, force_id: false }
12
- end
13
-
14
- def self.expanding_parameters
15
- parameters.keys # all of them
16
- end
17
-
18
- def self.params_with_units
19
- []
20
- end
21
-
22
- def validate_id(arg, _i)
23
- return nil if arg.nil?
24
- arg = '#' << arg unless arg.start_with? '#'
25
- arg
26
- end
27
-
28
- # Only render if we have an ID specified, or we are forcing an ID
29
- def render?(i)
30
- return false if force_id[i] && id[i].to_s.empty?
31
- return true
32
- end
33
-
34
- end
35
-
36
- end
37
- end
1
+ require_relative 'arg_loader'
2
+
3
+ module Squib
4
+ # @api private
5
+ module Args
6
+
7
+ class SvgSpecial
8
+ include ArgLoader
9
+
10
+ def self.parameters
11
+ { data: nil, id: nil, force_id: false }
12
+ end
13
+
14
+ def self.expanding_parameters
15
+ parameters.keys # all of them
16
+ end
17
+
18
+ def self.params_with_units
19
+ []
20
+ end
21
+
22
+ def validate_id(arg, _i)
23
+ return nil if arg.nil?
24
+ arg = '#' << arg unless arg.start_with? '#'
25
+ arg
26
+ end
27
+
28
+ # Only render if we have an ID specified, or we are forcing an ID
29
+ def render?(i)
30
+ return false if force_id[i] && id[i].to_s.empty?
31
+ return true
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+ end
@@ -1,61 +1,61 @@
1
- require_relative 'arg_loader'
2
-
3
- module Squib
4
- # @api private
5
- module Args
6
-
7
- class Transform
8
- include ArgLoader
9
-
10
- def initialize(deck = nil)
11
- @deck = deck
12
- end
13
-
14
- def self.parameters
15
- { angle: 0,
16
- crop_x: 0,
17
- crop_y: 0,
18
- crop_width: :native,
19
- crop_height: :native,
20
- crop_corner_radius: nil,
21
- crop_corner_x_radius: 0,
22
- crop_corner_y_radius: 0,
23
- flip_vertical: false,
24
- flip_horizontal: false,
25
- }
26
- end
27
-
28
- def self.expanding_parameters
29
- parameters.keys # all of them
30
- end
31
-
32
- def self.params_with_units
33
- parameters.keys - [:flip_vertical, :flip_horizontal]
34
- end
35
-
36
- def validate_crop_width(arg, _i)
37
- return arg if @deck.nil?
38
- return @deck.width if arg == :deck
39
- arg
40
- end
41
-
42
- def validate_crop_height(arg, _i)
43
- return arg if @deck.nil?
44
- return @deck.height if arg == :deck
45
- arg
46
- end
47
-
48
- def validate_crop_corner_x_radius(arg, i)
49
- return crop_corner_radius[i] unless crop_corner_radius[i].nil?
50
- arg
51
- end
52
-
53
- def validate_crop_corner_y_radius(arg, i)
54
- return crop_corner_radius[i] unless crop_corner_radius[i].nil?
55
- arg
56
- end
57
-
58
- end
59
-
60
- end
61
- end
1
+ require_relative 'arg_loader'
2
+
3
+ module Squib
4
+ # @api private
5
+ module Args
6
+
7
+ class Transform
8
+ include ArgLoader
9
+
10
+ def initialize(deck = nil)
11
+ @deck = deck
12
+ end
13
+
14
+ def self.parameters
15
+ { angle: 0,
16
+ crop_x: 0,
17
+ crop_y: 0,
18
+ crop_width: :native,
19
+ crop_height: :native,
20
+ crop_corner_radius: nil,
21
+ crop_corner_x_radius: 0,
22
+ crop_corner_y_radius: 0,
23
+ flip_vertical: false,
24
+ flip_horizontal: false,
25
+ }
26
+ end
27
+
28
+ def self.expanding_parameters
29
+ parameters.keys # all of them
30
+ end
31
+
32
+ def self.params_with_units
33
+ parameters.keys - [:flip_vertical, :flip_horizontal]
34
+ end
35
+
36
+ def validate_crop_width(arg, _i)
37
+ return arg if @deck.nil?
38
+ return @deck.width if arg == :deck
39
+ arg
40
+ end
41
+
42
+ def validate_crop_height(arg, _i)
43
+ return arg if @deck.nil?
44
+ return @deck.height if arg == :deck
45
+ arg
46
+ end
47
+
48
+ def validate_crop_corner_x_radius(arg, i)
49
+ return crop_corner_radius[i] unless crop_corner_radius[i].nil?
50
+ arg
51
+ end
52
+
53
+ def validate_crop_corner_y_radius(arg, i)
54
+ return crop_corner_radius[i] unless crop_corner_radius[i].nil?
55
+ arg
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
@@ -1,119 +1,119 @@
1
- require_relative '../constants'
2
-
3
- module Squib
4
- # @api private
5
- module Args
6
- # Internal class for handling arguments
7
- # @api private
8
- class Typographer
9
-
10
- def initialize(config = Conf::DEFAULTS)
11
- %w(lsquote ldquote rsquote rdquote smart_quotes
12
- em_dash en_dash ellipsis).each do |var|
13
- instance_variable_set("@#{var}", config[var])
14
- end
15
- end
16
-
17
- def process(str)
18
- str = explicit_replacements(str.to_s)
19
- str = smart_quotes(str) if @smart_quotes
20
- str
21
- end
22
-
23
- def explicit_replacements(str)
24
- [ :left_curly, :right_curly, :apostraphize,
25
- :ellipsificate, :em_dash, :en_dash ].each do |sym|
26
- str = each_non_tag(str) do |token|
27
- self.method(sym).call(token)
28
- end
29
- end
30
- str
31
- end
32
-
33
- def smart_quotes(str)
34
- [ :single_inside_double_quote,
35
- :right_double_quote,
36
- :left_double_quote,
37
- :right_single_quote,
38
- :left_single_quote].each do |sym|
39
- str = each_non_tag(str) do |token|
40
- self.method(sym).call(token)
41
- end
42
- end
43
- str
44
- end
45
-
46
- # Iterate over each non-tag for processing
47
- # Allows us to ignore anything inside < and >
48
- def each_non_tag(str)
49
- full_str = ''
50
- tag_delimit = /(<(?:(?!<).)*>)/ # use non-capturing group w/ negative lookahead
51
- str.split(tag_delimit).each do |token|
52
- if token.start_with? '<'
53
- full_str << token # don't process tags
54
- else
55
- full_str << yield(token)
56
- end
57
- end
58
- return full_str
59
- end
60
-
61
- # Straightforward replace
62
- def left_curly(str)
63
- str.gsub('``', @ldquote)
64
- end
65
-
66
- # Straightforward replace
67
- def right_curly(str)
68
- str.gsub(%{''}, @rdquote)
69
- end
70
-
71
- # A quote between two letters is an apostraphe
72
- def apostraphize(str)
73
- str.gsub(/(\w)(\')(\w)/, '\1' + @rsquote + '\3')
74
- end
75
-
76
- # Straightforward replace
77
- def ellipsificate(str)
78
- str.gsub('...', @ellipsis)
79
- end
80
-
81
- # Straightforward replace
82
- def en_dash(str)
83
- str.gsub('--', @en_dash)
84
- end
85
-
86
- # Straightforward replace
87
- def em_dash(str)
88
- str.gsub('---', @em_dash)
89
- end
90
-
91
- # Quote next to non-whitespace curls
92
- def right_double_quote(str)
93
- str.gsub(/(\S)(\")/, '\1' + @rdquote)
94
- end
95
-
96
- # Quote next to non-whitespace curls
97
- def left_double_quote(str)
98
- str.gsub(/(\")(\S)/, @ldquote + '\2')
99
- end
100
-
101
- # Handle the cases where a double quote is next to a single quote
102
- def single_inside_double_quote(str)
103
- str.gsub(/(\")(\')(\S)/, @ldquote + @lsquote + '\3')
104
- .gsub(/(\")(\')(\S)/, '\1' + @rsquote + @rdquote)
105
- end
106
-
107
- # Quote next to non-whitespace curls
108
- def right_single_quote(str)
109
- str.gsub(/(\S)(\')/, '\1' + @rsquote)
110
- end
111
-
112
- # Quote next to non-whitespace curls
113
- def left_single_quote(str)
114
- str.gsub(/(\')(\S)/, @lsquote + '\2')
115
- end
116
-
117
- end
118
- end
119
- end
1
+ require_relative '../constants'
2
+
3
+ module Squib
4
+ # @api private
5
+ module Args
6
+ # Internal class for handling arguments
7
+ # @api private
8
+ class Typographer
9
+
10
+ def initialize(config = Conf::DEFAULTS)
11
+ %w(lsquote ldquote rsquote rdquote smart_quotes
12
+ em_dash en_dash ellipsis).each do |var|
13
+ instance_variable_set("@#{var}", config[var])
14
+ end
15
+ end
16
+
17
+ def process(str)
18
+ str = explicit_replacements(str.to_s)
19
+ str = smart_quotes(str) if @smart_quotes
20
+ str
21
+ end
22
+
23
+ def explicit_replacements(str)
24
+ [ :left_curly, :right_curly, :apostraphize,
25
+ :ellipsificate, :em_dash, :en_dash ].each do |sym|
26
+ str = each_non_tag(str) do |token|
27
+ self.method(sym).call(token)
28
+ end
29
+ end
30
+ str
31
+ end
32
+
33
+ def smart_quotes(str)
34
+ [ :single_inside_double_quote,
35
+ :right_double_quote,
36
+ :left_double_quote,
37
+ :right_single_quote,
38
+ :left_single_quote].each do |sym|
39
+ str = each_non_tag(str) do |token|
40
+ self.method(sym).call(token)
41
+ end
42
+ end
43
+ str
44
+ end
45
+
46
+ # Iterate over each non-tag for processing
47
+ # Allows us to ignore anything inside < and >
48
+ def each_non_tag(str)
49
+ full_str = ''
50
+ tag_delimit = /(<(?:(?!<).)*>)/ # use non-capturing group w/ negative lookahead
51
+ str.split(tag_delimit).each do |token|
52
+ if token.start_with? '<'
53
+ full_str << token # don't process tags
54
+ else
55
+ full_str << yield(token)
56
+ end
57
+ end
58
+ return full_str
59
+ end
60
+
61
+ # Straightforward replace
62
+ def left_curly(str)
63
+ str.gsub('``', @ldquote)
64
+ end
65
+
66
+ # Straightforward replace
67
+ def right_curly(str)
68
+ str.gsub(%{''}, @rdquote)
69
+ end
70
+
71
+ # A quote between two letters is an apostraphe
72
+ def apostraphize(str)
73
+ str.gsub(/(\w)(\')(\w)/, '\1' + @rsquote + '\3')
74
+ end
75
+
76
+ # Straightforward replace
77
+ def ellipsificate(str)
78
+ str.gsub('...', @ellipsis)
79
+ end
80
+
81
+ # Straightforward replace
82
+ def en_dash(str)
83
+ str.gsub('--', @en_dash)
84
+ end
85
+
86
+ # Straightforward replace
87
+ def em_dash(str)
88
+ str.gsub('---', @em_dash)
89
+ end
90
+
91
+ # Quote next to non-whitespace curls
92
+ def right_double_quote(str)
93
+ str.gsub(/(\S)(\")/, '\1' + @rdquote)
94
+ end
95
+
96
+ # Quote next to non-whitespace curls
97
+ def left_double_quote(str)
98
+ str.gsub(/(\")(\S)/, @ldquote + '\2')
99
+ end
100
+
101
+ # Handle the cases where a double quote is next to a single quote
102
+ def single_inside_double_quote(str)
103
+ str.gsub(/(\")(\')(\S)/, @ldquote + @lsquote + '\3')
104
+ .gsub(/(\")(\')(\S)/, '\1' + @rsquote + @rdquote)
105
+ end
106
+
107
+ # Quote next to non-whitespace curls
108
+ def right_single_quote(str)
109
+ str.gsub(/(\S)(\')/, '\1' + @rsquote)
110
+ end
111
+
112
+ # Quote next to non-whitespace curls
113
+ def left_single_quote(str)
114
+ str.gsub(/(\')(\S)/, @lsquote + '\2')
115
+ end
116
+
117
+ end
118
+ end
119
+ end