marked-conductor 1.0.26 → 1.0.28

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.
@@ -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.26'
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.26
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