class SublimeDSL::TextMate::Grammar::DSLWriter

Creates the DSL for a grammar.

Attributes

grammar[R]
io[R]

Public Class Methods

new(grammar) click to toggle source
# File lib/sublime_dsl/textmate/grammar/dsl_writer.rb, line 15
def initialize(grammar)
  @grammar = grammar
  @io = StringIO.new('', 'wb:utf-8')
  output_grammar
end

Public Instance Methods

dsl() click to toggle source
# File lib/sublime_dsl/textmate/grammar/dsl_writer.rb, line 21
def dsl
  io.string
end

Private Instance Methods

output_array(list, indent) click to toggle source
# File lib/sublime_dsl/textmate/grammar/dsl_writer.rb, line 92
def output_array(list, indent)
  list.each { |o| output_object o, indent }
end
output_begin_end_rule(rule, indent) click to toggle source
# File lib/sublime_dsl/textmate/grammar/dsl_writer.rb, line 125
def output_begin_end_rule(rule, indent)
  output_rule_start rule, indent
  i = indent + '  '
  io.puts i + 'content_scope ' + rule.content_scope.inspect if rule.content_scope
  output_match 'from', rule.from, i
  output_match 'to', rule.to, i
  unless rule.captures.empty?
    io.print i + 'both '
    output_captures rule.captures, i + '     '
  end
  output_boolean 'to_last', rule.to_last, i
  output_array rule.patterns, i
  io.puts indent + 'end'
end
output_boolean(name, value, indent) click to toggle source
# File lib/sublime_dsl/textmate/grammar/dsl_writer.rb, line 166
def output_boolean(name, value, indent)
  io.puts indent + name + ' ' + (value.to_i == 0 ? 'false' : 'true') if value
end
output_captures(captures, indent) click to toggle source
# File lib/sublime_dsl/textmate/grammar/dsl_writer.rb, line 158
def output_captures(captures, indent)
  lines = []
  captures.each_pair do |number, scope|
    lines << number.to_s + " => '" + scope + "'"
  end
  io.puts lines.join(",\n" + indent)
end
output_comment(text, indent) click to toggle source
# File lib/sublime_dsl/textmate/grammar/dsl_writer.rb, line 170
def output_comment(text, indent)
  text and text.each_line { |l| io.puts indent + ('# ' + l).rstrip }
end
output_fragment(f, indent) click to toggle source
# File lib/sublime_dsl/textmate/grammar/dsl_writer.rb, line 96
def output_fragment(f, indent)
  io.puts
  io.puts indent + '# FIXME: this fragment is never referenced' unless f.used
  io.puts "#{indent}fragment #{f.name.to_sym.inspect} do"
  i = indent + '  '
  output_comment f.comment, i
  output_array f.patterns, i
  io.puts indent + 'end'
end
output_grammar() click to toggle source
# File lib/sublime_dsl/textmate/grammar/dsl_writer.rb, line 27
def output_grammar

  args = "#{grammar.name.to_source} => #{grammar.scope.to_source}"
  args << grammar.dsl_file_arg

  # grammar start
  io.puts "language #{args} do"
  indent = '  '

  # comment
  output_comment grammar.comment, indent

  # file types
  if grammar.file_types && !grammar.file_types.empty?
    if grammar.file_types.any? { |t| t =~ /\s/ }
      array = grammar.file_types.map { |t| "'" << t << "'" }.join(', ')
      io.puts indent + "file_types [#{array}]"
    else
      list = grammar.file_types.join(' ')
      if list.length <= 80
        io.puts indent + "file_types %w(#{list})"
      else
        io.puts indent + "file_types %w("
        io.puts list.wrap.indent(indent.length + 2)
        io.puts indent + ")"
      end
    end
  else
    io.puts indent + '# FIXME: no file types'
  end

  # regexps
  %w(firstLineMatch foldingStartMarker foldingStopMarker).each do |att|
    met = att.snake_case
    re = grammar.send(met)
    next unless re
    io.print re.fixme_comments(indent)
    io.puts indent + met + ' ' + re.inspect(true)
  end

  # TextMate stuff
  %w(keyEquivalent uuid bundleUUID).each do |att|
    met = att.snake_case
    str = grammar.send(met)
    next unless str
    io.puts indent + met + ' ' + str.inspect + '  # TextMate only'
  end

  # patterns
  io.puts
  output_array grammar.patterns, indent

  # repository
  grammar.fragments.each { |f| output_fragment f, indent }

  # grammar end
  io.puts 'end'

end
output_include(inc, indent) click to toggle source
# File lib/sublime_dsl/textmate/grammar/dsl_writer.rb, line 106
def output_include(inc, indent)
  output_comment inc.comment, indent
  io.puts indent + 'include ' + inc.fragment_name.inspect
end
output_match(name, match, indent) click to toggle source
# File lib/sublime_dsl/textmate/grammar/dsl_writer.rb, line 147
def output_match(name, match, indent)
  io.print match.regexp.fixme_comments(indent)
  io.print indent + name + ' ' + match.regexp.inspect(true)
  if match.captures.empty?
    io.puts
  else
    io.print ",\n" << indent + '  '
    output_captures match.captures, indent + '  '
  end
end
output_match_rule(rule, indent) click to toggle source
# File lib/sublime_dsl/textmate/grammar/dsl_writer.rb, line 119
def output_match_rule(rule, indent)
  output_rule_start rule, indent
  output_match 'match', rule.match, indent + '  '
  io.puts indent + 'end'
end
output_no_match_rule(rule, indent) click to toggle source
# File lib/sublime_dsl/textmate/grammar/dsl_writer.rb, line 111
def output_no_match_rule(rule, indent)
  io.puts indent + '# FIXME: no "match" nor "begin/end"' unless !rule.patterns.empty? &&
    (rule.scope && rule.scope.start_with?('meta.') || !rule.disabled.nil?)
  output_rule_start rule, indent
  output_array rule.patterns, indent + '  '
  io.puts indent + 'end'
end
output_object(object, indent) click to toggle source
# File lib/sublime_dsl/textmate/grammar/dsl_writer.rb, line 87
def output_object(object, indent)
  k = object.class.name.split('::').last.snake_case
  send "output_#{k}", object, indent
end
output_rule_start(rule, indent) click to toggle source
# File lib/sublime_dsl/textmate/grammar/dsl_writer.rb, line 140
def output_rule_start(rule, indent)
  io.puts indent + (rule.scope ? "rule '#{rule.scope}' do" : 'rule do')
  indent += '  '
  output_comment rule.comment, indent
  output_boolean 'disabled', rule.disabled, indent
end