Class: String

Inherits:
Object
  • Object
show all
Defined in:
lib/conductor/filter.rb,
lib/conductor/string.rb

Overview

String helpers

Direct Known Subclasses

Conductor::Filter

Instance Method Summary collapse

Instance Method Details

#add_comment(key, value) ⇒ Object



484
485
486
487
488
489
490
491
492
# File 'lib/conductor/filter.rb', line 484

def add_comment(key, value)
  if comment?(key)
    sub(/ *#{key}: .*?$/, "#{key}: #{value}")
  else
    lines = utf8.split(/\n/)
    lines.insert(meta_insert_point + 1, "\n<!--\n#{key}: #{value}\n-->")
    lines.join("\n")
  end
end

#add_mmd(key, value) ⇒ Object



466
467
468
469
470
471
472
473
474
# File 'lib/conductor/filter.rb', line 466

def add_mmd(key, value)
  if match(/(\A|\n) *#{key}: *\S+/i)
    sub(/^ *#{key}:.*?\n/i, "#{key}: #{value}\n")
  else
    lines = utf8.split(/\n/)
    lines.insert(meta_insert_point, "#{key}: #{value}")
    "#{lines.join("\n")}\n"
  end
end

#add_yaml(key, value) ⇒ Object



448
449
450
451
452
453
454
455
# File 'lib/conductor/filter.rb', line 448

def add_yaml(key, value)
  sub(/^---.*?\n(---|\.\.\.)/m) do
    m = Regexp.last_match
    yaml = YAML.load(m[0])
    yaml[key.gsub(/ /, "_")] = value
    "#{YAML.dump(yaml)}---\n"
  end
end

#append(string) ⇒ Object

Append string to self

Parameters:

  • string (String)

    The string to append

Returns:

  • self with string appended



314
315
316
# File 'lib/conductor/filter.rb', line 314

def append(string)
  "#{self}\n#{string}"
end

#append!(string) ⇒ Object

Destructive version of #append

Returns:

  • self with string appended

See Also:



324
325
326
# File 'lib/conductor/filter.rb', line 324

def append!(string)
  replace append(string)
end


528
529
530
531
# File 'lib/conductor/filter.rb', line 528

def autolink
  gsub(%r{(?mi)(?<!\(|\]: |"|')\b((?:[\w-]+?://)[-a-zA-Z0-9@:%._+~#=]{2,256}\b(?:[-a-zA-Z0-9@:%_+.~#?&/=]*))},
       '<\1>')
end

#bool?Boolean

Test if a string is a boolean

Returns:

  • (Boolean)

    test result



129
130
131
# File 'lib/conductor/string.rb', line 129

def bool?
  dup.force_encoding("utf-8").match?(/^(?:y(?:es)?|no?|t(?:rue)?|f(?:alse)?)$/)
end

#bool_to_symbolSymbol

Convert a string boolean to symbol

Returns:

  • (Symbol)

    symbolized version



57
58
59
60
61
62
63
64
65
66
# File 'lib/conductor/string.rb', line 57

def bool_to_symbol
  case self
  when /(NOT|!!)/
    :not
  when /(AND|&&)/
    :and
  else
    :or
  end
end

#clean_encodeString

Get a clean UTF-8 string by forcing an ISO encoding and then re-encoding

Returns:



226
227
228
# File 'lib/conductor/string.rb', line 226

def clean_encode
  force_encoding("ISO-8859-1").encode("utf-8", replace: nil)
end

#clean_encode!String

Destructive version of #clean_encode

Returns:

  • (String)

    UTF-8 string, in place



235
236
237
# File 'lib/conductor/string.rb', line 235

def clean_encode!
  replace clean_encode
end

#comment?(key) ⇒ Boolean

Returns:

  • (Boolean)


480
481
482
# File 'lib/conductor/filter.rb', line 480

def comment?(key)
  match(/^<!--.*?#{key}: \S.*?-->/m)
end

#count_h1sInteger

Count the number of h1 headers in the document

Returns:

  • (Integer)

    Number of h1s.



538
539
540
# File 'lib/conductor/filter.rb', line 538

def count_h1s
  scan(/^#[^#]/).count
end

#date?Boolean

Test a string to see if it’s a UTC date

Returns:

  • (Boolean)

    test result



73
74
75
# File 'lib/conductor/string.rb', line 73

def date?
  dup.force_encoding("utf-8") =~ /^\d{4}-\d{2}-\d{2}( \d{1,2}(:\d\d)? *([ap]m)?)?$/ ? true : false
end

#decrease_headers(amt = 1) ⇒ Object

Decrease all headers by given amount

Parameters:

  • amt (Integer) (defaults to: 1)

    The amount to decrease



138
139
140
141
142
143
144
145
146
# File 'lib/conductor/filter.rb', line 138

def decrease_headers(amt = 1)
  normalize_headers.gsub(/^(\#{1,6})(?!=#)/) do
    m = Regexp.last_match
    level = m[1].size
    level -= amt
    level = 1 if level < 1
    "#" * level
  end
end

#delete_meta(key) ⇒ Object



494
495
496
497
498
499
500
501
502
503
# File 'lib/conductor/filter.rb', line 494

def delete_meta(key)
  case meta_type
  when :yaml
    delete_yaml(key)
  when :mmd
    delete_mmd(key)
  else
    self
  end
end

#delete_mmd(key) ⇒ Object



476
477
478
# File 'lib/conductor/filter.rb', line 476

def delete_mmd(key)
  sub(/^ *#{key}:.*?\n/i, "")
end

#delete_yaml(key) ⇒ Object



457
458
459
460
461
462
463
464
# File 'lib/conductor/filter.rb', line 457

def delete_yaml(key)
  sub(/^---.*?\n(---|\.\.\.)/m) do
    m = Regexp.last_match
    yaml = YAML.load(m[0])
    yaml.delete(key)
    "#{YAML.dump(yaml)}\n---\n"
  end
end

#ensure_h1String

Ensure there’s at least one H1 in the document

If no H1 is found, converts the lowest level header (first one) into an H1

Returns:

  • (String)

    content with at least 1 H1



576
577
578
579
580
581
582
583
584
585
586
# File 'lib/conductor/filter.rb', line 576

def ensure_h1
  headers = to_enum(:scan, /(\#{1,6})([^#].*?)$/m).map { Regexp.last_match }
  return self unless headers.select { |h| h[1].size == 1 }.empty?

  lowest_header = headers.min_by { |h| h[1].size }
  return self if lowest_header.nil?

  level = lowest_header[1].size - 1

  sub(/#{Regexp.escape(lowest_header[0])}/, "# #{lowest_header[2].strip}").decrease_headers(level)
end

#ensure_h1!Object

Destructive version of #ensure_h1

Returns:

  • Content with at least one H1

See Also:



595
596
597
# File 'lib/conductor/filter.rb', line 595

def ensure_h1!
  replace ensure_h1
end

#ensure_mmd_meta_newlineObject



444
445
446
# File 'lib/conductor/filter.rb', line 444

def ensure_mmd_meta_newline
  utf8.split(/\n/).insert(meta_insert_point, "\n\n").join("\n")
end

#find_file_in(paths, filename, ext) ⇒ Object

Search config folder for multiple subfolders and content

Parameters:

  • paths (Array)

    The possible directory names

  • filename (String)

    The filename to search for

  • ext (String)

    The file extension



12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/conductor/filter.rb', line 12

def find_file_in(paths, filename, ext)
  return filename if File.exist?(filename)

  ext = ext.sub(/^\./, "")

  filename = File.basename(filename, ".#{ext}")

  paths.each do |path|
    exp = File.join(File.expand_path("~/.config/conductor/"), path, "#{filename}.#{ext}")
    return exp if File.exist?(exp)
  end
  "#{filename}.#{ext}"
end

#first_h1Integer

Locate the first H1 in the document

Returns:

  • (Integer)

    index of first H1



103
104
105
106
107
108
109
110
111
112
# File 'lib/conductor/filter.rb', line 103

def first_h1
  first = nil
  utf8.split(/\n/).each_with_index do |line, idx|
    if line =~ /^(# *[^#]|={2,} *$)/
      first = idx
      break
    end
  end
  first
end

#first_h2Integer

Locate the first H2 in the document

Returns:

  • (Integer)

    index of first H2



119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/conductor/filter.rb', line 119

def first_h2
  first = nil
  meta_end = meta_insert_point
  utf8.split(/\n/).each_with_index do |line, idx|
    next if idx <= meta_end

    if line =~ /^(## *[^#]|-{2,} *$)/
      first = idx
      break
    end
  end
  first
end

#fix_headersObject

Bump all headers except for first H1

Returns:

  • Content with adjusted headers



604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
# File 'lib/conductor/filter.rb', line 604

def fix_headers
  return self if count_h1s == 1

  h1 = true

  gsub(/^(\#{1,6})([^#].*?)$/) do
    m = Regexp.last_match
    level = m[1].size
    content = m[2].strip
    if level == 1 && h1
      h1 = false
      m[0]
    else
      level += 1 if level < 6

      "#{"#" * level} #{content}"
    end
  end
end

#fix_headers!String

Destructive version of #fix_headers

Returns:

  • (String)

    headers fixed #

See Also:



632
633
634
# File 'lib/conductor/filter.rb', line 632

def fix_headers!
  replace fix_headers
end

#fix_hierarchyObject

Adjust header levels so there’s no jump greater than 1

Returns:

  • Content with adjusted headers



641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
# File 'lib/conductor/filter.rb', line 641

def fix_hierarchy
  normalize_headers!
  ensure_h1!
  fix_headers!
  headers = to_enum(:scan, /(\#{1,6})([^#].*?)$/m).map { Regexp.last_match }
  content = dup
  last = 1
  headers.each do |h|
    level = h[1].size
    if level <= last + 1
      last = level
      next
    end

    level = last + 1
    content.sub!(/#{Regexp.escape(h[0])}/, "#{"#" * level} #{h[2].strip}")
  end

  content
end

#increase_headers(amt = 1) ⇒ String

Increase all header levels by amount

Parameters:

  • amt (Integer) (defaults to: 1)

    number to increase by (1-5)

Returns:

  • (String)

    content with headers increased



155
156
157
# File 'lib/conductor/filter.rb', line 155

def increase_headers(amt = 1)
  normalize_headers.gsub(/^#/, "#{"#" * amt}#").gsub(/^\#{7,}/, "######")
end

#increase_headers!(amt = 1) ⇒ String

Destructive version of #increase_headers

Parameters:

  • amt (Integer) (defaults to: 1)

    The amount

Returns:

  • (String)

    content with headers increased

See Also:



168
169
170
# File 'lib/conductor/filter.rb', line 168

def increase_headers!(amt = 1)
  replace increase_headers(amt)
end

#inject_after_meta(content) ⇒ String

Insert the given content after any existing metadata

Parameters:

  • content (String)

    The content

Returns:

  • (String)

    string with content injected



257
258
259
260
261
262
263
# File 'lib/conductor/filter.rb', line 257

def inject_after_meta(content)
  lines = utf8.split(/\n/)
  insert_point = meta_insert_point
  insert_at = insert_point.positive? ? insert_point + 1 : 0
  lines.insert(insert_at, "#{content}\n\n")
  lines.join("\n")
end

#insert_css(path) ⇒ String

Insert raw CSS into the document, reading from a file and compressing contents

Parameters:

  • path (String)

    The CSS file path

Returns:

  • (String)

    content with raw CSS injected



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/conductor/filter.rb', line 228

def insert_css(path)
  return insert_stylesheet(path) if path.strip =~ /^http/

  path = path.sub(/(\.css)?$/, ".css")

  if path =~ %r{^[~/.]}
    path = File.expand_path(path)
  else
    path = find_file_in(%w[css styles files], path, "css")
  end

  if File.exist?(path)
    content = IO.read(path)
    yui = YuiCompressor::Yui.new
    content = yui.compress(content.utf8)
    inject_after_meta(content.wrap_style)
  else
    warn "File not found (#{path})"
    self
  end
end

#insert_file(path, type = :file, position = :end) ⇒ Object

Insert a file include syntax for various types

Parameters:

  • path (String)

    The file path

  • type (Symbol) (defaults to: :file)

    The type (:file, :code, :raw)

  • position (Symbol) (defaults to: :end)

    The position (:start, :h1, :h2, :end)



272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/conductor/filter.rb', line 272

def insert_file(path, type = :file, position = :end)
  path = path.strip

  path = if path =~ %r{^[.~/]}
      File.expand_path(path)
    else
      find_file_in(%w[files], path, File.extname(path))
    end

  warn "File not found: #{path}" unless File.exist?(path)

  out = case type
    when :code
      "<<(#{path})"
    when :raw
      "<<{#{path}}"
    else
      "<<[#{path}]"
    end
  out = "\n#{out}\n"

  case position
  when :start
    inject_after_meta(out)
  when :h1
    h1 = first_h1.nil? ? 0 : first_h1 + 1
    utf8.split(/\n/).insert(h1, out).join("\n")
  when :h2
    h2 = first_h2.nil? ? 0 : first_h2 + 1
    utf8.split(/\n/).insert(h2, out).join("\n")
  else
    "#{self}\n#{out}"
  end
end

#insert_javascript(path) ⇒ Object

Append a <script> tag for a given path

Parameters:

Returns:

  • self with javascript tag appended



335
336
337
# File 'lib/conductor/filter.rb', line 335

def insert_javascript(path)
  %(#{self}\n<script type="javascript" src="#{path.strip}"></script>\n)
end

#insert_raw_javascript(content) ⇒ Object

Append raw javascript

Parameters:

  • content (String)

    The content

Returns:

  • self with script tag containing contents appended



346
347
348
# File 'lib/conductor/filter.rb', line 346

def insert_raw_javascript(content)
  %(#{self}\n<script>#{content}</script>\n)
end

#insert_script(path) ⇒ Object

Insert javascript, detecting raw js and files, inserting appropriately

Paths that are just a filename will be searched for in various .config directories. If found, a full path will be used.

Parameters:

  • path (String)

    The path or raw content to inject



358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
# File 'lib/conductor/filter.rb', line 358

def insert_script(path)
  path = path.strip
  orig_path = path

  return insert_javascript(path) if path =~ /^http/

  return insert_raw_javascript(path) if path =~ /\(.*?\)/

  path = if path =~ %r{^[~/.]}
      File.expand_path(path)
    else
      find_file_in(%w[javascript javascripts js scripts], path.sub(/(\.js)?$/, ".js"), "js")
    end

  if File.exist?(path)
    insert_javascript(path)
  else
    warn "Javascript not found: #{path}"
    insert_javascript(orig_path)
  end
end

#insert_stylesheet(path) ⇒ String

Insert a <link> tag for the given path

Parameters:

  • path (String)

    path to CSS files

Returns:

  • (String)

    path with <style> link added



215
216
217
218
# File 'lib/conductor/filter.rb', line 215

def insert_stylesheet(path)
  path = find_file_in(%w[css styles], path, "css") unless path =~ /^http/
  inject_after_meta(%(<link rel="stylesheet" href="#{path.strip}">))
end

#insert_title(shift: 0) ⇒ Object



422
423
424
425
426
427
428
429
430
431
# File 'lib/conductor/filter.rb', line 422

def insert_title(shift: 0)
  content = dup.utf8
  title = read_title
  content.increase_headers!(shift) if shift.positive?
  lines = content.split(/\n/)
  insert_point = content.meta_insert_point
  insert_at = insert_point.positive? ? insert_point + 1 : 0
  lines.insert(insert_at, "# #{title}\n")
  lines.join("\n")
end

#insert_toc(max = nil, after = :h1) ⇒ String

Insert a Table of Contents at given position

Parameters:

  • max (Integer) (defaults to: nil)

    The maximum depth of the TOC

  • after (Symbol) (defaults to: :h1)

    Where to place TOC after (:top, :h1, :h2)

Returns:

  • (String)

    content with TOC tag added



180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/conductor/filter.rb', line 180

def insert_toc(max = nil, after = :h1)
  lines = utf8.split(/\n/)
  max = max.to_i&.positive? ? " max#{max}" : ""
  line = case after.to_sym
    when :h2
      first_h2.nil? ? 0 : first_h2 + 1
    when :h1
      first_h1.nil? ? 0 : first_h1 + 1
    else
      meta_insert_point.positive? ? meta_insert_point + 1 : 0
    end

  lines.insert(line, "\n<!--toc#{max}-->\n").join("\n")
end

#meta?Boolean

Test if a string starts with MMD metadata

Returns:

  • (Boolean)

    test result



147
148
149
# File 'lib/conductor/string.rb', line 147

def meta?
  dup.force_encoding('utf-8').match?(/^\w+: +\S+/m)
end

#meta_insert_pointInteger

Determine which line to use to insert after existing metadata

Returns:

  • (Integer)

    line index



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/conductor/filter.rb', line 64

def meta_insert_point
  insert_point = 0

  case meta_type
  when :yaml
    lines = utf8.split(/\n/)
    lines.shift
    lines.each_with_index do |line, idx|
      next unless line =~ /^(\.\.\.|---) *$/

      insert_point = idx + 1
      break
    end
  when :mmd
    lines = utf8.split(/\n/)
    lines.each_with_index do |line, idx|
      next if line =~ /^ *[ \w]+: +\S+/

      insert_point = idx
      break
    end
  when :pandoc
    lines = utf8.split(/\n/)
    lines.each_with_index do |line, idx|
      next if line =~ /^% +\S/

      insert_point = idx
      break
    end
  end

  insert_point
end

#meta_typeSymbol

Determine type of metadata (yaml, mmd, none)

Returns:

  • (Symbol)

    metadata type



45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/conductor/filter.rb', line 45

def meta_type
  lines = utf8.split(/\n/)
  case lines[0]
  when /^--- *$/
    :yaml
  when /^ *[ \w]+: +\S+/
    :mmd
  when /^% +\S/
    :pandoc
  else
    :none
  end
end

#normalize_filterArray<String,Array>

Normalize the filter name and parameters, downcasing and removing spaces, underscores, splitting params by comma

Returns:

  • (Array<String,Array>)

    array containing normalize filter and array of parameters



33
34
35
36
37
38
# File 'lib/conductor/filter.rb', line 33

def normalize_filter
  parts = match(/(?<filter>[\w_]+)(?:\((?<paren>.*?)\))?$/i)
  filter = parts["filter"].downcase.gsub(/_/, "")
  params = parts["paren"]&.split(/ *, */)
  [filter, params]
end

#normalize_headersString

Normalize Setext headers to ATX

Returns:

  • (String)

    content with headers updated



547
548
549
550
551
552
553
554
555
556
557
# File 'lib/conductor/filter.rb', line 547

def normalize_headers
  gsub(/^(?<=\n\n|^)(\S[^\n]+)\n([=-]{2,})\n/) do
    m = Regexp.last_match
    case m[2]
    when /=/
      "# #{m[1]}\n\n"
    else
      "## #{m[1]}\n\n"
    end
  end
end

#normalize_headers!Object

Destructive version of #normalize_headers

Returns:

  • String with setext headers converted to ATX

See Also:



565
566
567
# File 'lib/conductor/filter.rb', line 565

def normalize_headers!
  replace normalize_headers
end

#normalize_include_typeSymbol

Normalize a file include string to symbol

Returns:

  • (Symbol)

    include type symbol (:code, :raw, :file)



41
42
43
44
45
46
47
48
49
50
# File 'lib/conductor/string.rb', line 41

def normalize_include_type
  case self
  when /^c/
    :code
  when /^r/
    :raw
  else
    :file
  end
end

#normalize_positionSymbol

Normalize positional string to symbol

Returns:

  • (Symbol)

    position symbol (:start, :h1, :h2, :end)



23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/conductor/string.rb', line 23

def normalize_position
  case self
  when /^(be|s|t)/
    :start
  when /h1/
    :h1
  when /h2/
    :h2
  else
    :end
  end
end

#number?Boolean

Test if a string is a number

Returns:

  • (Boolean)

    test result



120
121
122
# File 'lib/conductor/string.rb', line 120

def number?
  to_f.positive?
end

#pandoc?Boolean

Test if a string starts with Pandoc metadata

Returns:

  • (Boolean)

    test result



156
157
158
# File 'lib/conductor/string.rb', line 156

def pandoc?
  dup.force_encoding('utf-8').match?(/^% \S/m)
end

#read_titleObject



388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
# File 'lib/conductor/filter.rb', line 388

def read_title
  title = nil

  case meta_type
  when :yaml
    m = match(/^---.*?\n(---|\.\.\.)/m)
    yaml = YAML.load(m[0])
    title = yaml["title"]
  when :mmd
    utf8.split(/\n/).each do |line|
      if line =~ /^ *title: *(\S.*?)$/i
        title = Regexp.last_match(1)
        break
      end
    end
  when :pandoc
    title = nil
    utf8.split(/\n/).each do |line|
      if line =~ /^% +(.*?)$/
        title = Regexp.last_match(1)
        break
      end
    end
    title
  else
    m = match(/title: (.*?)$/i)
    title = m ? m[0] : nil
  end

  title ||= title_from_slug.titleize

  title
end

#replace_all(regex, pattern) ⇒ Object



520
521
522
# File 'lib/conductor/filter.rb', line 520

def replace_all(regex, pattern)
  gsub(regex.to_rx, pattern.to_pattern)
end

#replace_one(regex, pattern) ⇒ Object



524
525
526
# File 'lib/conductor/filter.rb', line 524

def replace_one(regex, pattern)
  sub(regex.to_rx, pattern.to_pattern)
end

#set_meta(key, value, style: :comment) ⇒ Object



433
434
435
436
437
438
439
440
441
442
# File 'lib/conductor/filter.rb', line 433

def set_meta(key, value, style: :comment)
  case style
  when :yaml
    add_yaml(key, value)
  when :mmd
    add_mmd(key, value).ensure_mmd_meta_newline
  else # comment or none
    add_comment(key, value)
  end
end

#split_listObject



14
15
16
# File 'lib/conductor/string.rb', line 14

def split_list
  split(/,/).map { |s| Shellwords.shellsplit(s) }
end

#strip_metaObject



505
506
507
508
509
510
511
512
513
514
515
516
517
518
# File 'lib/conductor/filter.rb', line 505

def strip_meta
  case meta_type
  when :yaml
    sub(/^---.*?(---|\.\.\.)/m, "")
  when :mmd
    lines = utf8.split(/\n/)
    lines[meta_insert_point..].join("\n")
  when :pandoc
    lines = utf8.split(/\n/)
    lines[meta_insert_point..].join("\n")
  else
    gsub(/(\n|^)<!--\n[\w\d\s]+: ([\w\d\s]+)\n-->\n/m, "")
  end
end

#strip_timeString

Remove time from string

Returns:

  • (String)

    string with time removed



101
102
103
# File 'lib/conductor/string.rb', line 101

def strip_time
  dup.force_encoding("utf-8").sub(/ \d{1,2}(:\d\d)? *([ap]m)?/i, "")
end

#time?Boolean

Test a string to see if it includes a time

Returns:

  • (Boolean)

    test result



82
83
84
# File 'lib/conductor/string.rb', line 82

def time?
  dup.force_encoding("utf-8") =~ / \d{1,2}(:\d\d)? *([ap]m)?/i ? true : false
end

#title_from_slugObject



380
381
382
383
384
385
386
# File 'lib/conductor/filter.rb', line 380

def title_from_slug
  filename = File.basename(Conductor::Env.env[:filepath]).sub(/\.[a-z]+$/i, "")
  filename.sub!(/-?\d{4}-\d{2}-\d{2}-?/, "")
  filename.sub!(/\bdot\b/, ".")
  filename.sub!(/ dash /, "-")
  filename.gsub(/-/, " ")
end

#titleizeObject

Titlecase a string

Returns:

  • Titleized string



10
11
12
# File 'lib/conductor/string.rb', line 10

def titleize
  split(/(\W)/).map(&:capitalize).join
end

#to_boolBoolean

Returns a bool representation of the string.

Returns:

  • (Boolean)

    Bool representation of the object.



165
166
167
168
169
170
171
172
# File 'lib/conductor/string.rb', line 165

def to_bool
  case self.dup.force_encoding('utf-8')
  when /^[yt]/i
    true
  else
    false
  end
end

#to_dateDate

Convert a natural language string to a Date

object

Returns:

  • (Date)

    Resulting Date object



92
93
94
# File 'lib/conductor/string.rb', line 92

def to_date
  Chronic.parse(dup.force_encoding("utf-8"))
end

#to_day(time = :end) ⇒ Object

Round a date string to a day

Parameters:

  • time (Symbol) (defaults to: :end)

    :start or :end



110
111
112
113
# File 'lib/conductor/string.rb', line 110

def to_day(time = :end)
  t = time == :end ? "23:59" : "00:00"
  Chronic.parse("#{strip_time} #{t}")
end

#to_patternString

Convert a string containing $1, $2 to a Regexp replace pattern

Returns:

  • (String)

    Pattern representation of the object.



199
200
201
# File 'lib/conductor/string.rb', line 199

def to_pattern
  gsub(/\$(\d+)/, '\\\\\1').gsub(/(^["']|["']$)/, "")
end

#to_rxRegexp

Convert a string to a regular expression

If the string matches /xxx/, it will be interpreted directly as a regex. Otherwise it will be escaped and converted to regex.

Returns:

  • (Regexp)

    Regexp representation of the string.



183
184
185
186
187
188
189
190
191
192
# File 'lib/conductor/string.rb', line 183

def to_rx
  if self =~ %r{^/(.*?)/([im]+)?$}
    m = Regexp.last_match
    regex = m[1]
    flags = m[2]
    Regexp.new(regex, flags)
  else
    Regexp.new(Regexp.escape(self))
  end
end

#utf8String

Discard invalid characters and output a UTF-8 String

Returns:

  • (String)

    UTF-8 encoded string



208
209
210
# File 'lib/conductor/string.rb', line 208

def utf8
  encode('utf-16', invalid: :replace).encode('utf-8')
end

#utf8!String

Destructive version of #utf8

Returns:

  • (String)

    UTF-8 encoded string, in place



217
218
219
# File 'lib/conductor/string.rb', line 217

def utf8!
  replace scrub
end

#wrap_styleString

Wrap content in <style> tag if needed

Returns:

  • (String)

    wrapped content



200
201
202
203
204
205
206
# File 'lib/conductor/filter.rb', line 200

def wrap_style
  if match(%r{<style>.*?</style>}m)
    self
  else
    "<style>#{self}</style>"
  end
end

#yaml?Boolean

Test if string starts with YAML

Returns:

  • (Boolean)

    test result



138
139
140
# File 'lib/conductor/string.rb', line 138

def yaml?
  dup.force_encoding('utf-8').match?(/^---/m)
end