howzit 2.0.14 → 2.0.17

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a4ce43666235573b6b74c77d0dcb6e1f4c1a45fb8b9cd516747698f56cc3723d
4
- data.tar.gz: c13702a3d4b7b2ad707890d3f9d8c2a75e92fba1c732689f1930b511254db742
3
+ metadata.gz: fa788ff480288582a4473e2bb2fa9388afc98165c9c78b2c90a1bb9b964d7919
4
+ data.tar.gz: e3012f8ed229832f7cefa29b1ff9a4d971858886c8c9778ec7fe6a3b74faa181
5
5
  SHA512:
6
- metadata.gz: 586fcb6d9e5bfd901a3e4d33ff9044c57ae50a97cb0a19e8c2d9e5b57dec6771b432e0dc83e28a924824cc04a758ce4397d0f74b7efb2d343181c262f92c636b
7
- data.tar.gz: 5f0eac9f6e53ed64ea159630e0f979f9cc8d8734b95186316b924e1e75e752b7a189d02eb1c178c15050676988356b391cfbc19f3da9eacb61d21051b474188e
6
+ metadata.gz: 893cc81a4db7d7297f8a3d195f6a02bec4a0e419c56ca6a76e97bfbbe49636ef6e6162457f83f914422bb42d5906df8f38a375309d9d5a1b6844d57d488c2e55
7
+ data.tar.gz: e286bd61f5d4d4dd9632691c3486a9daa51701aac8c4facd3f5a62d01e871ec0cd06d7ff4ac1f19c0f9ff7d24d6ef1d3b9f812d68aa6d62877c99b5bfed7b261
data/.travis.yml CHANGED
@@ -13,4 +13,4 @@ install:
13
13
  script: "bundle exec rspec spec --exclude-pattern 'cli*'"
14
14
  branches:
15
15
  only:
16
- - master
16
+ - main
data/CHANGELOG.md CHANGED
@@ -1,3 +1,36 @@
1
+ ### 2.0.17
2
+
3
+ 2022-08-07 06:09
4
+
5
+ ### 2.0.16
6
+
7
+ 2022-08-07 06:05
8
+
9
+ #### NEW
10
+
11
+ - --edit-template NAME will open a template in your editor, offering to create it if missing
12
+
13
+ #### FIXED
14
+
15
+ - If --show-code is given (or :show_all_code: is set to true), show content of @directives instead of title
16
+
17
+ ### 2.0.15
18
+
19
+ 2022-08-05 17:16
20
+
21
+ #### IMPROVED
22
+
23
+ - -R can take an argument to filter results
24
+ - Show a topic preview when using fzf to select from available topics
25
+ - Paginate help output
26
+ - Refactor Topic.run
27
+
28
+ #### FIXED
29
+
30
+ - Invalid options for more pager
31
+ - Error running grep command
32
+ - Show method not accepting paginate option
33
+
1
34
  ### 2.0.14
2
35
 
3
36
  2022-08-05 13:24
data/bin/howzit CHANGED
@@ -49,7 +49,8 @@ OptionParser.new do |opts|
49
49
  Howzit.options[:list_topics] = true
50
50
  end
51
51
 
52
- opts.on('-R', '--list-runnable', 'List topics containing @ directives (verbose)') do
52
+ opts.on('-R', '--list-runnable [PATTERN]', 'List topics containing @ directives (verbose)') do |pat|
53
+ Howzit.options[:for_topic] = pat
53
54
  Howzit.options[:list_runnable] = true
54
55
  end
55
56
 
@@ -93,6 +94,11 @@ OptionParser.new do |opts|
93
94
  Process.exit 0
94
95
  end
95
96
 
97
+ opts.on('--edit-template NAME', 'Create or edit a template') do |template|
98
+ Howzit.buildnote.edit_template(template)
99
+ Process.exit 0
100
+ end
101
+
96
102
  opts.on('--config-get [KEY]', 'Display the configuration settings or setting for a specific key') do |k|
97
103
  if k.nil?
98
104
  Howzit::Config::DEFAULTS.sort_by { |key, _| key }.each do |key, _|
@@ -201,7 +207,7 @@ OptionParser.new do |opts|
201
207
  opts.separator("\n Misc:\n\n") #=================================================================== MISC
202
208
 
203
209
  opts.on('-h', '--help', 'Display this screen') do
204
- puts opts
210
+ Howzit::Util.page opts.to_s
205
211
  Process.exit 0
206
212
  end
207
213
 
@@ -11,27 +11,24 @@ module Howzit
11
11
  ## Initialize a build note
12
12
  ##
13
13
  ## @param file [String] The path to the build note file
14
- ## @param args [Array] additional args
15
14
  ##
16
- def initialize(file: nil, args: [])
15
+ def initialize(file: nil)
17
16
  @topics = []
18
- if note_file.nil?
19
- res = Prompt.yn('No build notes file found, create one?', default: true)
17
+ create_note(prompt: true) if note_file.nil?
20
18
 
21
- create_note if res
22
- Process.exit 0
23
- end
24
19
  content = Util.read_file(note_file)
25
- if content.nil? || content.empty?
26
- Howzit.console.error("{br}No content found in build note (#{note_file}){x}".c)
27
- Process.exit 1
28
- else
29
- @metadata = content.split(/^#/)[0].strip.get_metadata
30
- end
20
+ raise "{br}No content found in build note (#{note_file}){x}".c if content.nil? || content.empty?
21
+
22
+ @metadata = content.split(/^#/)[0].strip.get_metadata
31
23
 
32
24
  read_help(file)
33
25
  end
34
26
 
27
+ ##
28
+ ## Inspect
29
+ ##
30
+ ## @return description
31
+ ##
35
32
  def inspect
36
33
  puts "#<Howzit::BuildNote @topics=[#{@topics.count}]>"
37
34
  end
@@ -50,12 +47,25 @@ module Howzit
50
47
  edit_note
51
48
  end
52
49
 
50
+ ##
51
+ ## Public method to open a template in the editor
52
+ ##
53
+ ## @param template [String] The template title
54
+ ##
55
+ def edit_template(template)
56
+ file = template.sub(/(\.md)?$/i, '.md')
57
+ file = File.join(Howzit.config.template_folder, file)
58
+ edit_template_file(file)
59
+ end
60
+
53
61
  ##
54
62
  ## Find a topic based on a fuzzy match
55
63
  ##
56
64
  ## @param term [String] The search term
57
65
  ##
58
- def find_topic(term)
66
+ def find_topic(term = nil)
67
+ return @topics if term.nil?
68
+
59
69
  @topics.filter do |topic|
60
70
  rx = term.to_rx
61
71
  topic.title.downcase =~ rx
@@ -127,18 +137,18 @@ module Howzit
127
137
  def list_runnable
128
138
  output = []
129
139
  output.push(%({bg}"Runnable" Topics:{x}\n).c)
130
- @topics.each do |topic|
140
+
141
+ find_topic(Howzit.options[:for_topic]).each do |topic|
131
142
  s_out = []
132
143
 
133
- topic.tasks.each do |task|
134
- s_out.push(task.to_list)
135
- end
144
+ topic.tasks.each { |task| s_out.push(task.to_list) }
136
145
 
137
- unless s_out.empty?
138
- output.push("- {bw}#{topic.title}{x}".c)
139
- output.push(s_out.join("\n"))
140
- end
146
+ next if s_out.empty?
147
+
148
+ output.push("- {bw}#{topic.title}{x}".c)
149
+ output.push(s_out.join("\n"))
141
150
  end
151
+
142
152
  output.join("\n")
143
153
  end
144
154
 
@@ -151,22 +161,75 @@ module Howzit
151
161
  read_help_file(file)
152
162
  end
153
163
 
164
+ ##
165
+ ## Create a template file
166
+ ##
167
+ ## @param file [String] file path
168
+ ## @param prompt [Boolean] confirm file creation?
169
+ ##
170
+ def create_template_file(file, prompt: false)
171
+ trap('SIGINT') do
172
+ Howzit.console.info "\nCancelled"
173
+ exit!
174
+ end
175
+
176
+ default = !$stdout.isatty || Howzit.options[:default]
177
+
178
+ if prompt && !default && !File.exist?(file)
179
+ res = Prompt.yn("{bg}Template {bw}#{File.basename(file)}{bg} not found, create it?{x}".c, default: true)
180
+ Process.exit 0 unless res
181
+ end
182
+
183
+ title = File.basename(file, '.md')
184
+
185
+ note = <<~EOBUILDNOTES
186
+ # #{title}
187
+
188
+ ## Template Topic
189
+
190
+ EOBUILDNOTES
191
+
192
+ if File.exist?(file) && !default
193
+ file = "{by}#{file}".c
194
+ unless Prompt.yn("Are you sure you want to overwrite #{file}", default: false)
195
+ puts 'Cancelled'
196
+ Process.exit 0
197
+ end
198
+ end
199
+
200
+ File.open(file, 'w') do |f|
201
+ f.puts note
202
+ puts "{by}Template {bw}#{title}{by} written to {bw}#{file}{x}".c
203
+ end
204
+
205
+ if File.exist?(file) && !default && Prompt.yn("{bg}Do you want to open {bw}#{file} {bg}for editing?{x}".c,
206
+ default: false)
207
+ edit_template_file(file)
208
+ end
209
+
210
+ Process.exit 0
211
+ end
212
+
154
213
  # Create a buildnotes skeleton
155
- def create_note
214
+ def create_note(prompt: false)
156
215
  trap('SIGINT') do
157
216
  Howzit.console.info "\nCancelled"
158
217
  exit!
159
218
  end
219
+
160
220
  default = !$stdout.isatty || Howzit.options[:default]
221
+
222
+ if prompt && !default
223
+ res = Prompt.yn('No build notes file found, create one?', default: true)
224
+ Process.exit 0 unless res
225
+ end
226
+
161
227
  # First make sure there isn't already a buildnotes file
162
228
  if note_file
163
229
  fname = "{by}#{note_file}{bw}".c
164
230
  unless default
165
231
  res = Prompt.yn("#{fname} exists and appears to be a build note, continue anyway?", default: false)
166
- unless res
167
- puts 'Canceled'
168
- Process.exit 0
169
- end
232
+ Process.exit 0 unless res
170
233
  end
171
234
  end
172
235
 
@@ -221,9 +284,7 @@ module Howzit
221
284
 
222
285
  if File.exist?(fname) && !default
223
286
  file = "{by}#{fname}".c
224
- res = Prompt.yn("Are you absolutely sure you want to overwrite #{file}", default: false)
225
-
226
- unless res
287
+ unless Prompt.yn("Are you absolutely sure you want to overwrite #{file}", default: false)
227
288
  puts 'Canceled'
228
289
  Process.exit 0
229
290
  end
@@ -231,24 +292,161 @@ module Howzit
231
292
 
232
293
  File.open(fname, 'w') do |f|
233
294
  f.puts note
234
- puts "{by}Build notes for #{title} written to #{fname}".c
295
+ puts "{by}Build notes for {bw}#{title}{by} written to {bw}#{fname}{x}".c
235
296
  end
236
297
 
237
- if File.exist?(fname) && !default
238
- res = Prompt.yn("{bg}Do you want to open {bw}#{file} {bg}for editing?{x}".c, default: false)
239
-
240
- edit_note if res
298
+ if File.exist?(fname) && !default && Prompt.yn("{bg}Do you want to open {bw}#{fname} {bg}for editing?{x}".c,
299
+ default: false)
300
+ edit_note
241
301
  end
242
302
 
243
303
  Process.exit 0
244
304
  end
245
305
 
306
+ ##
307
+ ## Accessor method for note_file (path to located build note)
308
+ ##
309
+ ## @return [String] path
310
+ ##
246
311
  def note_file
247
312
  @note_file ||= find_note_file
248
313
  end
249
314
 
250
315
  private
251
316
 
317
+ ##
318
+ ## Import the contents of a filename as new topics
319
+ ##
320
+ ## @param mtch [MatchData] the filename match from
321
+ ## the include directive
322
+ ##
323
+ def include_file(mtch)
324
+ file = File.expand_path(mtch[1])
325
+
326
+ return mtch[0] unless File.exist?(file)
327
+
328
+ content = Util.read_file(file)
329
+ home = ENV['HOME']
330
+ short_path = File.dirname(file.sub(/^#{home}/, '~'))
331
+ prefix = "#{short_path}/#{File.basename(file)}:"
332
+ parts = content.split(/^##+/)
333
+ parts.shift
334
+ if parts.empty?
335
+ content
336
+ else
337
+ "## #{parts.join('## ')}".gsub(/^(##+ *)(?=\S)/, "\\1#{prefix}")
338
+ end
339
+ end
340
+
341
+ ##
342
+ ## Test to ensure that any `required` metadata in a
343
+ ## template is fulfilled by the build note
344
+ ##
345
+ ## @param template [String] The template to read
346
+ ## from
347
+ ##
348
+ def ensure_requirements(template)
349
+ t_leader = Util.read_file(template).split(/^#/)[0].strip
350
+ if t_leader.length > 0
351
+ t_meta = t_leader.get_metadata
352
+ if t_meta.key?('required')
353
+ required = t_meta['required'].strip.split(/\s*,\s*/)
354
+ required.each do |req|
355
+ unless @metadata.keys.include?(req.downcase)
356
+ Howzit.console.error %({bRw}ERROR:{xbr} Missing required metadata key from template '{bw}#{File.basename(template, '.md')}{xr}'{x}).c
357
+ Howzit.console.error %({br}Please define {by}#{req.downcase}{xr} in build notes{x}).c
358
+ Process.exit 1
359
+ end
360
+ end
361
+ end
362
+ end
363
+ end
364
+
365
+ ##
366
+ ## Test a template string for bracketed subtopics
367
+ ##
368
+ ## @param template [String] The template name
369
+ ##
370
+ ## @return [Array] [[String] updated template name, [Array]
371
+ ## subtopic titles]
372
+ ##
373
+ def detect_subtopics(template)
374
+ subtopics = nil
375
+
376
+ if template =~ /\[(.*?)\]$/
377
+ subtopics = Regexp.last_match[1].split(/\s*\|\s*/).map { |t| t.gsub(/\*/, '.*?')}
378
+ template.sub!(/\[.*?\]$/, '').strip
379
+ end
380
+
381
+ [template, subtopics]
382
+ end
383
+
384
+ ##
385
+ ## Enumerate templates and read their associated files
386
+ ## into topics
387
+ ##
388
+ ## @param templates [Array] The templates to read
389
+ ##
390
+ ## @return [Array] template topics
391
+ ##
392
+ def gather_templates(templates)
393
+ template_topics = []
394
+
395
+ templates.each do |template|
396
+ template, subtopics = detect_subtopics(template)
397
+
398
+ file = template.sub(/(\.md)?$/i, '.md')
399
+ file = File.join(Howzit.config.template_folder, file)
400
+
401
+ next unless File.exist?(file)
402
+
403
+ ensure_requirements(file)
404
+
405
+ template_topics.concat(read_template(template, file, subtopics))
406
+ end
407
+
408
+ template_topics
409
+ end
410
+
411
+ ##
412
+ ## Filter topics based on subtopic titles
413
+ ##
414
+ ## @param note [BuildNote] The note
415
+ ## @param subtopics [Array] The subtopics to
416
+ ## extract
417
+ ##
418
+ ## @return [Array] extracted subtopics
419
+ ##
420
+ def extract_subtopics(note, subtopics)
421
+ template_topics = []
422
+
423
+ subtopics.each do |subtopic|
424
+ note.topics.each { |topic| template_topics.push(topic) if topic.title =~ /^(.*?:)?#{subtopic}$/i }
425
+ end
426
+
427
+ template_topics
428
+ end
429
+
430
+ ##
431
+ ## Read a template file
432
+ ##
433
+ ## @param template [String] The template title
434
+ ## @param file [String] The file path
435
+ ## @param subtopics [Array] The subtopics to
436
+ ## extract, nil to return all
437
+ ##
438
+ ## @return [Array] extracted topics
439
+ ##
440
+ def read_template(template, file, subtopics = nil)
441
+ note = BuildNote.new(file: file)
442
+
443
+ template_topics = subtopics.nil? ? note.topics : extract_subtopics(note, subtopics)
444
+ template_topics.map do |topic|
445
+ topic.parent = template
446
+ topic
447
+ end
448
+ end
449
+
252
450
  ##
253
451
  ## Traverse up directory tree looking for build notes
254
452
  ##
@@ -329,30 +527,6 @@ module Howzit
329
527
  topics_dict
330
528
  end
331
529
 
332
- ##
333
- ## Test to ensure that any `required` metadata in a
334
- ## template is fulfilled by the build note
335
- ##
336
- ## @param template [String] The template to read
337
- ## from
338
- ##
339
- def ensure_requirements(template)
340
- t_leader = Util.read_file(template).split(/^#/)[0].strip
341
- if t_leader.length > 0
342
- t_meta = t_leader.get_metadata
343
- if t_meta.key?('required')
344
- required = t_meta['required'].strip.split(/\s*,\s*/)
345
- required.each do |req|
346
- unless @metadata.keys.include?(req.downcase)
347
- Howzit.console.error %({bRw}ERROR:{xbr} Missing required metadata key from template '{bw}#{File.basename(template, '.md')}{xr}'{x}).c
348
- Howzit.console.error %({br}Please define {by}#{req.downcase}{xr} in build notes{x}).c
349
- Process.exit 1
350
- end
351
- end
352
- end
353
- end
354
- end
355
-
356
530
  ##
357
531
  ## Read a list of topics from an included template
358
532
  ##
@@ -363,87 +537,17 @@ module Howzit
363
537
 
364
538
  template_topics = []
365
539
 
366
- if leader.length > 0
367
- data = leader.get_metadata
540
+ return template_topics if leader.empty?
368
541
 
369
- if data.key?('template')
370
- templates = data['template'].strip.split(/\s*,\s*/)
371
- templates.each do |t|
372
- tasks = nil
373
- if t =~ /\[(.*?)\]$/
374
- tasks = Regexp.last_match[1].split(/\s*,\s*/).map {|t| t.gsub(/\*/, '.*?')}
375
- t = t.sub(/\[.*?\]$/, '').strip
376
- end
542
+ data = leader.get_metadata
377
543
 
378
- t_file = t.sub(/(\.md)?$/, '.md')
379
- template = File.join(Howzit.config.template_folder, t_file)
380
- if File.exist?(template)
381
- ensure_requirements(template)
382
-
383
- t_topics = BuildNote.new(file: template)
384
- if tasks
385
- tasks.each do |task|
386
- t_topics.topics.each do |topic|
387
- if topic.title =~ /^(.*?:)?#{task}$/i
388
- topic.parent = t
389
- template_topics.push(topic)
390
- end
391
- end
392
- end
393
- else
394
- t_topics.topics.map! do |topic|
395
- topic.parent = t
396
- topic
397
- end
398
-
399
- template_topics.concat(t_topics.topics)
400
- end
401
- end
402
- end
403
- end
404
- end
405
- template_topics
406
- end
544
+ if data.key?('template')
545
+ templates = data['template'].strip.split(/\s*,\s*/)
407
546
 
408
- ##
409
- ## Import the contents of a filename as new topics
410
- ##
411
- ## @param mtch [MatchData] the filename match from
412
- ## the include directive
413
- ##
414
- def include_file(mtch)
415
- file = File.expand_path(mtch[1])
416
-
417
- return mtch[0] unless File.exist?(file)
418
-
419
- content = Util.read_file(file)
420
- home = ENV['HOME']
421
- short_path = File.dirname(file.sub(/^#{home}/, '~'))
422
- prefix = "#{short_path}/#{File.basename(file)}:"
423
- parts = content.split(/^##+/)
424
- parts.shift
425
- if parts.empty?
426
- content
427
- else
428
- "## #{parts.join('## ')}".gsub(/^(##+ *)(?=\S)/, "\\1#{prefix}")
547
+ template_topics.concat(gather_templates(templates))
429
548
  end
430
- end
431
-
432
- ##
433
- ## Get the title of the build note (top level header)
434
- ##
435
- ## @param truncate [Integer] Truncate to width
436
- ##
437
- def note_title(truncate = 0)
438
- help = Util.read_file(note_file)
439
- title = help.match(/(?:^(\S.*?)(?=\n==)|^# ?(.*?)$)/)
440
- title = if title
441
- title[1].nil? ? title[2] : title[1]
442
- else
443
- note_file.sub(/(\.\w+)?$/, '')
444
- end
445
549
 
446
- title && truncate.positive? ? title.trunc(truncate) : title
550
+ template_topics
447
551
  end
448
552
 
449
553
  # Read in the build notes file and output a hash of
@@ -465,7 +569,7 @@ module Howzit
465
569
  Process.exit 1
466
570
  end
467
571
 
468
- @title = note_title
572
+ @title = help.note_title(filename)
469
573
 
470
574
  help.gsub!(/@include\((.*?)\)/) do
471
575
  include_file(Regexp.last_match)
@@ -535,14 +639,33 @@ module Howzit
535
639
 
536
640
  raise "Invalid editor (#{editor})" unless Util.valid_command?(editor)
537
641
 
538
- if note_file.nil?
539
- res = Prompt.yn('No build notes file found, create one?', default: true)
642
+ create_note(prompt: true) if note_file.nil?
643
+ `#{editor} "#{note_file}"`
644
+ end
540
645
 
541
- create_note if res
542
- edit_note
543
- else
544
- `#{editor} "#{note_file}"`
545
- end
646
+ ##
647
+ ## Public method to create a new template
648
+ ##
649
+ ## @param template [String] The template name
650
+ ##
651
+ def create_template(template)
652
+ file = template.sub(/(\.md)?$/i, '.md')
653
+ file = File.join(Howzit.config.template_folder, file)
654
+ create_template_file(file, prompt: false)
655
+ end
656
+
657
+ ##
658
+ ## Open template in editor
659
+ ##
660
+ def edit_template_file(file)
661
+ editor = Howzit.options.fetch(:editor, ENV['EDITOR'])
662
+
663
+ raise 'No editor defined' if editor.nil?
664
+
665
+ raise "Invalid editor (#{editor})" unless Util.valid_command?(editor)
666
+
667
+ create_template_file(file, prompt: true) unless File.exist?(file)
668
+ `#{editor} "#{file}"`
546
669
  end
547
670
 
548
671
  ##
@@ -577,17 +700,11 @@ module Howzit
577
700
  unless note_file
578
701
  Process.exit 0 if Howzit.options[:list_runnable_titles] || Howzit.options[:list_topic_titles]
579
702
 
580
- # clear the buffer
581
- ARGV.length.times do
582
- ARGV.shift
583
- end
584
- res = yn("No build notes file found, create one?", true)
585
- create_note if res
586
- Process.exit 1
703
+ create_note(prompt: true)
587
704
  end
588
705
 
589
706
  if Howzit.options[:title_only]
590
- out = note_title(20)
707
+ out = Util.read_file(note_file).note_title(note_file, 20)
591
708
  $stdout.print(out.strip)
592
709
  Process.exit(0)
593
710
  elsif Howzit.options[:output_title] && !Howzit.options[:run]
@@ -620,15 +737,15 @@ module Howzit
620
737
 
621
738
  topic_matches = []
622
739
  if Howzit.options[:grep]
623
- matches = grep_topics(Howzit.options[:grep])
740
+ matches = grep(Howzit.options[:grep])
624
741
  case Howzit.options[:multiple_matches]
625
742
  when :all
626
- topic_matches.concat(matches.sort)
743
+ topic_matches.concat(matches.sort_by(&:title))
627
744
  else
628
- topic_matches.concat(Prompt.choose(matches))
745
+ topic_matches.concat(Prompt.choose(matches.map(&:title), height: :max))
629
746
  end
630
747
  elsif Howzit.options[:choose]
631
- titles = Prompt.choose(list_topics)
748
+ titles = Prompt.choose(list_topics, height: :max)
632
749
  titles.each { |title| topic_matches.push(find_topic(title)[0]) }
633
750
  # If there are arguments use those to search for a matching topic
634
751
  elsif !Howzit.cli_args.empty?
data/lib/howzit/colors.rb CHANGED
@@ -243,6 +243,7 @@ module Howzit
243
243
 
244
244
  ATTRIBUTES.each do |c, v|
245
245
  new_method = <<-EOSCRIPT
246
+ # Color string as #{c}
246
247
  def #{c}(string = nil)
247
248
  result = ''
248
249
  result << "\e[#{v}m" if Howzit::Color.coloring?
@@ -266,6 +267,7 @@ module Howzit
266
267
 
267
268
  # Accept brightwhite in addition to boldwhite
268
269
  new_method = <<-EOSCRIPT
270
+ # color string as #{c}
269
271
  def #{c.to_s.sub(/bold/, 'bright')}(string = nil)
270
272
  result = ''
271
273
  result << "\e[#{v}m" if Howzit::Color.coloring?
@@ -286,6 +288,13 @@ module Howzit
286
288
  module_eval(new_method)
287
289
  end
288
290
 
291
+ ##
292
+ ## Generate escape codes for hex colors
293
+ ##
294
+ ## @param hex [String] The hexadecimal color code
295
+ ##
296
+ ## @return [String] ANSI escape string
297
+ ##
289
298
  def rgb(hex)
290
299
  is_bg = hex.match(/^bg?#/) ? true : false
291
300
  hex_string = hex.sub(/^([fb]g?)?#/, '')
data/lib/howzit/config.rb CHANGED
@@ -89,6 +89,7 @@ module Howzit
89
89
  flags = {
90
90
  choose: false,
91
91
  default: false,
92
+ for_topic: nil,
92
93
  grep: nil,
93
94
  list_runnable: false,
94
95
  list_runnable_titles: false,