tex_log_parser 1.0.0.pre.1 → 1.0.0.pre.2
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/README.md +16 -2
- data/bin/texlogparser +71 -2
- data/lib/tex_log_parser/log_buffer.rb +56 -0
- data/lib/tex_log_parser/log_message.rb +29 -5
- data/lib/tex_log_parser/log_parser.rb +80 -44
- data/lib/tex_log_parser/log_pattern.rb +8 -6
- data/lib/tex_log_parser/patterns/prefixed_multi_line_pattern.rb +1 -1
- data/lib/tex_log_parser/version.rb +3 -0
- data/lib/tex_log_parser.rb +23 -27
- metadata +29 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 062e87fb6cd767aacf4df4306f06812861c0f435
|
4
|
+
data.tar.gz: 36c8a772c8a16b79b112288a4673603050b181d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d2dbe0b0507532726115f4c45652ba3d5d642db99ff43e9298a628f2fc3891d6e0b97e0fe4226cb91d1c81f8afa32be6bfc38093b2a6bb897edb6356e61eeb8f
|
7
|
+
data.tar.gz: 1251c33e7e6803f91f309b8d5920febfb45e6d0e4a14eb9c24bbaea5aa83a47f2fe290ae0d7d1b97e59d81170fc54ff71d35f7309c8741ba27afd9adb2cc7c03
|
data/README.md
CHANGED
@@ -1,6 +1,20 @@
|
|
1
1
|
# TeXLogParser
|
2
2
|
|
3
|
-
[](https://badge.fury.io/rb/tex_log_parser)
|
4
|
+
[](http://www.rubydoc.info/gems/tex_log_parser/1.0.0.pre.1) **˙**
|
5
|
+
[](https://codeclimate.com/github/reitzig/texlogparser/maintainability)
|
6
|
+
[](https://codeclimate.com/github/reitzig/texlogparser/test_coverage) **˙**
|
4
7
|
[](https://travis-ci.org/reitzig/texlogparser)
|
8
|
+
[](http://inch-ci.org/github/reitzig/texlogparser)
|
5
9
|
|
6
|
-
|
10
|
+
Eases the many pains around logs from (La)TeX engines.
|
11
|
+
|
12
|
+
## Usage
|
13
|
+
|
14
|
+
* Use `texlogparser` on the CLI.
|
15
|
+
* Use `TexLogParser` from Ruby scripts.
|
16
|
+
|
17
|
+
## Contributing
|
18
|
+
|
19
|
+
1. TeXians: Report wrong parsing (w/ excerpt and full log incl expectations).
|
20
|
+
2. Rubyists: Review API, documentation, gem setup, etc.
|
data/bin/texlogparser
CHANGED
@@ -1,6 +1,75 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
if $PROGRAM_NAME == __FILE__
|
4
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
5
|
+
end
|
6
|
+
|
3
7
|
require 'tex_log_parser'
|
8
|
+
require 'optparse'
|
9
|
+
require 'json'
|
10
|
+
|
11
|
+
# Defaults
|
12
|
+
options = {
|
13
|
+
debug: false,
|
14
|
+
format: :file_line,
|
15
|
+
input: STDIN,
|
16
|
+
output: STDOUT
|
17
|
+
}
|
18
|
+
formats = [:file_line, :json]
|
19
|
+
|
20
|
+
OptionParser.new do |opts|
|
21
|
+
opts.banner = 'Usage: texlogparser [options]'
|
22
|
+
opts.on('-d', '--debug', 'Output debug information') do
|
23
|
+
options[:debug] = true
|
24
|
+
end
|
25
|
+
opts.on('-f ENUM', '--format ENUM', formats,
|
26
|
+
'Output format', "One of: #{formats.map { |e| e.to_s }.join(", ")}") do |format|
|
27
|
+
options[:format] = format
|
28
|
+
end
|
29
|
+
opts.on('-i', '--input PATH', 'Read input from PATH') do |path|
|
30
|
+
unless File.file?(path)
|
31
|
+
STDERR.puts("No such file: #{path}")
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
|
35
|
+
options[:input] = path
|
36
|
+
end
|
37
|
+
opts.on('-o', '--output PATH', 'Write output to PATH') do |path|
|
38
|
+
options[:output] = path
|
39
|
+
end
|
40
|
+
opts.on_tail('-h', '--help', 'Show this message') do
|
41
|
+
puts opts
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
opts.on_tail('-v', '--version', 'Show version') do
|
45
|
+
puts TexLogParser::VERSION
|
46
|
+
exit
|
47
|
+
end
|
48
|
+
|
49
|
+
begin
|
50
|
+
opts.parse!
|
51
|
+
rescue => e
|
52
|
+
STDERR.puts e
|
53
|
+
exit 1
|
54
|
+
end
|
55
|
+
|
56
|
+
if !options[:input].is_a?(String) && STDIN.tty?
|
57
|
+
STDERR.puts opts.help
|
58
|
+
exit 1
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
input = STDIN
|
63
|
+
input = File.open(options[:input], 'r') if options[:input].is_a?(String)
|
64
|
+
parser = TexLogParser.new(input, options)
|
65
|
+
messages = parser.parse
|
4
66
|
|
5
|
-
|
6
|
-
|
67
|
+
output = STDOUT
|
68
|
+
output = File.open(options[:output], 'w') if options[:output].is_a?(String)
|
69
|
+
case options[:format]
|
70
|
+
when :file_line
|
71
|
+
output.write(messages.map { |m| m.to_s }.join("\n\n"))
|
72
|
+
when :json
|
73
|
+
output.write(JSON.pretty_generate(messages))
|
74
|
+
end
|
75
|
+
output.close
|
@@ -0,0 +1,56 @@
|
|
1
|
+
class LogBuffer
|
2
|
+
# @param [Array<String>,IO] log
|
3
|
+
def initialize(log)
|
4
|
+
@buffer = []
|
5
|
+
@stream = nil
|
6
|
+
|
7
|
+
@buffer = log if log.is_a?(Array)
|
8
|
+
@stream = log if log.is_a?(IO) || log.is_a?(StringIO)
|
9
|
+
end
|
10
|
+
|
11
|
+
def empty?
|
12
|
+
@buffer.empty? && stream_is_done?
|
13
|
+
end
|
14
|
+
|
15
|
+
def first
|
16
|
+
self[0]
|
17
|
+
end
|
18
|
+
|
19
|
+
def find_index(starting_from = 0)
|
20
|
+
index = starting_from
|
21
|
+
element = self[index]
|
22
|
+
|
23
|
+
until element.nil?
|
24
|
+
return index if yield(element)
|
25
|
+
index += 1
|
26
|
+
element = self[index]
|
27
|
+
end
|
28
|
+
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def [](offset, length = nil)
|
33
|
+
base_length = length || 1
|
34
|
+
while offset + base_length > @buffer.size
|
35
|
+
return (length.nil? ? nil : @buffer[offset, @buffer.size]) if stream_is_done?
|
36
|
+
@buffer.push(@stream.readline.rstrip)
|
37
|
+
end
|
38
|
+
|
39
|
+
length.nil? ? @buffer[offset] : @buffer[offset, length]
|
40
|
+
end
|
41
|
+
|
42
|
+
def forward(offset = 1)
|
43
|
+
self[offset]
|
44
|
+
@buffer.slice!(0, offset)
|
45
|
+
end
|
46
|
+
|
47
|
+
def close
|
48
|
+
@stream.close unless @stream.nil? || @stream.closed?
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def stream_is_done?
|
54
|
+
@stream.nil? || @stream.closed? || @stream.eof?
|
55
|
+
end
|
56
|
+
end
|
@@ -1,17 +1,24 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
1
3
|
# @attr [String] message
|
2
4
|
# @attr [String,nil] source_file
|
3
5
|
# @attr [Hash<Symbol, Int>,nil] source_lines
|
4
6
|
# @attr [Hash<Symbol, Int>,nil] log_lines
|
5
7
|
# @attr [true,false] preformatted
|
6
8
|
# @attr [:error,:warning,:info,:debug] level
|
9
|
+
# @attr [Class] pattern
|
7
10
|
class LogMessage
|
8
|
-
def initialize(message:, source_file: nil, source_lines: nil, log_lines: nil,
|
11
|
+
def initialize(message:, source_file: nil, source_lines: nil, log_lines: nil,
|
12
|
+
preformatted: false, level: :info, pattern: nil)
|
9
13
|
@message = message
|
10
14
|
@source_file = source_file
|
11
15
|
@source_lines = source_lines
|
12
16
|
@log_lines = log_lines
|
13
17
|
@preformatted = preformatted
|
14
18
|
@level = level
|
19
|
+
@pattern = pattern
|
20
|
+
|
21
|
+
@debug = false # TODO: get option here
|
15
22
|
end
|
16
23
|
|
17
24
|
attr_accessor :message, :source_file, :source_lines, :log_lines,
|
@@ -19,14 +26,31 @@ class LogMessage
|
|
19
26
|
|
20
27
|
def to_s
|
21
28
|
lines = if @source_lines.nil?
|
22
|
-
|
29
|
+
''
|
23
30
|
else
|
24
31
|
# @type [Hash<Symbol, Int>] @source_lines
|
25
|
-
@source_lines.values.join(
|
32
|
+
":#{@source_lines.values.uniq.join('-')}"
|
26
33
|
end
|
34
|
+
|
35
|
+
message = @message
|
36
|
+
message = message.split("\n").map {|l| l.strip }.join("") unless @preformatted
|
37
|
+
message += "\nLog pattern: '#{@pattern}'" if @debug
|
38
|
+
|
27
39
|
<<~MSG
|
28
|
-
#{@source_file}
|
29
|
-
#{
|
40
|
+
#{@source_file}#{lines}: #{@level.to_s.upcase}
|
41
|
+
#{message}
|
30
42
|
MSG
|
31
43
|
end
|
44
|
+
|
45
|
+
def to_json(options={})
|
46
|
+
hash = {
|
47
|
+
level: @level,
|
48
|
+
source_file: @source_file,
|
49
|
+
source_lines: @source_lines,
|
50
|
+
message: @message,
|
51
|
+
log_lines: @log_lines,
|
52
|
+
preformatted: @preformatted
|
53
|
+
}
|
54
|
+
JSON.pretty_generate hash
|
55
|
+
end
|
32
56
|
end
|
@@ -1,7 +1,22 @@
|
|
1
|
+
require "#{File.expand_path(__dir__)}/log_buffer.rb"
|
2
|
+
|
1
3
|
# TODO: document
|
2
4
|
module LogParser
|
3
|
-
|
5
|
+
attr_reader :messages
|
6
|
+
|
7
|
+
# TODO: document
|
8
|
+
# @param [Array<String>,IO,StringIO] log
|
9
|
+
# @param [Hash] options
|
10
|
+
def initialize(log, options)
|
4
11
|
@files = []
|
12
|
+
|
13
|
+
@messages = []
|
14
|
+
@log_line_number = 0
|
15
|
+
@lines = LogBuffer.new(log)
|
16
|
+
|
17
|
+
@debug = options.fetch(:debug, false)
|
18
|
+
|
19
|
+
puts "Parsing from '#{log}'" if @debug
|
5
20
|
end
|
6
21
|
|
7
22
|
# @return [Array<LogPattern>]
|
@@ -18,57 +33,78 @@ module LogParser
|
|
18
33
|
end
|
19
34
|
|
20
35
|
# TODO: document
|
21
|
-
# @param [Array<String>] log_lines
|
22
36
|
# @return [Array<LogMessage>]
|
23
|
-
def parse
|
24
|
-
|
37
|
+
def parse
|
38
|
+
raise 'Parser already ran!' unless @log_line_number.zero?
|
25
39
|
|
26
|
-
log_line_number = 1
|
27
|
-
until
|
28
|
-
line =
|
40
|
+
@log_line_number = 1
|
41
|
+
until @lines.empty?
|
42
|
+
line = @lines.first
|
29
43
|
|
30
44
|
if line.strip.empty?
|
31
|
-
|
32
|
-
|
33
|
-
# Use the first pattern that matches. Let's hope that's a good heuristic.
|
34
|
-
# If not, we'll have to let all competitors consume and see who wins --
|
35
|
-
# which we'd decide how?
|
36
|
-
matching_pattern = patterns.detect { |p| p.begins_at?(line) }
|
37
|
-
|
38
|
-
if matching_pattern.nil?
|
39
|
-
# In the hope that scope changes happen not on the same
|
40
|
-
# line as messages. Gulp.
|
41
|
-
scope_changes(log_lines.first).each { |op|
|
42
|
-
if op == :pop
|
43
|
-
left = @files.pop
|
44
|
-
#puts "Finished file #{left.nil? ? "nil" : left}" # TODO: debug mode
|
45
|
-
left
|
46
|
-
else
|
47
|
-
#puts "Entered file #{op}" # TODO: debug mode
|
48
|
-
@files.push(op)
|
49
|
-
end
|
50
|
-
}
|
51
|
-
|
52
|
-
# Try again with the next line
|
53
|
-
consumed_lines = 1
|
54
|
-
else
|
55
|
-
# Apply the pattern, i.e. read the next message!
|
56
|
-
# @type [LogMessage] message
|
57
|
-
message, consumed_lines = matching_pattern.read(log_lines)
|
58
|
-
message.log_lines = { from: log_line_number,
|
59
|
-
to: log_line_number + consumed_lines - 1 }
|
60
|
-
message.source_file ||= @files.last
|
61
|
-
|
62
|
-
messages.push(message)
|
63
|
-
end
|
45
|
+
remove_consumed_lines 1
|
46
|
+
next
|
64
47
|
end
|
65
48
|
|
66
|
-
#
|
67
|
-
|
68
|
-
|
49
|
+
puts "\nLine: '#{line.strip}'" if @debug
|
50
|
+
|
51
|
+
# Use the first pattern that matches. Let's hope that's a good heuristic.
|
52
|
+
# If not, we'll have to let all competitors consume and see who wins --
|
53
|
+
# which we'd decide how?
|
54
|
+
matching_pattern = patterns.detect { |p| p.begins_at?(line) }
|
55
|
+
|
56
|
+
if matching_pattern.nil?
|
57
|
+
puts '- No pattern matches' if @debug
|
58
|
+
apply_scope_changes
|
59
|
+
else
|
60
|
+
puts "- Matched pattern: '#{matching_pattern.class}'" if @debug
|
61
|
+
consume_pattern(matching_pattern)
|
62
|
+
end
|
69
63
|
end
|
70
64
|
|
71
|
-
|
65
|
+
puts "\nFiles that did not close: #{@files}" if @debug
|
66
|
+
@lines.close
|
72
67
|
messages
|
73
68
|
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def remove_consumed_lines(i)
|
73
|
+
@lines.forward(i)
|
74
|
+
@log_line_number += i
|
75
|
+
end
|
76
|
+
|
77
|
+
def consume_pattern(pattern)
|
78
|
+
# Apply the pattern, i.e. read the next message!
|
79
|
+
begin
|
80
|
+
# @type [LogMessage] message
|
81
|
+
message, consumed_lines = pattern.read(@lines)
|
82
|
+
message.log_lines = { from: @log_line_number,
|
83
|
+
to: @log_line_number + consumed_lines - 1 }
|
84
|
+
message.source_file ||= @files.last
|
85
|
+
|
86
|
+
puts message if @debug
|
87
|
+
@messages.push(message)
|
88
|
+
remove_consumed_lines consumed_lines
|
89
|
+
rescue => e
|
90
|
+
puts "#{e}" if @debug
|
91
|
+
remove_consumed_lines 1
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def apply_scope_changes
|
96
|
+
# In the hope that scope changes happen not on the same
|
97
|
+
# line as messages. Gulp.
|
98
|
+
scope_changes(@lines.first).each do |op|
|
99
|
+
if op == :pop
|
100
|
+
left = @files.pop
|
101
|
+
puts "- Finished source file: '#{left.nil? ? 'nil' : left}'" if @debug
|
102
|
+
else # op is file name
|
103
|
+
puts "- Entered source file: '#{op}'" if @debug
|
104
|
+
@files.push(op)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
remove_consumed_lines 1
|
109
|
+
end
|
74
110
|
end
|
@@ -29,11 +29,12 @@ module RegExpPattern
|
|
29
29
|
# @option ending [Regexp] :pattern
|
30
30
|
# @option ending [:match,:mismatch] :until
|
31
31
|
# @option ending [true,false] :inclusive
|
32
|
-
def initialize(start, ending = { pattern: ->(_) { /^\s
|
32
|
+
def initialize(start, ending = { pattern: ->(_) { /^\s*$/ },
|
33
33
|
until: :match,
|
34
34
|
inclusive: false })
|
35
35
|
@start = start
|
36
36
|
@ending = ending
|
37
|
+
@debug = false # TODO: Get the option here
|
37
38
|
end
|
38
39
|
|
39
40
|
# TODO: document
|
@@ -50,16 +51,17 @@ module RegExpPattern
|
|
50
51
|
end
|
51
52
|
|
52
53
|
# TODO make failable (e.g. EOF)
|
53
|
-
# @param [
|
54
|
+
# @param [LogBuffer] lines
|
54
55
|
# @return [Array<(LogMessage, Int)>]
|
55
|
-
def read(lines)
|
56
|
+
def read(lines)
|
56
57
|
raise NotImplementedError if @ending.nil?
|
57
58
|
|
58
|
-
ending = lines
|
59
|
-
|
59
|
+
ending = lines.find_index(1) { |l| ends_at?(l) }
|
60
|
+
raise "Did not find end of message (pattern '#{self.class}')." if ending.nil?
|
61
|
+
ending -= 1 unless @ending[:inclusive]
|
60
62
|
|
61
63
|
# Use ending+1 since ending is the index when we drop the first line!
|
62
|
-
msg = LogMessage.new(message: lines[0, ending+1].join, preformatted:
|
64
|
+
msg = LogMessage.new(message: lines[0, ending + 1].join("\n"), preformatted: true, level: nil)
|
63
65
|
[msg, ending + 1]
|
64
66
|
end
|
65
67
|
end
|
@@ -44,7 +44,7 @@ class PrefixedMultiLinePattern
|
|
44
44
|
msg.source_lines = { from: line, to: line }
|
45
45
|
end
|
46
46
|
|
47
|
-
# TODO: message itself contains useless line prefixes --> remove
|
47
|
+
# TODO: message itself contains useless line prefixes --> remove, preformatted = false
|
48
48
|
|
49
49
|
[msg, consumed]
|
50
50
|
end
|
data/lib/tex_log_parser.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'tex_log_parser/log_parser'
|
2
|
+
require 'tex_log_parser/version'
|
2
3
|
Dir["#{File.expand_path(__dir__)}/tex_log_parser/patterns/*.rb"].each { |p| require p }
|
3
4
|
|
4
5
|
# TODO: document
|
@@ -10,32 +11,27 @@ class TexLogParser
|
|
10
11
|
end
|
11
12
|
|
12
13
|
def scope_changes(line)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
# puts line # TODO: debug mode
|
37
|
-
# puts ops.to_s
|
38
|
-
# puts ""
|
39
|
-
ops
|
14
|
+
case line
|
15
|
+
when /^\s*\(([^()]*)\)\s+(.*)$/
|
16
|
+
# A scope opened and closed immediately -- log it, then
|
17
|
+
# continue with rest of the line (there can be multiple such
|
18
|
+
# things in one line, see e.g. 000.log:656)
|
19
|
+
[$1, :pop] + ($2.strip.empty? ? [] : scope_changes($2))
|
20
|
+
when /^\s*\(([^()]+?)\s*$/
|
21
|
+
# A scope opened and will be closed later.
|
22
|
+
# Happens on a dedicated line
|
23
|
+
[$1]
|
24
|
+
when /^\s*(\)+)(.*)$/
|
25
|
+
# Scopes close on a dedicated line, except if they don't (cf 000.log:624)
|
26
|
+
# So we have to continue on the rest of the line. Uh oh.
|
27
|
+
([:pop] * $1.length) + scope_changes($2)
|
28
|
+
when /\([^)]*$/
|
29
|
+
# BROKEN_BY_LINEBREAKS
|
30
|
+
# Bad linebreaks can cause trailing ) to spill over. Narf.
|
31
|
+
# e.g. 000.log:502-503
|
32
|
+
["dummy"] # Compensate the bad pop that will happen next line.
|
33
|
+
else
|
34
|
+
[]
|
35
|
+
end
|
40
36
|
end
|
41
37
|
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.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Raphael Reitzig
|
@@ -14,44 +14,58 @@ dependencies:
|
|
14
14
|
name: minitest
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '5.10'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '5.10'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '12.3'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '12.3'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: yard
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
47
|
+
version: '0.9'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
54
|
+
version: '0.9'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: json
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.1'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.1'
|
55
69
|
description: Parses log files of (La)TeX engines
|
56
70
|
email: 4246780+reitzig@users.noreply.github.com
|
57
71
|
executables:
|
@@ -63,6 +77,7 @@ files:
|
|
63
77
|
- README.md
|
64
78
|
- bin/texlogparser
|
65
79
|
- lib/tex_log_parser.rb
|
80
|
+
- lib/tex_log_parser/log_buffer.rb
|
66
81
|
- lib/tex_log_parser/log_message.rb
|
67
82
|
- lib/tex_log_parser/log_parser.rb
|
68
83
|
- lib/tex_log_parser/log_pattern.rb
|
@@ -71,6 +86,7 @@ files:
|
|
71
86
|
- lib/tex_log_parser/patterns/fontspec_error.rb
|
72
87
|
- lib/tex_log_parser/patterns/prefixed_multi_line_pattern.rb
|
73
88
|
- lib/tex_log_parser/patterns/runaway_parameter_error.rb
|
89
|
+
- lib/tex_log_parser/version.rb
|
74
90
|
homepage: http://github.com/reitzig/texlogparser
|
75
91
|
licenses:
|
76
92
|
- MIT
|