class DSS

Public Class Methods

new() click to toggle source
# File lib/dss.rb, line 2
def initialize
  def default_parser(output)
    output[:line][:contents]
  end

  def state_parser(output)
    state = output[:line][:contents].split(' - ');
    [{
      name: (state[0]) ? trim_whitespace(state[0]) : '',
      escaped: (state[0]) ? trim_whitespace(state[0].gsub('.', ' ').gsub(':', ' pseudo-class-')) : '',
      description: (state[1]) ? trim_whitespace(state[1]) : ''
    }];
  end

  def markup_parser(output)
    [{
      example: output[:line][:contents],
      escaped: output[:line][:contents].gsub(/</, '&lt;').gsub(/>/, '&gt;')
    }]
  end

  @parsers = {
    name: method(:default_parser),
    description: method(:default_parser),
    state: method(:state_parser),
    markup: method(:markup_parser)
  }
end

Public Instance Methods

alias(newName, oldName) click to toggle source
# File lib/dss.rb, line 50
def alias(newName, oldName)
  @parsers[newName.to_sym] = @parsers[oldName.to_sym]
end
default_parser(output) click to toggle source
# File lib/dss.rb, line 3
def default_parser(output)
  output[:line][:contents]
end
detect(line) click to toggle source
# File lib/dss.rb, line 31
def detect(line)
  if !line.is_a?(String)
    false
  end
  reference = line.split("\n\n").pop
  !!(/.*@/).match(reference)
end
detector(callback) click to toggle source
# File lib/dss.rb, line 39
def detector(callback)
  # TODO: Figure out how to do this, or why it's even necessary
  # DSS.class_eval do
  #   %Q{def detect(args) #{callback}.call(args) end}
  # end
end
markup_parser(output) click to toggle source
# File lib/dss.rb, line 16
def markup_parser(output)
  [{
    example: output[:line][:contents],
    escaped: output[:line][:contents].gsub(/</, '&lt;').gsub(/>/, '&gt;')
  }]
end
parse(lines, options = {}) click to toggle source
# File lib/dss.rb, line 99
def parse(lines, options = {})
  current_block = ''
  inside_single_line_block = false
  inside_multi_line_block = false
  unparsed_blocks = []
  trimmed = ''
  parsed_blocks = []
  temp = {}
  line_num = 0
  from = 0
  to = 0

  lines.to_s.split(/\n/).each do |line|
    line_num += 1

    if single_line_comment(line) || start_multi_line_comment(line)
      from = line_num
    end

    if single_line_comment(line)
      trimmed = trim_single_line(line)
      if inside_single_line_block
        current_block += "\n#{trimmed}"
      else
        current_block = trimmed
        inside_single_line_block = true
      end
    end

    if start_multi_line_comment(line) || inside_multi_line_block
      trimmed = trim_multi_line(line)
      if inside_multi_line_block
        current_block += "\n#{trimmed}"
      else
        current_block += trimmed
        inside_multi_line_block = true
      end
    end

    if end_multi_line_comment(line)
      inside_multi_line_block = false
    end

    if !single_line_comment(line) && !inside_multi_line_block
      if current_block
        unparsed_blocks.push({ text: normalize(current_block), from: from, to: line_num })
      end
      inside_single_line_block = false
      current_block = ''
    end
  end

  unparsed_blocks.each do |_block|
    from = _block[:from]
    to = _block[:to]
    block = _block[:text].split(/\n/).select do |line|
      line.length > 0
    end
    block = block.join("\n")

    block.split(/\n/).each do |line|
      if detect(line)
        temp = parse_line(temp, normalize(line), block, lines, from, to, options)
      end
    end

    if temp.length > 0
      parsed_blocks.push(temp)
    end
    temp = {}
  end
  { blocks: parsed_blocks }
end
parse_line(_temp, line, block, file, from, to, options) click to toggle source
# File lib/dss.rb, line 54
def parse_line(_temp, line, block, file, from, to, options)
  temp = _temp
  parts = line.gsub(/.*@/, '')
  index = parts.index(' ') || parts.index(/\n/) || parts.index(/\r/) || parts.length
  name = trim_whitespace(parts[0..index]).to_sym
  output = {
    options: options,
    file: file,
    name: name,
    line: {
      contents: nil,
      from: block.index(line),
      to: block.index(line)
    },
    block: {
      contents: block,
      from: from,
      to: to
    }
  }

  next_parser_index = block.index('@', output[:line][:from] + 1)
  markup_length = !next_parser_index.nil? ? next_parser_index - output[:line][:from] : block.length
  parser_marker = "@#{name}"
  contents = block.split('').slice(output[:line][:from], markup_length).join('').gsub(parser_marker, '')
  output[:line][:contents] = trim_whitespace(normalize(contents))

  new_line = {}
  new_line[name] = !@parsers[name.to_sym].nil? ? @parsers[name.to_sym].call(output) : ''

  if (temp[name])
    if !temp[name].is_a?(Array)
      temp[name] = [temp[name]]
    end
    if !new_line[name].is_a?(Array)
      temp[name].push(new_line[name])
    else
      temp[name].push(new_line[name][0])
    end
  else
    temp = temp.merge(new_line)
  end
  temp
end
parser(name, callback) click to toggle source
# File lib/dss.rb, line 46
def parser(name, callback)
  @parsers[name.to_sym] = callback
end
state_parser(output) click to toggle source
# File lib/dss.rb, line 7
def state_parser(output)
  state = output[:line][:contents].split(' - ');
  [{
    name: (state[0]) ? trim_whitespace(state[0]) : '',
    escaped: (state[0]) ? trim_whitespace(state[0].gsub('.', ' ').gsub(':', ' pseudo-class-')) : '',
    description: (state[1]) ? trim_whitespace(state[1]) : ''
  }];
end

Private Instance Methods

end_multi_line_comment(line) click to toggle source
# File lib/dss.rb, line 200
def end_multi_line_comment(line)
  if single_line_comment(line)
    false
  end
  !!(/.*\*\//).match(line)
end
normalize(text_block) click to toggle source
# File lib/dss.rb, line 207
def normalize(text_block)
  indent_size = nil
  normalized = text_block.split(/\n/).map do |line|
    preceding_whitespace = (/\A\s*/).match(line)[0].length
    indent_size = preceding_whitespace unless indent_size
    if line === ''
      ''
    elsif (indent_size <= preceding_whitespace) && (indent_size > 0)
      line[indent_size..line.length]
    else
      line
    end
  end
  normalized.join("\n")
end
single_line_comment(line) click to toggle source
# File lib/dss.rb, line 184
def single_line_comment(line)
  !!(/\A\s*\/\//).match(line)
end
start_multi_line_comment(line) click to toggle source
# File lib/dss.rb, line 188
def start_multi_line_comment(line)
  !!(/\A\s*\/\*/).match(line)
end
trim_multi_line(line) click to toggle source
# File lib/dss.rb, line 196
def trim_multi_line(line)
  line.gsub(/\A.*(\/\*|\*\/|\*)+/, '')
end
trim_single_line(line) click to toggle source
# File lib/dss.rb, line 192
def trim_single_line(line)
  line.gsub(/\s*\/\//, '')
end
trim_whitespace(str) click to toggle source
# File lib/dss.rb, line 175
def trim_whitespace(str)
  patterns = [/\A\s\s*/, /\s\s*\z/]
  trimmed_str = str
  patterns.each do |regEx|
    trimmed_str = trimmed_str.gsub(regEx, '')
  end
  trimmed_str
end