Class: Korekto::Main
- Inherits:
-
Object
- Object
- Korekto::Main
- Defined in:
- lib/korekto/main.rb
Constant Summary collapse
- MD_STATEMENT_CODE_TITLE =
rubocop: disable Layout/LineLength
%r{^(?<statement>.*)\s#(?<code>[A-Z](\d+(\.\w+)?(/[\w,.]+)?)?)(\s+(?<title>[^#]+))?$}- MD_FILENAME =
%r{^< (?<filename>[/\w\-.]+)$}- MD_KLASS_METHOD_DEFINITION =
patch
/^(?<klass>::[A-Z]\w+)#(?<method>\w+)(?<definition>[^=]*=.+)$/- MD_RULE =
/^[?] (?<rule>\S.*)$/- MD_TYPE_PATTERN =
%r{^! (?<type>\S+)\s+/(?<pattern>.*)/$}- MD_TYPE_VARIABLES =
/^! (?<type>\S+)\s+\{(?<variables>\S+( \S+)*)\}$/- MD_KEY_VALUE =
/^! (?<key>\w+):\s+'(?<value>.*)'$/- M_FENCE =
rubocop: enable Layout/LineLength
/^```\s*$/- M_COMMENT_LINE =
/^\s*#/- BACKUPS =
{}
Instance Method Summary collapse
-
#active? ⇒ Boolean
Is the current line a non-comment Korekto line?.
-
#initialize(filename = '-', statements: Statements.new, imports: []) ⇒ Main
constructor
A new instance of Main.
- #key_value(key, value) ⇒ Object
- #parse(lines) ⇒ Object
- #patch(klass, method, definition) ⇒ Object
- #preprocess? ⇒ Boolean
- #run ⇒ Object
- #type_pattern(type, pattern) ⇒ Object
- #type_variables(type, variables) ⇒ Object
Constructor Details
#initialize(filename = '-', statements: Statements.new, imports: []) ⇒ Main
Returns a new instance of Main.
18 19 20 21 22 23 24 |
# File 'lib/korekto/main.rb', line 18 def initialize(filename='-', statements: Statements.new, imports: []) @filename,@statements,@imports = filename,statements,imports @imports.push @filename.freeze @line,@active = nil,false @section = File.basename(@filename,'.*') @m_fence_korekto = /^```korekto$/ # default fence end |
Instance Method Details
#active? ⇒ Boolean
Is the current line a non-comment Korekto line?
151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/korekto/main.rb', line 151 def active? case @line when @m_fence_korekto raise Error, 'unexpected fence' if @active @active = true false when M_FENCE @active = false else @active && !M_COMMENT_LINE.match?(@line) end end |
#key_value(key, value) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/korekto/main.rb', line 86 def key_value(key, value) case key when 'scanner' @statements.symbols.set_scanner value when 'fence' @m_fence_korekto = Regexp.new "^```#{value}$" # user defined fence when 'section' @section = value when 'save' BACKUPS[value] = Marshal.dump(@statements) when 'restore' if (backup = BACKUPS[value]) @statements = Marshal.load(backup) else raise Error, "nothing saved as '#{value}'" end else raise Error, "key '#{key}' not implemented" end end |
#parse(lines) ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/korekto/main.rb', line 107 def parse(lines) statement_number = line_number = 0 while (@line = lines.shift) begin line_number += 1 next unless active? next if preprocess? if (md = MD_STATEMENT_CODE_TITLE.match @line) code,title = @statements.add(md[:statement].strip, md[:code], md[:title], @section # Block executes if statement is new. # Method recieves the return value. ){ statement_number += 1 } if Korekto.scrape? print @statements.last print "\t##{code}" print " #{title}" unless title.nil? || title.empty? puts elsif Korekto.trace? || (@filename=='-' && !(md[:code]==code && md[:title]==title)) puts "#{@filename}:#{line_number}:#{code}:#{title}" end else raise Error, 'unrecognized korekto line' end rescue Error puts "#{@filename}:#{line_number}:!:#{$!.}" exit 65 rescue StandardError puts "#{@filename}:#{line_number}:?:#{$!.}" warn $!.backtrace exit 1 end end end |
#patch(klass, method, definition) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/korekto/main.rb', line 42 def patch(klass, method, definition) if Object.const_get(klass).method_defined?(method) raise Error, "overrides: #{klass}##{method}" end # rubocop: disable Security/Eval # rubocop: disable Style/DocumentDynamicEvalDefinition # rubocop: disable Style/EvalWithLocation eval <<~EVAL class #{klass} def #{method}#{definition} end EVAL # rubocop: enable Style/EvalWithLocation # rubocop: enable Style/DocumentDynamicEvalDefinition # rubocop: enable Security/Eval end |
#preprocess? ⇒ Boolean
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/korekto/main.rb', line 59 def preprocess? case @line when MD_FILENAME filename = $~[:filename].strip unless @imports.include? filename Main.new(filename, statements:@statements, imports:@imports).run end when MD_KLASS_METHOD_DEFINITION if @filename=='-' && !Korekto.patch? # We'll trust files, but not stdin. raise Error, 'monkey patching not allowed on stdin' end patch($~[:klass],$~[:method],$~[:definition]) when MD_RULE @statements.syntax.push $~[:rule].strip when MD_TYPE_PATTERN type_pattern($~[:type], $~[:pattern]) when MD_TYPE_VARIABLES type_variables($~[:type], $~[:variables].split) when MD_KEY_VALUE key_value($~[:key], $~[:value]) else return false end true end |
#run ⇒ Object
145 146 147 148 |
# File 'lib/korekto/main.rb', line 145 def run parse @filename=='-' ? $stdin.readlines(chomp: true) : File.readlines(@filename, chomp: true) end |
#type_pattern(type, pattern) ⇒ Object
26 27 28 29 30 |
# File 'lib/korekto/main.rb', line 26 def type_pattern(type, pattern) t2p = @statements.symbols.t2p raise Error, "type #{type} in use" if t2p.key? type t2p[type] = pattern end |
#type_variables(type, variables) ⇒ Object
32 33 34 35 36 37 38 39 40 |
# File 'lib/korekto/main.rb', line 32 def type_variables(type, variables) v2t,t2p = @statements.symbols.v2t,@statements.symbols.t2p pattern = t2p[type] raise Error, "type #{type} not defined" unless pattern variables.each do |variable| raise Error, "variable #{variable} in use" if v2t.key? variable v2t[variable] = type end end |