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
277 278 279 280 281 282 283 284 |
# File 'lib/howzit/stringutils.rb', line 277 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
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 |
# File 'lib/howzit/stringutils.rb', line 351 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("#{[:color]}\u{258C}#{title}#{should_mark_iterm? && [:mark] ? iterm_marker : ''}{x}") else cols = TTY::Screen.columns cols = Howzit.[:wrap] if (Howzit.[:wrap]).positive? && cols > Howzit.[:wrap] title = Color.template("#{[:border]}#{[:hr] * 2}( #{[:color]}#{title}#{[:border]} )") tail = if should_mark_iterm? "#{[:hr] * (cols - title.uncolor.length - 15)}#{[: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
291 292 293 294 295 296 297 298 299 300 |
# File 'lib/howzit/stringutils.rb', line 291 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
341 342 343 |
# File 'lib/howzit/stringutils.rb', line 341 def iterm_marker "\e]1337;SetMark\a" if should_mark_iterm? end |
#normalize_metadata(meta) ⇒ Hash
Autocorrect some keys
309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/howzit/stringutils.rb', line 309 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
247 248 249 250 251 252 |
# File 'lib/howzit/stringutils.rb', line 247 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
254 255 256 257 258 259 260 |
# File 'lib/howzit/stringutils.rb', line 254 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
262 263 264 265 266 267 268 |
# File 'lib/howzit/stringutils.rb', line 262 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 228 229 230 231 |
# File 'lib/howzit/stringutils.rb', line 221 def render_template(vars) vars.each do |k, v| gsub!(/\[%#{k}(:.*?)?\]/, v) end # Replace empty variables with default gsub!(/\[%(.*?):(.*?)\]/, '\2') # Remove remaining empty variables gsub(/\[%(.*?)\]/, '') end |
#render_template!(vars) ⇒ Object
Render [%variable] placeholders in place
238 239 240 |
# File 'lib/howzit/stringutils.rb', line 238 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
331 332 333 |
# File 'lib/howzit/stringutils.rb', line 331 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 |