marked-conductor 1.0.27 → 1.0.28

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Hash helpers
3
4
  class ::Hash
5
+ ##
6
+ ## Destructive version of #symbolize_keys
7
+ ##
8
+ ## @see #symbolize_keys
9
+ ##
10
+ ## @return [Hash] hash with keys as symbols
11
+ ##
4
12
  def symbolize_keys!
5
13
  replace symbolize_keys
6
14
  end
7
15
 
16
+ ##
17
+ ## Convert all keys in hash to symbols. Works on nested hashes
18
+ ##
19
+ ## @see #symbolize_keys!
20
+ ##
21
+ ## @return [Hash] hash with keys as symbols
22
+ ##
8
23
  def symbolize_keys
9
24
  each_with_object({}) { |(k, v), hsh| hsh[k.to_sym] = (v.is_a?(Hash) || v.is_a?(Array)) ? v.symbolize_keys : v }
10
25
  end
@@ -22,7 +22,7 @@ module Conductor
22
22
  ## @param path The path
23
23
  ##
24
24
  def path=(path)
25
- @path = if %r{^[%/]}.match?(path)
25
+ @path = if %r{^[~/.]}.match?(path)
26
26
  File.expand_path(path)
27
27
  else
28
28
  script_dir = File.expand_path("~/.config/conductor/scripts")
@@ -56,7 +56,7 @@ module Conductor
56
56
  ## @return [String] script results (STDOUT)
57
57
  ##
58
58
  def run
59
- stdin = Conductor.stdin
59
+ stdin = Conductor.stdin unless /\$\{?file\}?/.match?(args)
60
60
 
61
61
  raise "Script path not defined" unless @path
62
62
 
@@ -15,6 +15,11 @@ class ::String
15
15
  split(/,/).map { |s| Shellwords.shellsplit(s) }
16
16
  end
17
17
 
18
+ ##
19
+ ## Normalize positional string to symbol
20
+ ##
21
+ ## @return [Symbol] position symbol (:start, :h1, :h2, :end)
22
+ ##
18
23
  def normalize_position
19
24
  case self
20
25
  when /^(be|s|t)/
@@ -28,6 +33,11 @@ class ::String
28
33
  end
29
34
  end
30
35
 
36
+ ##
37
+ ## Normalize a file include string to symbol
38
+ ##
39
+ ## @return [Symbol] include type symbol (:code, :raw, :file)
40
+ ##
31
41
  def normalize_include_type
32
42
  case self
33
43
  when /^c/
@@ -61,7 +71,7 @@ class ::String
61
71
  ## @return [Boolean] test result
62
72
  ##
63
73
  def date?
64
- dup.force_encoding("utf-8").match?(/^\d{4}-\d{2}-\d{2}( \d\d:\d\d)?$/)
74
+ dup.force_encoding("utf-8") =~ /^\d{4}-\d{2}-\d{2}( \d{1,2}(:\d\d)? *([ap]m)?)?$/ ? true : false
65
75
  end
66
76
 
67
77
  ##
@@ -70,7 +80,7 @@ class ::String
70
80
  ## @return [Boolean] test result
71
81
  ##
72
82
  def time?
73
- dup.force_encoding("utf-8").match(/ \d{1,2}(:\d\d)? *([ap]m)?/i)
83
+ dup.force_encoding("utf-8") =~ / \d{1,2}(:\d\d)? *([ap]m)?/i ? true : false
74
84
  end
75
85
 
76
86
  ##
@@ -92,6 +102,11 @@ class ::String
92
102
  dup.force_encoding("utf-8").sub(/ \d{1,2}(:\d\d)? *([ap]m)?/i, "")
93
103
  end
94
104
 
105
+ ##
106
+ ## Round a date string to a day
107
+ ##
108
+ ## @param time [Symbol] :start or :end
109
+ ##
95
110
  def to_day(time = :end)
96
111
  t = time == :end ? "23:59" : "00:00"
97
112
  Chronic.parse("#{strip_time} #{t}")
@@ -134,13 +149,12 @@ class ::String
134
149
  end
135
150
 
136
151
  ##
137
- ## Destructive version of #to_bool
152
+ ## Test if a string starts with Pandoc metadata
138
153
  ##
154
+ ## @return [Boolean] test result
139
155
  ##
140
- ## @see #to_bool
141
- ##
142
- def to_bool!
143
- replace to_bool
156
+ def pandoc?
157
+ dup.force_encoding('utf-8').match?(/^% \S/m)
144
158
  end
145
159
 
146
160
  ##
@@ -149,11 +163,40 @@ class ::String
149
163
  ## @return [Boolean] Bool representation of the object.
150
164
  ##
151
165
  def to_bool
152
- case self.force_encoding('utf-8')
166
+ case self.dup.force_encoding('utf-8')
153
167
  when /^[yt]/i
154
168
  true
155
169
  else
156
170
  false
157
171
  end
158
172
  end
173
+
174
+ ##
175
+ ## Convert a string to a regular expression
176
+ ##
177
+ ## If the string matches /xxx/, it will be interpreted
178
+ ## directly as a regex. Otherwise it will be escaped and
179
+ ## converted to regex.
180
+ ##
181
+ ## @return [Regexp] Regexp representation of the string.
182
+ ##
183
+ def to_rx
184
+ if self =~ %r{^/(.*?)/([im]+)?$}
185
+ m = Regexp.last_match
186
+ regex = m[1]
187
+ flags = m[2]
188
+ Regexp.new(regex, flags)
189
+ else
190
+ Regexp.new(Regexp.escape(self))
191
+ end
192
+ end
193
+
194
+ ##
195
+ ## Convert a string containing $1, $2 to a Regexp replace pattern
196
+ ##
197
+ ## @return [String] Pattern representation of the object.
198
+ ##
199
+ def to_pattern
200
+ gsub(/\$(\d+)/, '\\\\\1').gsub(/(^["']|["']$)/, "")
201
+ end
159
202
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Conductor
4
- VERSION = '1.0.27'
4
+ VERSION = "1.0.28"
5
5
  end
@@ -1,42 +1,54 @@
1
+ # frozen_string_literal: true
2
+ #
1
3
  # This is a Ruby port of the YUI CSS compressor
2
4
  # See LICENSE for license information
3
5
 
4
6
  module YuiCompressor
5
7
  # Compress CSS rules using a variety of techniques
6
-
7
8
  class Yui
8
9
  attr_reader :input_size, :output_size
9
10
 
11
+ ##
12
+ ## Instantiate compressor
13
+ ##
14
+ ## @return [Yui] self
15
+ ##
10
16
  def initialize
11
- @preservedTokens = []
17
+ @preserved_tokens = []
12
18
  @comments = []
13
19
  @input_size = 0
14
20
  @output_size = 0
15
21
  end
16
22
 
23
+ ##
24
+ ## YUI Compress string
25
+ ##
26
+ ## @param css [String] The css
27
+ ## @param line_length [Integer] The line length
28
+ ##
17
29
  def compress(css, line_length = 0)
18
30
  @input_size = css.length
19
31
 
20
32
  css = process_comments_and_strings(css)
21
33
 
22
34
  # Normalize all whitespace strings to single spaces. Easier to work with that way.
23
- css.gsub!(/\s+/, ' ')
35
+ css.gsub!(/\s+/, " ")
24
36
 
25
37
  # Remove the spaces before the things that should not have spaces before them.
26
38
  # But, be careful not to turn "p :link {...}" into "p:link{...}"
27
39
  # Swap out any pseudo-class colons with the token, and then swap back.
28
40
  css.gsub!(/(?:^|\})[^{:]+\s+:+[^{]*\{/) do |match|
29
- match.gsub(':', '___PSEUDOCLASSCOLON___')
41
+ match.gsub(":", "___PSEUDOCLASSCOLON___")
30
42
  end
31
43
  css.gsub!(/\s+([!{};:>+()\],])/, '\1')
32
44
  css.gsub!(/([!{}:;>+(\[,])\s+/, '\1')
33
- css.gsub!('___PSEUDOCLASSCOLON___', ':')
45
+ css.gsub!("___PSEUDOCLASSCOLON___", ":")
34
46
 
35
47
  # special case for IE
36
48
  css.gsub!(/:first-(line|letter)(\{|,)/, ':first-\1 \2')
37
49
 
38
50
  # no space after the end of a preserved comment
39
- css.gsub!(%r{\*/ }, '*/')
51
+ css.gsub!(%r{\*/ }, "*/")
40
52
 
41
53
  # If there is a @charset, then only allow one, and push to the top of the file.
42
54
  css.gsub!(/^(.*)(@charset "[^"]*";)/i, '\2\1')
@@ -44,10 +56,10 @@ module YuiCompressor
44
56
 
45
57
  # Put the space back in some cases, to support stuff like
46
58
  # @media screen and (-webkit-min-device-pixel-ratio:0){
47
- css.gsub!(/\band\(/i, 'and (')
59
+ css.gsub!(/\band\(/i, "and (")
48
60
 
49
61
  # remove unnecessary semicolons
50
- css.gsub!(/;+\}/, '}')
62
+ css.gsub!(/;+\}/, "}")
51
63
 
52
64
  # Replace 0(%, em, ex, px, in, cm, mm, pt, pc) with just 0.
53
65
  css.gsub!(/([\s:])([+-]?0)(?:%|em|ex|px|in|cm|mm|pt|pc)/i, '\1\2')
@@ -56,8 +68,9 @@ module YuiCompressor
56
68
  css.gsub!(/:(?:0 )+0(;|\})/, ':0\1')
57
69
 
58
70
  # Restore background-position:0 0; if required
59
- css.gsub!(/(background-position|transform-origin|webkit-transform-origin|moz-transform-origin|o-transform-origin|ms-transform-origin):0(;|\})/i) {
60
- "#{::Regexp.last_match(1).downcase}:0 0#{::Regexp.last_match(2)}" }
71
+ css.gsub!(/(background-position|(?:(?:webkit|moz|o|ms)-)?transform-origin):0(;|\})/i) do
72
+ "#{::Regexp.last_match(1).downcase}:0 0#{::Regexp.last_match(2)}"
73
+ end
61
74
 
62
75
  # Replace 0.6 with .6, but only when preceded by : or a space.
63
76
  css.gsub!(/(:|\s)0+\.(\d+)/, '\1.\2')
@@ -65,7 +78,7 @@ module YuiCompressor
65
78
  # Shorten colors from rgb(51,102,153) to #336699
66
79
  # This makes it more likely that it'll get further compressed in the next step.
67
80
  css.gsub!(/rgb\s*\(\s*([0-9,\s]+)\s*\)/) do |_match|
68
- '#' << ::Regexp.last_match(1).scan(/\d+/).map {|n| n.to_i.to_s(16).rjust(2, '0') }.join
81
+ "#".dup << ::Regexp.last_match(1).scan(/\d+/).map { |n| n.to_i.to_s(16).rjust(2, "0") }.join
69
82
  end
70
83
 
71
84
  # Shorten colors from #AABBCC to #ABC. Note that we want to make sure
@@ -77,34 +90,35 @@ module YuiCompressor
77
90
  css.gsub!(/([^"'=\s])(\s?)\s*#([0-9a-f])\3([0-9a-f])\4([0-9a-f])\5/i, '\1\2#\3\4\5')
78
91
 
79
92
  # border: none -> border:0
80
- css.gsub!(/(border|border-top|border-right|border-bottom|border-right|outline|background):none(;|\})/i) {
81
- "#{::Regexp.last_match(1).downcase}:0#{::Regexp.last_match(2)}" }
93
+ css.gsub!(/(border|border-(top|right|bottom)|outline|background):none(;|\})/i) do
94
+ "#{::Regexp.last_match(1).downcase}:0#{::Regexp.last_match(2)}"
95
+ end
82
96
 
83
97
  # shorter opacity IE filter
84
- css.gsub!(/progid:DXImageTransform\.Microsoft\.Alpha\(Opacity=/i, 'alpha(opacity=')
98
+ css.gsub!(/progid:DXImageTransform\.Microsoft\.Alpha\(Opacity=/i, "alpha(opacity=")
85
99
 
86
100
  # Remove empty rules.
87
- css.gsub!(%r{[^\};\{/]+\{\}}, '')
101
+ css.gsub!(%r{[^\};\{/]+\{\}}, "")
88
102
 
89
- if line_length > 0
103
+ if line_length.positive?
90
104
  # Some source control tools don't like it when files containing lines longer
91
105
  # than, say 8000 characters, are checked in. The linebreak option is used in
92
106
  # that case to split long lines after a specific column.
93
- startIndex = 0
94
- index = 0
107
+ start_index = 0
108
+ idx = 0
95
109
  length = css.length
96
- while index < length
97
- index += 1
98
- if css[index - 1, 1] === '}' && index - startIndex > line_length
99
- css = css.slice(0, index) + "\n" + css.slice(index, length)
100
- startIndex = index
110
+ while idx < length
111
+ idx += 1
112
+ if css[idx - 1, 1] == "}" && idx - start_index > line_length
113
+ css = "#{css.slice(0, idx)}\n#{css.slice(idx, length)}"
114
+ start_index = idx
101
115
  end
102
116
  end
103
117
  end
104
118
 
105
119
  # Replace multiple semi-colons in a row by a single one
106
120
  # See SF bug #1980989
107
- css.gsub!(/;+/, ';')
121
+ css.gsub!(/;+/, ";")
108
122
 
109
123
  # restore preserved comments and strings
110
124
  css = restore_preserved_comments_and_strings(css)
@@ -116,26 +130,28 @@ module YuiCompressor
116
130
  css
117
131
  end
118
132
 
133
+ ##
134
+ ## Replace comments and strings with placeholders
135
+ ##
136
+ ## @param css_text [String] The css text
137
+ ##
138
+ ## @return [String] css text with strings replaced
119
139
  def process_comments_and_strings(css_text)
120
- css = css_text.clone
140
+ css = css_text.dup.force_encoding("ISO-8859-1").encode("utf-8", replace: nil)
121
141
 
122
- startIndex = 0
123
- endIndex = 0
124
- i = 0
125
- max = 0
126
- token = ''
142
+ start_index = 0
143
+ token = ""
127
144
  totallen = css.length
128
- placeholder = ''
145
+ placeholder = ""
129
146
 
130
147
  # collect all comment blocks
131
- while (startIndex = css.index(%r{/\*}, startIndex))
132
- endIndex = css.index(%r{\*/}, startIndex + 2)
133
- endIndex = totallen unless endIndex
134
- token = css.slice(startIndex + 2..endIndex - 1)
148
+ while (start_index = css.index(%r{/\*}, start_index))
149
+ end_index = css.index(%r{\*/}, start_index + 2)
150
+ end_index ||= totallen
151
+ token = css.slice(start_index + 2..end_index - 1)
135
152
  @comments.push(token)
136
- css = css.slice(0..startIndex + 1).to_s + '___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_' + (@comments.length - 1).to_s + '___' + css.slice(
137
- endIndex, totallen).to_s
138
- startIndex += 2
153
+ css = "#{css.slice(0..start_index + 1)}___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_#{@comments.length - 1}___#{css.slice(end_index, totallen)}"
154
+ start_index += 2
139
155
  end
140
156
 
141
157
  # preserve strings so their content doesn't get accidentally minified
@@ -146,82 +162,86 @@ endIndex, totallen).to_s
146
162
  # maybe the string contains a comment-like substring?
147
163
  # one, maybe more? put'em back then
148
164
  if string =~ /___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_/
149
- @comments.each_index do |index|
150
- string.gsub!(/___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_#{index}___/, @comments[index])
165
+ @comments.each_index do |idx|
166
+ string.gsub!(/___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_#{idx}___/, @comments[idx])
151
167
  end
152
168
  end
153
169
 
154
170
  # minify alpha opacity in filter strings
155
- string.gsub!(/progid:DXImageTransform\.Microsoft\.Alpha\(Opacity=/i, 'alpha(opacity=')
156
- @preservedTokens.push(string)
171
+ string.gsub!(/progid:DXImageTransform\.Microsoft\.Alpha\(Opacity=/i, "alpha(opacity=")
172
+ @preserved_tokens.push(string)
157
173
 
158
- quote + '___YUICSSMIN_PRESERVED_TOKEN_' + (@preservedTokens.length - 1).to_s + '___' + quote
174
+ "#{quote}___YUICSSMIN_PRESERVED_TOKEN_#{@preserved_tokens.length - 1}___#{quote}"
159
175
  end
160
176
 
161
- # used to jump one index in loop
162
- ie5_hack = false
177
+ # # used to jump one index in loop
178
+ # ie5_hack = false
163
179
  # strings are safe, now wrestle the comments
164
- @comments.each_index do |index|
165
- if ie5_hack
166
- ie5_hack = false
167
- next
168
- end
180
+ @comments.each_index do |idx|
181
+ # if ie5_hack
182
+ # ie5_hack = false
183
+ # next
184
+ # end
169
185
 
170
- token = @comments[index]
171
- placeholder = '___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_' + index.to_s + '___'
186
+ token = @comments[idx]
187
+ placeholder = "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_#{idx}___"
172
188
 
173
189
  # ! in the first position of the comment means preserve
174
190
  # so push to the preserved tokens keeping the !
175
- if token[0, 1] === '!'
176
- @preservedTokens.push(token)
177
- css.gsub!(/#{placeholder}/i, '___YUICSSMIN_PRESERVED_TOKEN_' + (@preservedTokens.length - 1).to_s + '___')
191
+ if token[0, 1] == "!"
192
+ @preserved_tokens.push(token)
193
+ css.gsub!(/#{placeholder}/i, "___YUICSSMIN_PRESERVED_TOKEN_#{@preserved_tokens.length - 1}___")
178
194
  next
179
195
  end
180
196
 
181
- # \ in the last position looks like hack for Mac/IE5
182
- # shorten that to /*\*/ and the next one to /**/
183
- if token[-1, 1] === '\\'
184
- @preservedTokens.push('\\')
185
- css.gsub!(/#{placeholder}/, '___YUICSSMIN_PRESERVED_TOKEN_' + (@preservedTokens.length - 1).to_s + '___')
186
- # keep the next comment but remove its content
187
- @preservedTokens.push('')
188
- css.gsub!(/___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_#{index + 1}___/,
189
- '___YUICSSMIN_PRESERVED_TOKEN_' + (@preservedTokens.length - 1).to_s + '___')
190
- ie5_hack = true
191
- next
192
- end
193
-
194
- # keep empty comments after child selectors (IE7 hack)
195
- # e.g. html >/**/ body
196
- if (token.length === 0) && (startIndex = css.index(/#{placeholder}/))
197
- if startIndex > 2
198
- if css[startIndex - 3, 1] === '>'
199
- @preservedTokens.push('')
200
- css.gsub!(/#{placeholder}/, '___YUICSSMIN_PRESERVED_TOKEN_' + (@preservedTokens.length - 1).to_s + '___')
201
- end
202
- end
203
- end
197
+ # # \ in the last position looks like hack for Mac/IE5
198
+ # # shorten that to /*\*/ and the next one to /**/
199
+ # if token[-1, 1] == "\\"
200
+ # @preserved_tokens.push("\\")
201
+ # css.gsub!(/#{placeholder}/, "___YUICSSMIN_PRESERVED_TOKEN_#{@preserved_tokens.length - 1}___")
202
+ # # keep the next comment but remove its content
203
+ # @preserved_tokens.push("")
204
+ # css.gsub!(/___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_#{idx + 1}___/,
205
+ # "___YUICSSMIN_PRESERVED_TOKEN_#{@preserved_tokens.length - 1}___")
206
+ # ie5_hack = true
207
+ # next
208
+ # end
209
+
210
+ # # keep empty comments after child selectors (IE7 hack)
211
+ # # e.g. html >/**/ body
212
+ # if token.empty? && (start_index = css.index(/#{placeholder}/)) &&
213
+ # (start_index > 2) && (css[start_index - 3, 1] == ">")
214
+ # @preserved_tokens.push("")
215
+ # css.gsub!(/#{placeholder}/, "___YUICSSMIN_PRESERVED_TOKEN_#{@preserved_tokens.length - 1}___")
216
+ # end
204
217
 
205
218
  # in all other cases kill the comment
206
- css.gsub!(%r{/\*#{placeholder}\*/}, '')
219
+ css.gsub!(%r{/\*#{placeholder}\*/}, "")
207
220
  end
208
221
 
209
222
  css
210
223
  end
211
224
 
225
+ ##
226
+ ## Restore saved comments and strings
227
+ ##
228
+ ## @param clean_css [String] The processed css
229
+ ##
230
+ ## @return [String] restored CSS
231
+ ##
212
232
  def restore_preserved_comments_and_strings(clean_css)
213
233
  css = clean_css.clone
214
234
  css_length = css.length
215
- @preservedTokens.each_index do |index|
235
+ @preserved_tokens.each_index do |idx|
216
236
  # slice these back into place rather than regex, because
217
237
  # complex nested strings cause the replacement to fail
218
- placeholder = "___YUICSSMIN_PRESERVED_TOKEN_#{index}___"
219
- startIndex = css.index(placeholder, 0)
220
- next unless startIndex # skip if nil
238
+ placeholder = "___YUICSSMIN_PRESERVED_TOKEN_#{idx}___"
239
+ start_index = css.index(placeholder, 0)
240
+ next unless start_index # skip if nil
221
241
 
222
- endIndex = startIndex + placeholder.length
242
+ end_index = start_index + placeholder.length
223
243
 
224
- css = css.slice(0..startIndex - 1).to_s + @preservedTokens[index] + css.slice(endIndex, css_length).to_s
244
+ css = css.slice(0..start_index - 1).to_s + @preserved_tokens[idx] + css.slice(end_index, css_length).to_s
225
245
  end
226
246
 
227
247
  css
data/lib/conductor.rb CHANGED
@@ -19,16 +19,108 @@ require_relative "conductor/filter"
19
19
  require_relative "conductor/script"
20
20
  require_relative "conductor/command"
21
21
  require_relative "conductor/condition"
22
- require_relative "conductor/yui-compressor"
22
+ require_relative "conductor/yui_compressor"
23
23
 
24
+ # Main Conductor module
24
25
  module Conductor
25
26
  class << self
26
27
  attr_accessor :original_input
27
28
  attr_writer :stdin
28
29
 
30
+ ##
31
+ ## Return STDIN value, reading from STDIN if needed
32
+ ##
33
+ ## @return [String] STDIN contents
34
+ ##
29
35
  def stdin
30
- warn "input on STDIN required" unless $stdin.stat.size.positive? || $stdin.fcntl(Fcntl::F_GETFL, 0).zero?
36
+ warn "input on STDIN required" unless ENV["CONDUCTOR_TEST"] || $stdin.stat.size.positive? || $stdin.fcntl(Fcntl::F_GETFL, 0).zero?
31
37
  @stdin ||= $stdin.read.force_encoding("utf-8")
32
38
  end
39
+
40
+ ##
41
+ ## Execute commands/scripts in the track
42
+ ##
43
+ ## @param track The track
44
+ ##
45
+ ## @return Resulting STDOUT output
46
+ ##
47
+ def execute_track(track)
48
+ if track[:sequence]
49
+ track[:sequence].each do |cmd|
50
+ if cmd[:script]
51
+ script = Script.new(cmd[:script])
52
+
53
+ res = script.run
54
+ elsif cmd[:command]
55
+ command = Command.new(cmd[:command])
56
+
57
+ res = command.run
58
+ elsif cmd[:filter]
59
+ filter = Filter.new(cmd[:filter])
60
+
61
+ res = filter.process
62
+ end
63
+
64
+ Conductor.stdin = res unless res.nil?
65
+ end
66
+ elsif track[:script]
67
+ script = Script.new(track[:script])
68
+
69
+ Conductor.stdin = script.run
70
+ elsif track[:command]
71
+ command = Command.new(track[:command])
72
+
73
+ Conductor.stdin = command.run
74
+ elsif track[:filter]
75
+ filter = Filter.new(track[:filter])
76
+
77
+ Conductor.stdin = filter.process
78
+ end
79
+
80
+ Conductor.stdin
81
+ end
82
+
83
+ ##
84
+ ## Main function to parse conditions and
85
+ ## execute actions. Executes recursively for
86
+ ## sub-tracks.
87
+ ##
88
+ ## @param tracks The tracks to process
89
+ ## @param res The current result
90
+ ## @param condition The current condition
91
+ ##
92
+ ## @return [Array] result, matched condition(s)
93
+ ##
94
+ def conduct(tracks, res = nil, condition = nil)
95
+ tracks.each do |track|
96
+ cond = Condition.new(track[:condition])
97
+
98
+ next unless cond.true?
99
+
100
+ # Build "matched condition" message
101
+ title = track[:title] || track[:condition]
102
+ condition ||= [""]
103
+ condition << title
104
+ condition.push(track.key?(:continue) ? " -> " : ", ")
105
+
106
+ res = execute_track(track)
107
+
108
+ if track[:tracks]
109
+ ts = track[:tracks]
110
+
111
+ res, condition = conduct(ts, res, condition)
112
+
113
+ next if res.nil?
114
+ end
115
+
116
+ break unless track[:continue]
117
+ end
118
+
119
+ if res&.strip == Conductor.original_input.strip
120
+ [nil, "No change in output"]
121
+ else
122
+ [res, condition]
123
+ end
124
+ end
33
125
  end
34
126
  end
@@ -9,7 +9,8 @@ Gem::Specification.new do |spec|
9
9
  spec.email = ["me@brettterpstra.com"]
10
10
 
11
11
  spec.summary = "A custom processor manager for Marked 2 (Mac)"
12
- spec.description = "Conductor allows easy configuration of multiple scripts that are run as custom pre/processors for Marked based on conditional statements."
12
+ spec.description = "Conductor allows easy configuration of multiple scripts" \
13
+ "which are run as custom pre/processors for Marked based on conditional statements."
13
14
  spec.homepage = "https://github.com/ttscoff/marked-conductor"
14
15
  spec.license = "MIT"
15
16
  spec.required_ruby_version = ">= 2.6.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marked-conductor
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.27
4
+ version: 1.0.28
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-24 00:00:00.000000000 Z
11
+ date: 2024-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
@@ -184,7 +184,7 @@ dependencies:
184
184
  - - "~>"
185
185
  - !ruby/object:Gem::Version
186
186
  version: 0.5.0
187
- description: Conductor allows easy configuration of multiple scripts that are run
187
+ description: Conductor allows easy configuration of multiple scriptswhich are run
188
188
  as custom pre/processors for Marked based on conditional statements.
189
189
  email:
190
190
  - me@brettterpstra.com
@@ -218,7 +218,7 @@ files:
218
218
  - lib/conductor/script.rb
219
219
  - lib/conductor/string.rb
220
220
  - lib/conductor/version.rb
221
- - lib/conductor/yui-compressor.rb
221
+ - lib/conductor/yui_compressor.rb
222
222
  - marked-conductor.gemspec
223
223
  - src/_README.md
224
224
  - test.sh