tex_log_parser 1.0.0.pre.9 → 1.0.0.pre.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0a31484789a537268e2bcd739ff74fac6b946068
4
- data.tar.gz: a0bce484490571886b62aa1434f3ea4c625dbd0f
3
+ metadata.gz: c466836b3e482413ab935462f0bc513bc7bd43a5
4
+ data.tar.gz: 8cf420477f87eb3e5cca65db7c5b5dedc1b1129b
5
5
  SHA512:
6
- metadata.gz: d6f9094ef608e78610997a5ed04ee3c01ee8e9d53bf942cf263c2b4e6378ee4193b3f8b39b77d69440591d6365d4a013e23c273bcdc2fb5a8abd0c10693081e9
7
- data.tar.gz: 623cd9d97a032617e669edaa71e171e70195fc71eb2480afd316387c01cfc9390dad80822dd680c8536b30ced3964760d3f7e6c7621fe8d83cd08c565eb46609
6
+ metadata.gz: 7e10d29ce1cfee50a9ee0c6ff16fa57bf76afe91f88b71b81966e7ee12bd469c4995147f76821b8fbba60f7b8ef07bd264fc32500a6dcba25b257a5d5c947ed3
7
+ data.tar.gz: 93884717b008a2b80f5b7d8aa4e8d9df4e7e4e563beed9e11333bd8bc28a8341b20fdd61b9d61b8c910537c8b5a0bc9cee1e7c207445e3e185348c6a51277ec1
data/lib/logger.rb CHANGED
@@ -8,10 +8,14 @@ class Logger
8
8
  class << self
9
9
  attr_accessor :debugging
10
10
 
11
+ def debug?
12
+ debugging || !ENV['DEBUG'].nil?
13
+ end
14
+
11
15
  # Logs the given message to STDOUT if `debug` is true.
12
16
  # @param [String] message
13
17
  def debug(message)
14
- puts message if debugging || !ENV['DEBUG'].nil?
18
+ puts message if debug?
15
19
  end
16
20
  end
17
21
  end
@@ -34,7 +34,7 @@ class LogMessage
34
34
 
35
35
  message = @message
36
36
  message = message.split("\n").map(&:strip).join(' ') unless @preformatted
37
- message += "\nLog pattern: '#{@pattern}'" if Logger.debugging
37
+ message += "\nLog pattern: '#{@pattern}'" if Logger.debug?
38
38
 
39
39
  <<~MSG
40
40
  #{@source_file}#{lines}: #{@level.to_s.upcase}
@@ -51,7 +51,7 @@ class LogMessage
51
51
  log_lines: @log_lines,
52
52
  preformatted: @preformatted
53
53
  }
54
- hash[:pattern] = @pattern if Logger.debugging
54
+ hash[:pattern] = @pattern if Logger.debug?
55
55
  JSON.pretty_generate hash
56
56
  end
57
57
  end
@@ -3,6 +3,7 @@
3
3
  # TODO: document
4
4
  module LogParser
5
5
  attr_reader :messages
6
+ attr_reader :scope_changes_by_line if Logger.debug?
6
7
 
7
8
  # TODO: document
8
9
  # @param [Array<String>,IO,StringIO] log
@@ -15,6 +16,7 @@ module LogParser
15
16
  @lines = LogBuffer.new(log)
16
17
 
17
18
  Logger.debug "Parsing from '#{log}'"
19
+ @scope_changes_by_line = {} if Logger.debug?
18
20
  end
19
21
 
20
22
  # @return [Array<LogPattern>]
@@ -62,7 +64,7 @@ module LogParser
62
64
  raise 'Parse already done!' if @lines.empty?
63
65
 
64
66
  line = @lines.first
65
- Logger.debug "\nLine: '#{line.strip}'"
67
+ Logger.debug "\nLine #{@log_line_number}: '#{line.strip}'"
66
68
  msg = nil
67
69
 
68
70
  # Use the first pattern that matches. Let's hope that's a good heuristic.
@@ -89,7 +91,9 @@ module LogParser
89
91
 
90
92
  def remove_consumed_lines(i)
91
93
  @lines.forward(i)
92
- @log_line_number += i
94
+ @log_line_number += i
95
+
96
+ @scope_changes_by_line[@log_line_number] = [] if Logger.debug? && i > 0
93
97
  end
94
98
 
95
99
  # @return [LogMessage,nil]
@@ -101,6 +105,7 @@ module LogParser
101
105
  message.log_lines = { from: @log_line_number,
102
106
  to: @log_line_number + consumed_lines - 1 }
103
107
  message.source_file ||= @files.last
108
+ message.source_lines ||= { from: nil, to: nil }
104
109
 
105
110
  Logger.debug message
106
111
  remove_consumed_lines consumed_lines
@@ -117,9 +122,13 @@ module LogParser
117
122
  scope_changes(@lines.first).each do |op|
118
123
  if op == :pop
119
124
  left = @files.pop
125
+
120
126
  Logger.debug "- Finished source file: '#{left.nil? ? 'nil' : left}'"
127
+ @scope_changes_by_line[@log_line_number].push "pop #{left}" if Logger.debug?
121
128
  else # op is file name
122
129
  Logger.debug "- Entered source file: '#{op}'"
130
+ @scope_changes_by_line[@log_line_number].push "push #{op}" if Logger.debug?
131
+
123
132
  @files.push(op)
124
133
  end
125
134
  end
@@ -22,6 +22,8 @@ class FileLineError
22
22
  msg.preformatted = true
23
23
  msg.level = :error
24
24
 
25
+ msg.message.gsub!(@start, '')
26
+
25
27
  [msg, consumed]
26
28
  end
27
29
  end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Matches messages of these forms:
4
+ #
5
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
6
+ # !
7
+ # ./plain.tex:5: fontspec error: "font-not-found"
8
+ # !
9
+ # ! The font "NoSuchFont" cannot be found.
10
+ # !
11
+ # ! See the fontspec documentation for further information.
12
+ # !
13
+ # ! For immediate help type H <return>.
14
+ # !...............................................
15
+ #
16
+ # l.5 \setmainfont{NoSuchFont}
17
+ #
18
+ # and
19
+ #
20
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
21
+ # !
22
+ # ! fontspec error: "font-not-found"
23
+ # !
24
+ # ! The font "NoSuchFont" cannot be found.
25
+ # !
26
+ # ! See the fontspec documentation for further information.
27
+ # !
28
+ # ! For immediate help type H <return>.
29
+ # !...............................................
30
+ #
31
+ # l.5 \setmainfont{NoSuchFont}
32
+ #
33
+ # and
34
+ #
35
+ # .................................................
36
+ # . LaTeX info: "xparse/define-command"
37
+ # .
38
+ # . Defining command \fontspec with sig. 'O{}mO{}' on line 472.
39
+ # .................................................
40
+ class HighlightedMessages
41
+ include RegExpPattern
42
+
43
+ def initialize
44
+ super(/^(\!{3,}|\.{3,})$/,
45
+ { pattern: lambda { |m|
46
+ if m[1][0] == '!'
47
+ /^l\.(\d+)/
48
+ else
49
+ /^\.{3,}\s*$/
50
+ end
51
+ },
52
+ until: :match,
53
+ inclusive: true })
54
+ end
55
+
56
+ def read(lines)
57
+ # @type [LogMessage] msg
58
+ msg, consumed = super(lines)
59
+
60
+ is_error = @start_match[1][0] == '!'
61
+
62
+ if is_error
63
+ file_line_match = %r{^(/?(?:.*?/)*[^/]+):(\d+):\s*}.match(msg.message)
64
+ line = nil
65
+ if !file_line_match.nil? # if file-line active
66
+ msg.source_file = file_line_match[1]
67
+ line = file_line_match[2].to_i
68
+ msg.message.gsub!(file_line_match[0], '')
69
+ elsif !@end_match[1].nil?
70
+ # No file-line format, so use line number from end match
71
+ line = @end_match[1].to_i
72
+ end
73
+ msg.source_lines = { from: line, to: line } unless line.nil?
74
+
75
+ msg.level = :error
76
+
77
+ msg.message.gsub!(/^.*?For immediate help type.*$/, '')
78
+ msg.message.gsub!(/^\!\.+\s*$/, '')
79
+ msg.message.gsub!(/^l\.\d+\s+.*$/, '')
80
+ else
81
+ # BROKEN_BY_LINEBREAKS
82
+ # TODO: may be split across lines --> remove whitespace before extracting
83
+ line_match = /on line\s+(\d+)\.$/.match(msg.message)
84
+ unless line_match.nil?
85
+ line = line_match[1].to_i
86
+ msg.source_lines = { from: line, to: line }
87
+ end
88
+
89
+ msg.level = :info
90
+
91
+ msg.message.gsub!(@end_match[0], '')
92
+ end
93
+
94
+ msg.preformatted = true
95
+ msg.message.gsub!(@start, '')
96
+ msg.message.gsub!(/^#{@start_match[1][0]}\s+/, '')
97
+ msg.message.strip!
98
+
99
+ [msg, consumed]
100
+ end
101
+ end
@@ -6,12 +6,20 @@
6
6
  # <inserted text>
7
7
  # \par
8
8
  # <*> plain.tex
9
- class ExclaimingError
9
+ #
10
+ # and
11
+ #
12
+ # ! Font TU/NoSuchFont(0)/m/n/9=NoSuchFont at 9.0pt not loadable: Metric (TFM) fi
13
+ # le or installed font not found.
14
+ # <to be read again>
15
+ # relax
16
+ # l.40 \end{document}
17
+ class StandardError
10
18
  include RegExpPattern
11
19
 
12
20
  def initialize
13
21
  super(/^\! \w+/,
14
- { pattern: ->(_) { /^\s*<\*>\s+([^\s]+)/ }, until: :match, inclusive: true }
22
+ { pattern: ->(_) { /^\s*<\*>\s+([^\s]+)|^l\.(\d+)\s+/ }, until: :match, inclusive: true }
15
23
  )
16
24
  end
17
25
 
@@ -24,7 +32,11 @@ class ExclaimingError
24
32
  msg.message.gsub!(@ending[:pattern][nil], '')
25
33
  msg.message.rstrip!
26
34
 
27
- msg.source_file = @end_match[1]
35
+ file = @end_match[1]
36
+ line = @end_match[2].to_i
37
+
38
+ msg.source_file = file unless file.nil?
39
+ msg.source_lines = { from: line, to: line } unless line.nil? || line.zero?
28
40
  msg.preformatted = true
29
41
 
30
42
  [msg, consumed]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class TexLogParser
4
- VERSION = '1.0.0.pre.9'
4
+ VERSION = '1.0.0.pre.10'
5
5
  end
@@ -11,37 +11,56 @@ Dir["#{File.expand_path(__dir__)}/tex_log_parser/patterns/*.rb"].each { |p| requ
11
11
  class TexLogParser
12
12
  include LogParser
13
13
 
14
+ def initialize(log, _options = {})
15
+ super(log, _options)
16
+
17
+ # BROKEN_BY_LINEBREAKS
18
+ # I'd prefer to have this stateless, but well (see below).
19
+ @pushed_dummy = false
20
+ end
21
+
14
22
  def patterns
15
- [FileLineError.new,
23
+ [HighlightedMessages.new,
24
+ FileLineError.new,
16
25
  PrefixedMultiLinePattern.new,
17
26
  RunawayParameterError.new,
18
- ExclaimingError.new,
27
+ StandardError.new,
19
28
  FatalErrorOccurred.new,
20
29
  BadHboxWarning.new]
21
30
  end
22
31
 
23
32
  def scope_changes(line)
24
- case line
25
- when /^\s*\(([^()]*)\)\s*(.*)$/
26
- # A scope opened and closed immediately -- log it, then
27
- # continue with rest of the line (there can be multiple such
28
- # things in one line, see e.g. 000.log:656)
29
- [Regexp.last_match(1), :pop] + (Regexp.last_match(2).strip.empty? ? [] : scope_changes(Regexp.last_match(2)))
30
- when /^\s*\(([^()]+?)\s*$/
31
- # A scope opened and will be closed later.
32
- # Happens on a dedicated line
33
- [Regexp.last_match(1)]
34
- when /^\s*(\)+)(.*)$/
35
- # Scopes close on a dedicated line, except if they don't (cf 000.log:624)
36
- # So we have to continue on the rest of the line. Uh oh.
37
- ([:pop] * Regexp.last_match(1).length) + scope_changes(Regexp.last_match(2))
38
- when /\([^)]*$/
39
- # BROKEN_BY_LINEBREAKS
40
- # Bad linebreaks can cause trailing ) to spill over. Narf.
41
- # e.g. 000.log:502-503
42
- ['dummy'] # Compensate the bad pop that will happen next line.
43
- else
44
- []
45
- end
33
+ result =
34
+ case line
35
+ when /^\s*\(([^()]*)\)\s*(.*)$/
36
+ # A scope opened and closed immediately -- log it, then
37
+ # continue with rest of the line (there can be multiple such
38
+ # things in one line, see e.g. 000.log:656)
39
+ [Regexp.last_match(1), :pop] +
40
+ (Regexp.last_match(2).strip.empty? ? [] : scope_changes(Regexp.last_match(2)))
41
+ when /^\s*\(([^()]+?)\s*$/
42
+ # A scope opened and will be closed later.
43
+ # Happens on a dedicated line
44
+ [Regexp.last_match(1)]
45
+ when /^\s*(\)+)(.*)$/
46
+ # Scopes close on a dedicated line, except if they don't (cf 000.log:624)
47
+ # So we have to continue on the rest of the line. Uh oh.
48
+ ([:pop] * Regexp.last_match(1).length) + scope_changes(Regexp.last_match(2))
49
+ when /\([^)]*$/
50
+ # BROKEN_BY_LINEBREAKS
51
+ # Bad linebreaks can cause trailing ) to spill over. Narf.
52
+ # e.g. 000.log:502-503
53
+ pushed_dummy = true
54
+ ['dummy'] # Compensate the bad pop that will happen next line.
55
+ when /^[^()]*\)/
56
+ # BROKEN_BY_LINEBREAKS
57
+ # Badly broken lines may push ) prefixed by non-whitespace. Narf.
58
+ [:pop] if @pushed_dummy ? [:pop] : []
59
+ else
60
+ []
61
+ end
62
+
63
+ @pushed_dummy = pushed_dummy || false
64
+ result
46
65
  end
47
66
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tex_log_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre.9
4
+ version: 1.0.0.pre.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raphael Reitzig
@@ -83,12 +83,12 @@ files:
83
83
  - lib/tex_log_parser/log_parser.rb
84
84
  - lib/tex_log_parser/log_pattern.rb
85
85
  - lib/tex_log_parser/patterns/bad_hbox_warning.rb
86
- - lib/tex_log_parser/patterns/exclaiming_error.rb
87
86
  - lib/tex_log_parser/patterns/fatal_error_occurred.rb
88
87
  - lib/tex_log_parser/patterns/file_line_error.rb
89
- - lib/tex_log_parser/patterns/fontspec_error.rb
88
+ - lib/tex_log_parser/patterns/highlighted_messages.rb
90
89
  - lib/tex_log_parser/patterns/prefixed_multi_line_pattern.rb
91
90
  - lib/tex_log_parser/patterns/runaway_parameter_error.rb
91
+ - lib/tex_log_parser/patterns/standard_error.rb
92
92
  - lib/tex_log_parser/version.rb
93
93
  homepage: http://github.com/reitzig/texlogparser
94
94
  licenses:
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # TODO: document
4
- class FontspecError
5
- include RegExpPattern
6
-
7
- # TODO: implement
8
- end