howzit 2.0.14 → 2.0.17

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.
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,