class Docdown::Parser

Constants

CODEBLOCK_REGEX
COMMAND_REGEX
DEFAULT_KEYWORD
GITHUB_BLOCK
INDENT_BLOCK

Attributes

contents[R]
keyword[R]
stack[R]

Public Class Methods

new(contents, options = {}) click to toggle source
# File lib/docdown/parser.rb, line 37
def initialize(contents, options = {})
  @contents = contents
  @original = contents.dup
  @keyword  = options[:keyword] || DEFAULT_KEYWORD
  @stack    = []
  partition
end

Public Instance Methods

add_code_commands(code) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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() click to toggle source
# File lib/docdown/parser.rb, line 131
def command_regex
  COMMAND_REGEX.call(keyword)
end
contents_to_array() click to toggle source
# File lib/docdown/parser.rb, line 127
def contents_to_array
  partition
end
partition() click to toggle source

split into [before_code, code, after_code], process code, and re-run until tail is empty

# 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() click to toggle source
# 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