Class: String
- Inherits:
-
Object
- Object
- String
- Defined in:
- lib/conductor/filter.rb,
lib/conductor/string.rb
Overview
String helpers
Direct Known Subclasses
Instance Method Summary collapse
- #add_comment(key, value) ⇒ Object
- #add_mmd(key, value) ⇒ Object
- #add_yaml(key, value) ⇒ Object
-
#append(string) ⇒ Object
Append string to self.
-
#append!(string) ⇒ Object
Destructive version of #append.
- #autolink ⇒ Object
-
#bool? ⇒ Boolean
Test if a string is a boolean.
-
#bool_to_symbol ⇒ Symbol
Convert a string boolean to symbol.
-
#clean_encode ⇒ String
Get a clean UTF-8 string by forcing an ISO encoding and then re-encoding.
-
#clean_encode! ⇒ String
Destructive version of #clean_encode.
- #comment?(key) ⇒ Boolean
-
#count_h1s ⇒ Integer
Count the number of h1 headers in the document.
-
#date? ⇒ Boolean
Test a string to see if it's a UTC date.
-
#decrease_headers(amt = 1) ⇒ Object
Decrease all headers by given amount.
- #delete_meta(key) ⇒ Object
- #delete_mmd(key) ⇒ Object
- #delete_yaml(key) ⇒ Object
-
#ensure_h1 ⇒ String
Ensure there's at least one H1 in the document.
-
#ensure_h1! ⇒ Object
Destructive version of #ensure_h1.
- #ensure_mmd_meta_newline ⇒ Object
-
#find_file_in(paths, filename, ext) ⇒ Object
Search config folder for multiple subfolders and content.
-
#first_h1 ⇒ Integer
Locate the first H1 in the document.
-
#first_h2 ⇒ Integer
Locate the first H2 in the document.
-
#fix_headers ⇒ Object
Bump all headers except for first H1.
-
#fix_headers! ⇒ String
Destructive version of #fix_headers.
-
#fix_hierarchy ⇒ Object
Adjust header levels so there's no jump greater than 1.
-
#increase_headers(amt = 1) ⇒ String
Increase all header levels by amount.
-
#increase_headers!(amt = 1) ⇒ String
Destructive version of #increase_headers.
-
#inject_after_meta(content) ⇒ String
Insert the given content after any existing metadata.
-
#insert_css(path) ⇒ String
Insert raw CSS into the document, reading from a file and compressing contents.
-
#insert_file(path, type = :file, position = :end) ⇒ Object
Insert a file include syntax for various types.
-
#insert_javascript(path) ⇒ Object
Append a
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( + 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(, "#{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
314 315 316
# File 'lib/conductor/filter.rb', line 314 def append(string) "#{self}\n#{string}" end
#append!(string) ⇒ Object
Destructive version of #append
324 325 326
# File 'lib/conductor/filter.rb', line 324 def append!(string) replace append(string) end
#autolink ⇒ Object
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
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_symbol ⇒ Symbol
Convert a string boolean to symbol
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_encode ⇒ String
Get a clean UTF-8 string by forcing an ISO encoding and then re-encoding
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
235 236 237
# File 'lib/conductor/string.rb', line 235 def clean_encode! replace clean_encode end
#comment?(key) ⇒ Boolean
480 481 482
# File 'lib/conductor/filter.rb', line 480 def comment?(key) match(/^<!--.*?#{key}: \S.*?-->/m) end
#count_h1s ⇒ Integer
Count the number of h1 headers in the document
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
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
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 (key) case 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_h1 ⇒ String
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
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
595 596 597
# File 'lib/conductor/filter.rb', line 595 def ensure_h1! replace ensure_h1 end
#ensure_mmd_meta_newline ⇒ Object
444 445 446
# File 'lib/conductor/filter.rb', line 444 def utf8.split(/\n/).insert(, "\n\n").join("\n") end
#find_file_in(paths, filename, ext) ⇒ Object
Search config folder for multiple subfolders and content
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.("~/.config/conductor/"), path, "#{filename}.#{ext}") return exp if File.exist?(exp) end "#{filename}.#{ext}" end
#first_h1 ⇒ Integer
Locate the first H1 in the document
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_h2 ⇒ Integer
Locate the first H2 in the document
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 = utf8.split(/\n/).each_with_index do |line, idx| next if idx <= if line =~ /^(## *[^#]|-{2,} *$)/ first = idx break end end first end
#fix_headers ⇒ Object
Bump all headers except for first H1
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
632 633 634
# File 'lib/conductor/filter.rb', line 632 def fix_headers! replace fix_headers end
#fix_hierarchy ⇒ Object
Adjust header levels so there's no jump greater than 1
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
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
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
257 258 259 260 261 262 263
# File 'lib/conductor/filter.rb', line 257 def (content) lines = utf8.split(/\n/) 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
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.(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) (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
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.(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 (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
Append raw javascript
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.
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.(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 tag for the given path