Module: Howzit::StringUtils
- Included in:
- String
- Defined in:
- lib/howzit/stringutils.rb
Overview
String Extensions
Instance Method Summary collapse
-
#available? ⇒ Boolean
Test if an executable is available on the system.
-
#build_note? ⇒ Boolean
Test if the filename matches the conditions to be a build note.
-
#c ⇒ String
Shortcut for calling Color.template.
-
#extract_metadata ⇒ Hash
Split the content at the first top-level header and assume everything before it is metadata.
-
#format_header(opts = {}) ⇒ String
Make a fancy title line for the topic.
-
#get_metadata ⇒ Hash
Examine text for multimarkdown-style metadata and return key/value pairs.
-
#iterm_marker ⇒ String
Output an iTerm marker.
-
#normalize_metadata(meta) ⇒ Hash
Autocorrect some keys.
-
#note_title(file, truncate = 0) ⇒ Object
Get the title of the build note (top level header).
-
#preserve_escapes ⇒ String
Replace slash escaped characters in a string with a zero-width space that will prevent a shell from interpreting them when output to console.
-
#render_arguments ⇒ String
Render $X placeholders based on positional arguments.
- #render_named_placeholders ⇒ Object
- #render_numeric_placeholders ⇒ Object
-
#render_template(vars) ⇒ String
Render [%variable] placeholders in a templated string.
-
#render_template!(vars) ⇒ Object
Render [%variable] placeholders in place.
-
#should_mark_iterm? ⇒ Boolean
Test if iTerm markers should be output.
-
#split_line(width, indent = '') ⇒ Object
Splits a line at nearest word break.
-
#to_config_value(orig_value = nil) ⇒ Object
Convert a string to a valid YAML value.
-
#to_rx ⇒ Regexp
Convert a string to a regex object based on matching settings.
-
#trunc(len) ⇒ Object
Truncate string to nearest word.
-
#trunc!(len) ⇒ Object
Truncate string in place (destructive).
-
#uncolor ⇒ Object
Just strip out color codes when requested.
-
#wrap(width) ⇒ String
Wrap text at a specified width.
-
#wrap!(width) ⇒ Object
Wrap string in place (destructive).
Instance Method Details
#available? ⇒ Boolean
Test if an executable is available on the system
209 210 211 |
# File 'lib/howzit/stringutils.rb', line 209 def available? Util.valid_command?(self) end |
#build_note? ⇒ Boolean
Test if the filename matches the conditions to be a build note
11 12 13 14 15 16 17 |
# File 'lib/howzit/stringutils.rb', line 11 def build_note? return false if downcase !~ /^(howzit[^.]*|build[^.]+)/ return false if Howzit.config.should_ignore(self) true end |
#c ⇒ String
Shortcut for calling Color.template
82 83 84 |
# File 'lib/howzit/stringutils.rb', line 82 def c Color.template(self) end |
#extract_metadata ⇒ Hash
Split the content at the first top-level header and assume everything before it is metadata. Passes to
get_metadata for processing
273 274 275 276 277 278 279 280 |
# File 'lib/howzit/stringutils.rb', line 273 def if File.exist?(self) leader = Util.read_file(self).split(/^#/)[0].strip leader.length > 0 ? leader. : {} else {} end end |
#format_header(opts = {}) ⇒ String
Make a fancy title line for the topic
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 |
# File 'lib/howzit/stringutils.rb', line 347 def format_header(opts = {}) title = dup = { hr: "\u{254C}", color: '{bg}', border: '{x}', mark: should_mark_iterm? } .merge!(opts) case Howzit.[:header_format] when :block Color.template("#{options[:color]}\u{258C}#{title}#{should_mark_iterm? && options[:mark] ? iterm_marker : ''}{x}") else cols = TTY::Screen.columns cols = Howzit.[:wrap] if (Howzit.[:wrap]).positive? && cols > Howzit.[:wrap] title = Color.template("#{options[:border]}#{options[:hr] * 2}( #{options[:color]}#{title}#{options[:border]} )") tail = if should_mark_iterm? "#{options[:hr] * (cols - title.uncolor.length - 15)}#{options[:mark] ? iterm_marker : ''}" else [:hr] * (cols - title.uncolor.length) end Color.template("#{title}#{tail}{x}") end end |
#get_metadata ⇒ Hash
Examine text for multimarkdown-style metadata and return key/value pairs
287 288 289 290 291 292 293 294 295 296 |
# File 'lib/howzit/stringutils.rb', line 287 def data = {} scan(/(?mi)^(\S[\s\S]+?): ([\s\S]*?)(?=\n\S[\s\S]*?:|\Z)/).each do |m| data[m[0].strip.downcase] = m[1] end out = (data) Howzit.named_arguments ||= {} Howzit.named_arguments = out.merge(Howzit.named_arguments) out end |
#iterm_marker ⇒ String
Output an iTerm marker
337 338 339 |
# File 'lib/howzit/stringutils.rb', line 337 def iterm_marker "\e]1337;SetMark\a" if should_mark_iterm? end |
#normalize_metadata(meta) ⇒ Hash
Autocorrect some keys
305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
# File 'lib/howzit/stringutils.rb', line 305 def () data = {} .each do |k, v| case k when /^te?m?pl(ate)?s?$/ data['template'] = v when /^req\w*$/ data['required'] = v else data[k] = v end end data end |
#note_title(file, truncate = 0) ⇒ Object
Get the title of the build note (top level header)
24 25 26 27 28 29 30 31 32 33 |
# File 'lib/howzit/stringutils.rb', line 24 def note_title(file, truncate = 0) title = match(/(?:^(\S.*?)(?=\n==)|^# ?(.*?)$)/) title = if title title[1].nil? ? title[2] : title[1] else file.sub(/(\.\w+)?$/, '') end title && truncate.positive? ? title.trunc(truncate) : title end |
#preserve_escapes ⇒ String
Replace slash escaped characters in a string with a zero-width space that will prevent a shell from interpreting them when output to console
42 43 44 |
# File 'lib/howzit/stringutils.rb', line 42 def preserve_escapes gsub(/\\([a-z])/, '\\1') end |
#render_arguments ⇒ String
Render $X placeholders based on positional arguments
243 244 245 246 247 248 |
# File 'lib/howzit/stringutils.rb', line 243 def render_arguments str = dup str.render_named_placeholders str.render_numeric_placeholders Howzit.arguments.nil? ? str : str.gsub(/\$[@*]/, Shellwords.join(Howzit.arguments)) end |
#render_named_placeholders ⇒ Object
250 251 252 253 254 255 256 |
# File 'lib/howzit/stringutils.rb', line 250 def render_named_placeholders gsub!(/\$\{(?<name>[A-Z0-9_]+(?::.*?)?)\}/i) do m = Regexp.last_match arg, default = m['name'].split(/:/).map(&:strip) Howzit.named_arguments.key?(arg) && !Howzit.named_arguments[arg].nil? ? Howzit.named_arguments[arg] : default end end |
#render_numeric_placeholders ⇒ Object
258 259 260 261 262 263 264 |
# File 'lib/howzit/stringutils.rb', line 258 def render_numeric_placeholders gsub!(/\$\{?(\d+)\}?/) do arg, default = Regexp.last_match(1).split(/:/) idx = arg.to_i - 1 Howzit.arguments.length > idx ? Howzit.arguments[idx] : default || Regexp.last_match(0) end end |
#render_template(vars) ⇒ String
Render [%variable] placeholders in a templated string
221 222 223 224 225 226 227 |
# File 'lib/howzit/stringutils.rb', line 221 def render_template(vars) vars.each do |k, v| gsub!(/\[%#{k}(:.*?)?\]/, v) end gsub(/\[%(.*?):(.*?)\]/, '\2') end |
#render_template!(vars) ⇒ Object
Render [%variable] placeholders in place
234 235 236 |
# File 'lib/howzit/stringutils.rb', line 234 def render_template!(vars) replace render_template(vars) end |
#should_mark_iterm? ⇒ Boolean
Test if iTerm markers should be output. Requires that the $TERM_PROGRAM be iTerm and howzit is not running directives or paginating output
327 328 329 |
# File 'lib/howzit/stringutils.rb', line 327 def should_mark_iterm? ENV['TERM_PROGRAM'] =~ /^iTerm/ && !Howzit.[:run] && !Howzit.[:paginate] end |
#split_line(width, indent = '') ⇒ Object
Splits a line at nearest word break
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/howzit/stringutils.rb', line 187 def split_line(width, indent = '') line = dup at = line.index(/\s/) last_at = at while !at.nil? && at < width last_at = at at = line.index(/\s/, last_at + 1) end if last_at.nil? [indent + line[0, width], line[width, line.length]] else [indent + line[0, last_at], line[last_at + 1, line.length]] end end |
#to_config_value(orig_value = nil) ⇒ Object
Convert a string to a valid YAML value
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/howzit/stringutils.rb', line 53 def to_config_value(orig_value = nil) if orig_value case orig_value.class.to_s when /Integer/ to_i when /(True|False)Class/ self =~ /^(t(rue)?|y(es)?|1)$/i ? true : false else self end else case self when /^[0-9]+$/ to_i when /^(t(rue)?|y(es)?)$/i true when /^(f(alse)?|n(o)?)$/i false else self end end end |
#to_rx ⇒ Regexp
Convert a string to a regex object based on matching settings
91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/howzit/stringutils.rb', line 91 def to_rx case Howzit.[:matching] when 'exact' /^#{self}$/i when 'beginswith' /^#{self}/i when 'fuzzy' /#{split(//).join('.{0,3}?')}/i else /#{self}/i end end |
#trunc(len) ⇒ Object
Truncate string to nearest word
164 165 166 167 168 169 170 |
# File 'lib/howzit/stringutils.rb', line 164 def trunc(len) split(/ /).each_with_object([]) do |x, ob| break ob unless ob.join(' ').length + ' '.length + x.length <= len ob.push(x) end.join(' ').strip end |
#trunc!(len) ⇒ Object
Truncate string in place (destructive)
177 178 179 |
# File 'lib/howzit/stringutils.rb', line 177 def trunc!(len) replace trunc(len) end |
#uncolor ⇒ Object
Just strip out color codes when requested
105 106 107 |
# File 'lib/howzit/stringutils.rb', line 105 def uncolor gsub(/\e\[[\d;]+m/, '').gsub(/\e\]1337;SetMark/,'') end |
#wrap(width) ⇒ String
Wrap text at a specified width.
Adapted from https://github.com/pazdera/word_wrap/, copyright (c) 2014, 2015 Radek Pazdera Distributed under the MIT License
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/howzit/stringutils.rb', line 120 def wrap(width) width ||= 80 output = [] indent = '' text = gsub(/\t/, ' ') text.lines do |line| line.chomp! "\n" if line.length > width indent = if line.uncolor =~ /^(\s*(?:[+\-*]|\d+\.) )/ ' ' * Regexp.last_match[1].length else '' end new_lines = line.split_line(width) while new_lines.length > 1 && new_lines[1].length + indent.length > width output.push new_lines[0] new_lines = new_lines[1].split_line(width, indent) end output += [new_lines[0], indent + new_lines[1]] else output.push line end end output.map!(&:rstrip) output.join("\n") end |
#wrap!(width) ⇒ Object
Wrap string in place (destructive)
156 157 158 |
# File 'lib/howzit/stringutils.rb', line 156 def wrap!(width) replace(wrap(width)) end |