Class: Docdown::Parser
- Inherits:
-
Object
- Object
- Docdown::Parser
- Defined in:
- lib/docdown/parser.rb
Defined Under Namespace
Classes: ParseError
Constant Summary collapse
- DEFAULT_KEYWORD =
":::"- INDENT_BLOCK =
'(?<before_indent>(^\s*$\n|\A)(^(?:[ ]{4}|\t))(?<indent_contents>.*)(?<after_indent>[^\s].*$\n?(?:(?:^\s*$\n?)*^(?:[ ]{4}|\t).*[^\s].*$\n?)*))'- GITHUB_BLOCK =
'^(?<fence>(?<fence_char>~|`){3,})\s*?(?<lang>\w+)?\s*?\n(?<contents>.*?)^\g<fence>\g<fence_char>*\s*?\n'- CODEBLOCK_REGEX =
/(#{GITHUB_BLOCK})/m
- COMMAND_REGEX =
->(keyword) { /^#{keyword}(?<tag>(\s|=|-)?)\s*(?<command>(\S)+)\s+(?<statement>.*)$/ }
Instance Attribute Summary collapse
-
#contents ⇒ Object
readonly
Returns the value of attribute contents.
-
#keyword ⇒ Object
readonly
Returns the value of attribute keyword.
-
#stack ⇒ Object
readonly
Returns the value of attribute stack.
Instance Method Summary collapse
- #add_code_commands(code) ⇒ Object
- #add_fenced_code(fenced_code_str) ⇒ Object
- #add_match_to_code_commands(match, commands) ⇒ Object
- #check_parse_error(command, code_block) ⇒ Object
- #command_regex ⇒ Object
- #contents_to_array ⇒ Object
-
#initialize(contents, options = {}) ⇒ Parser
constructor
A new instance of Parser.
-
#partition ⇒ Object
split into [before_code, code, after_code], process code, and re-run until tail is empty.
- #to_md ⇒ Object
Constructor Details
#initialize(contents, options = {}) ⇒ Parser
Returns a new instance of Parser.
37 38 39 40 41 42 43 |
# File 'lib/docdown/parser.rb', line 37 def initialize(contents, = {}) @contents = contents @original = contents.dup @keyword = [:keyword] || DEFAULT_KEYWORD @stack = [] partition end |
Instance Attribute Details
#contents ⇒ Object (readonly)
Returns the value of attribute contents.
35 36 37 |
# File 'lib/docdown/parser.rb', line 35 def contents @contents end |
#keyword ⇒ Object (readonly)
Returns the value of attribute keyword.
35 36 37 |
# File 'lib/docdown/parser.rb', line 35 def keyword @keyword end |
#stack ⇒ Object (readonly)
Returns the value of attribute stack.
35 36 37 |
# File 'lib/docdown/parser.rb', line 35 def stack @stack end |
Instance Method Details
#add_code_commands(code) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/docdown/parser.rb', line 111 def add_code_commands(code) commands = [] code.lines.each do |line| if match = line.match(command_regex) add_match_to_code_commands(match, commands) check_parse_error(line, code) else unless commands.empty? commands.last << line next end @stack << line end end end |
#add_fenced_code(fenced_code_str) ⇒ Object
66 67 68 69 70 71 72 73 74 75 |
# File 'lib/docdown/parser.rb', line 66 def add_fenced_code(fenced_code_str) fenced_code_str.match(CODEBLOCK_REGEX) do |m| fence = m[:fence] lang = m[:lang] code = m[:contents] @stack << "#{fence}#{lang}\n" add_code_commands(code) @stack << "#{fence}\n" end end |
#add_match_to_code_commands(match, commands) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/docdown/parser.rb', line 77 def add_match_to_code_commands(match, commands) command = match[:command] tag = match[:tag] statement = match[:statement] code_command = Docdown.code_command_from_keyword(command, statement) case tag when /\-/ code_command.hidden = true when /\=/ code_command.render_result = true when /\s/ # default do nothing end @stack << "\n" if commands.last.is_a?(Docdown::CodeCommand) @stack << code_command commands << code_command code_command end |
#check_parse_error(command, code_block) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/docdown/parser.rb', line 99 def check_parse_error(command, code_block) return unless code_command = @stack.last return unless code_command.is_a?(Docdown::CodeCommands::NoSuchCommand) @original.lines.each_with_index do |line, index| next unless line == command raise ParseError.new(keyword: code_command.keyword, block: code_block, command: command, line_number: index.next) end end |
#command_regex ⇒ Object
131 132 133 |
# File 'lib/docdown/parser.rb', line 131 def command_regex COMMAND_REGEX.call(keyword) end |
#contents_to_array ⇒ Object
127 128 129 |
# File 'lib/docdown/parser.rb', line 127 def contents_to_array partition end |
#partition ⇒ Object
split into [before_code, code, after_code], process code, and re-run until tail is empty
57 58 59 60 61 62 63 64 |
# File 'lib/docdown/parser.rb', line 57 def partition until contents.empty? head, code, tail = contents.partition(CODEBLOCK_REGEX) @stack << head unless head.empty? add_fenced_code(code) unless code.empty? @contents = tail end end |
#to_md ⇒ Object
46 47 48 49 50 51 52 53 54 |
# File 'lib/docdown/parser.rb', line 46 def to_md @stack.map do |s| if s.respond_to?(:render) s.render else s end end.join("") end |