tex_log_parser 1.0.0.pre.9 → 1.0.0.pre.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/logger.rb +5 -1
- data/lib/tex_log_parser/log_message.rb +2 -2
- data/lib/tex_log_parser/log_parser.rb +11 -2
- data/lib/tex_log_parser/patterns/file_line_error.rb +2 -0
- data/lib/tex_log_parser/patterns/highlighted_messages.rb +101 -0
- data/lib/tex_log_parser/patterns/{exclaiming_error.rb → standard_error.rb} +15 -3
- data/lib/tex_log_parser/version.rb +1 -1
- data/lib/tex_log_parser.rb +43 -24
- metadata +3 -3
- data/lib/tex_log_parser/patterns/fontspec_error.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c466836b3e482413ab935462f0bc513bc7bd43a5
|
4
|
+
data.tar.gz: 8cf420477f87eb3e5cca65db7c5b5dedc1b1129b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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.
|
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.
|
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
|
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
|
@@ -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
|
-
|
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]+)
|
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
|
-
|
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]
|
data/lib/tex_log_parser.rb
CHANGED
@@ -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
|
-
[
|
23
|
+
[HighlightedMessages.new,
|
24
|
+
FileLineError.new,
|
16
25
|
PrefixedMultiLinePattern.new,
|
17
26
|
RunawayParameterError.new,
|
18
|
-
|
27
|
+
StandardError.new,
|
19
28
|
FatalErrorOccurred.new,
|
20
29
|
BadHboxWarning.new]
|
21
30
|
end
|
22
31
|
|
23
32
|
def scope_changes(line)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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.
|
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/
|
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:
|