Module: Docks::Processors
Constant Summary collapse
- CODE_BLOCK_INDICATOR =
"```"
- LIST_ITEM_INDICATOR =
/^(?:\*|\-|\d+\.)/
- HEADING_INDICATOR =
/^#+/
- HEADING_UNDERLINE_INDICATOR =
/^[=\-]+/
Instance Method Summary collapse
-
#code_block_with_language_and_description(content) ⇒ Object
Public: Processes the passed content by splitting it on commas, spaces, and pipes (and removing associated whitespace).
-
#ensure_valid_demo_type(content) ⇒ Object
Public: Processes the passed content by returning it if it’s a valid demo type, and otherwise returning the default demo type.
-
#join_with_smart_line_breaks(content, join = "\n\n") ⇒ Object
Public: Processes the passed content by joining it with line breaks as required.
-
#multiline_description(content) ⇒ Object
Public: Processes the passed content by yielding to the passed block in order to create a base hash, then adding any subsequent lines to the description (which can start on the first line — just set the description part as the returned hash’s :description key. The description is then joined with smart line breaks.
-
#name_and_parenthetical(content, name_key = :name, default_for_parenthetical = nil) ⇒ Object
Public: parses a string with names and optional parentheticals into an array of hashes with the name as the ‘name_key` and the parsed parenthetical options using the optional `default_for_parenthetical`.
-
#parenthetical_options(content, default = nil) ⇒ Object
Public:.
-
#split_on_characters(content, split_on = "\,\s") ⇒ Object
Public: Processes the passed content splitting it on type-delimitting symbols (/ to declare the type, ,/|/s to separate them).
-
#split_on_commas_spaces_and_pipes(content) ⇒ Object
Public: Processes the passed content by splitting it on commas, spaces, and pipes (and removing associated whitespace).
- #split_on_top_level_parens_commas_and_pipes(content) ⇒ Object
-
#split_types(content) ⇒ Object
Public: Processes the passed content by splitting it on type-delimitting symbols (/ to declare the type, ,/|/s to separate them).
-
#stringy_boolean(content) ⇒ Object
Public: Processes the passed String by converting it to a boolean where any string other than one matching /false/ will be considered true.
Instance Method Details
#code_block_with_language_and_description(content) ⇒ Object
Public: Processes the passed content by splitting it on commas, spaces, and pipes (and removing associated whitespace).
content - An Array or String representing the parsed result.
Examples
CodeBlockWithLanguage.process([ "html - The markup.",
"<div class="foo">Bar</div>",
"<div class="bar">Baz</div>" ])
# => {language: "html", description: "The markup", code: "<div class=\"foo\">Bar</div>\n<div class=\"foo\">Bar</div>"}
CodeBlockWithLanguage.process([ "<div class="foo">Bar</div>",
"<div class="bar">Baz</div>" ])
# => {code: "<div class=\"foo\">Bar</div>\n<div class=\"foo\">Bar</div>"}
Returns a Hash containing the language, description, and code block.
401 402 403 404 405 406 407 408 409 410 411 412 413 414 |
# File 'lib/docks/processors.rb', line 401 def code_block_with_language_and_description(content) result = {} content = Array(content) possible_line_details = content.first.strip.split(/\s*\-\s*/, 2) if Docks::Languages.extensions.include?(possible_line_details.first) result[:language] = possible_line_details.first result[:description] = possible_line_details.last if possible_line_details.length > 1 content.shift end result[:code] = content.join("\n") result end |
#ensure_valid_demo_type(content) ⇒ Object
Public: Processes the passed content by returning it if it’s a valid demo type, and otherwise returning the default demo type.
content - A string representing the desired demo type.
Examples
ensure_valid_demo_type(Docks::Types::Demo::SELECT)
# => "select"
ensure_valid_demo_type("foo")
# => "none"
Returns the processed string.
378 379 380 381 |
# File 'lib/docks/processors.rb', line 378 def ensure_valid_demo_type(content) @demo_types ||= Docks::Types::Demo.constants.map { |const| Docks::Types::Demo.const_get(const) } @demo_types.include?(content) ? content : Docks::Types::Demo::DEFAULT end |
#join_with_smart_line_breaks(content, join = "\n\n") ⇒ Object
Public: Processes the passed content by joining it with line breaks as required. to create markdown-parsable paragraphs and code blocks.
content - An Array representing the parsed result. join - The string with which to join two different paragraphs together.
Examples
join_with_smart_line_breaks(["One paragraph that", "spans two lines.", "And another!"])
# => "One paragraph that spans two lines.\n\nAnd another!"
join_with_smart_line_breaks(["One paragraph", "```html", "<p>A code block</p>", "```", "another paragraph."])
# => "One paragraph.\n\n```html\n<p>A code block</p>\n```\n\nanother paragraph"
Returns the processed string.
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/docks/processors.rb', line 162 def join_with_smart_line_breaks(content, join = "\n\n") return content unless content.kind_of?(Array) text = "" in_code_block = false in_list = false at_start_of_paragraph = true content.each_with_index do |line, index| stripped_line = line.strip if stripped_line.start_with?(CODE_BLOCK_INDICATOR) # Either the start or end of a code block if in_code_block in_code_block = false at_start_of_paragraph = true text << "\n#{line}#{join}" else in_code_block = true text << "#{join}#{line}" end elsif in_code_block || (in_list && stripped_line =~ LIST_ITEM_INDICATOR) # Either: # 1. In a code block — just keep appending lines, or # 2. Last item was a list item and this item is directly below it, # so just add that line below. text << "\n#{line}" elsif stripped_line.length == 0 # Empty line — new paragraph at_start_of_paragraph = true text << join elsif stripped_line =~ LIST_ITEM_INDICATOR && at_start_of_paragraph # Line that looks like a list item and we're ready for a new paragraph in_list = true at_start_of_paragraph = false text << line elsif stripped_line =~ HEADING_INDICATOR # Starts and ends a "## Header"-style heading at_start_of_paragraph = true text << "\n#{line}\n" elsif stripped_line =~ HEADING_UNDERLINE_INDICATOR # Ends a "Header\n======"-style heading at_start_of_paragraph = true text << "#{line}#{join}" elsif content[index + 1] && content[index + 1].strip =~ HEADING_UNDERLINE_INDICATOR # Start of a "Header\n======"-style heading text << "\n#{line}\n" elsif at_start_of_paragraph # New line at the start of a regular paragraph at_start_of_paragraph = false in_list = false text << line else # Line that isn't at the start of a paragraph — pin it to the previous line. text << " #{stripped_line}" end end text.strip! text.gsub!(/\n{3,}/, "\n\n") text.length > 0 ? text : nil end |
#multiline_description(content) ⇒ Object
Public: Processes the passed content by yielding to the passed block in order to create a base hash, then adding any subsequent lines to the description (which can start on the first line — just set the description part as the returned hash’s :description key. The description is then joined with smart line breaks.
Yields the first line (item) of content.
content - An Array of Strings representing the multiline description.
Examples
multiline_description(['bar', 'baz']) { |first_line| { foo: first_line } }
# => { foo: 'bar', description: 'baz' }
multiline_description(['bar', 'Baz']) { |first_line| { foo: first_line, description: 'Already started!' } }
# => { foo: 'bar', description: "Already started!\n\nBaz" }
Returns the processed Hash.
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
# File 'lib/docks/processors.rb', line 336 def multiline_description(content) content = Array(content) description = [] item = nil content.each do |line| if item.nil? item = yield(line) if block_given? if !item.kind_of?(Hash) item = Hash.new description << line elsif !item[:description].nil? description << item.delete(:description) end else description << line end end unless item.nil? item[:description] = join_with_smart_line_breaks(description) item end end |
#name_and_parenthetical(content, name_key = :name, default_for_parenthetical = nil) ⇒ Object
Public: parses a string with names and optional parentheticals into an array of hashes with the name as the ‘name_key` and the parsed parenthetical options using the optional `default_for_parenthetical`.
content - The string with the name and optional parenthetical. name_key - An optional Symbol representing the key that should be
used for the non-parenthetical portion. Defaults to :name.
default_key - An optional Symbol to be used as the default key for an
unpaired item in the parentheses.
Examples
name_and_parenthetical(':matches?', :setter)
# => [{setter: ':matches?'}]
name_and_parenthetical(':size (SIZE::LARGE)', :setter, :constant)
# => [{setter: ':size', constant: 'SIZE::LARGE'}]
name_and_parenthetical([':size (SIZE::LARGE)', ':checked?'], :setter, :constant)
# => [{setter: ':size', constant: 'SIZE::LARGE'}, {setter: ':checked?'}]
Returns the parsed hash.
260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/docks/processors.rb', line 260 def name_and_parenthetical(content, name_key=:name, default_for_parenthetical=nil) result = {} match = content.match(/\s*(?<name>[^\(]*)(?:\s*\((?<paren>[^\)]*)\))?/) result[name_key] = match[:name].strip if (parenthetical = match[:paren]).nil? result else result.merge((parenthetical, default_for_parenthetical)) end end |
#parenthetical_options(content, default = nil) ⇒ Object
Public:
content - A String of the parenthetical. default - An optional Symbol representing the key that should be used if
an un-paired value is provided.
Examples
('Activate with : foo , active : false')
# => {activate_with: 'foo', active: 'false'}
('select, active : false, javascript action: $(this).text(1 + 1)', :demo_type)
# => {demo_type: 'select', active: 'false', javascript_action: '$(this).text(1 + 1)'}
Returns the processed Hash.
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 |
# File 'lib/docks/processors.rb', line 288 def (content, default=nil) return content unless content.kind_of?(String) result, default_only = {}, true default = default.to_sym unless default.nil? # Strip leading and trailing parentheses content = content.strip.sub(/^\(/, '').sub(/\)$/, '') # Get a leading, un-keyed value. This will be set to the default # key (`default`), if it was passed content.sub!(/\s*([^,]*),?\s*/) do |match| if match.index(': ').nil? result[default] = $1.strip unless default.nil? '' else match end end # Cycle over key value pairs and add to the return Hash content.scan(/\s*(?<attribute>[^:]*):\s+(?<value>[^,]*),?\s*/).each do |match| default_only = false # Ensure that the key looks like a regular symbol result[match[0].strip.downcase.gsub(/\s+/, '_').to_sym] = match[1].strip end result end |
#split_on_characters(content, split_on = "\,\s") ⇒ Object
Public: Processes the passed content splitting it on type-delimitting symbols (/ to declare the type, ,/|/s to separate them).
content - The String to break apart. split_on - The characters, passed as a single String or an Array of Strings,
on which the content string should be split. Defaults to "\,\s".
Examples
split_on_characters("String, Array", "\s\,")
# => ["String", "Array"]
Returns an Array with the split pieces.
110 111 112 113 114 115 116 117 |
# File 'lib/docks/processors.rb', line 110 def split_on_characters(content, split_on="\,\s") return content unless content.kind_of?(String) split_on = split_on.join("") if split_on.kind_of?(Array) return content unless split_on.kind_of?(String) content.split(/[#{split_on}]/).select { |piece| piece.length > 0 } end |
#split_on_commas_spaces_and_pipes(content) ⇒ Object
Public: Processes the passed content by splitting it on commas, spaces, and pipes (and removing associated whitespace).
content - An Array or String representing the parsed result.
Examples
split_on_commas_spaces_and_pipes("String, Array | Object")
# => ["String", "Array", "Object"]
Returns an Array of the split results.
17 18 19 |
# File 'lib/docks/processors.rb', line 17 def split_on_commas_spaces_and_pipes(content) split_on_characters(content, [",", "|", "\s"]) end |
#split_on_top_level_parens_commas_and_pipes(content) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/docks/processors.rb', line 21 def split_on_top_level_parens_commas_and_pipes(content) return content unless content.kind_of?(String) indexes = [] depth = 0 split_on = /[\|,]/ content.chars.each_with_index do |char, index| if char == "(" depth += 1 elsif char == ")" new_depth = [0, depth - 1].max if new_depth == 0 && depth != 0 indexes << index end depth = new_depth elsif split_on =~ char && depth == 0 indexes << index end end result = [] start_index = 0 start_strip = /^\s*[,\|]*\s*/ end_strip = /\s*[,\|]*\s*$/ indexes.each do |index| if index > start_index item = content[start_index..index].gsub(start_strip, "").gsub(end_strip, "") result << item if item.length > 0 end start_index = index + 1 end if start_index < content.length result << content[start_index..-1].gsub(start_strip, "").gsub(end_strip, "") end result end |
#split_types(content) ⇒ Object
Public: Processes the passed content by splitting it on type-delimitting symbols (/ to declare the type, ,/|/s to separate them).
content - An Array or String representing the parsed result.
Examples
split_types("{String, Number |Object[]}")
# => [
OpenStruct.new(name: "String", array: false),
OpenStruct.new(name: "Number", array: false),
OpenStruct.new(name: "Object", array: true)
]
Returns an Array of types.
82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/docks/processors.rb', line 82 def split_types(content) split_on_commas_spaces_and_pipes(content.gsub(/[\{\}]/, "").strip).map do |type| array, type = if /\[\]/ =~ type [true, type.split("[").first] else [false, type] end type = "Anything" if type == "*" OpenStruct.new(name: type, array: array) end end |
#stringy_boolean(content) ⇒ Object
Public: Processes the passed String by converting it to a boolean where any string other than one matching /false/ will be considered true.
content - A String representing the parsed result.
Examples
stringy_boolean(" false ")
# => false
stringy_boolean("foo")
# => true
Returns a boolean version of the content.
135 136 137 138 139 |
# File 'lib/docks/processors.rb', line 135 def stringy_boolean(content) return false if content.nil? return content unless content.kind_of?(String) !content.include?("false") end |