Class: Metanorma::Utils::Log

Inherits:
Object
  • Object
show all
Defined in:
lib/utils/log.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeLog

Returns a new instance of Log.



8
9
10
11
12
# File 'lib/utils/log.rb', line 8

def initialize
  @log = {}
  @c = HTMLEntities.new
  @mapid = {}
end

Instance Attribute Details

#xml=(value) ⇒ Object (writeonly)

Sets the attribute xml

Parameters:

  • value

    the value to set the attribute xml to.



6
7
8
# File 'lib/utils/log.rb', line 6

def xml=(value)
  @xml = value
end

Instance Method Details

#add(category, loc, msg) ⇒ Object



14
15
16
17
18
19
20
21
# File 'lib/utils/log.rb', line 14

def add(category, loc, msg)
  @novalid and return
  @log[category] ||= []
  item = create_entry(loc, msg)
  @log[category] << item
  loc = loc.nil? ? "" : "(#{current_location(loc)}): "
  warn "#{category}: #{loc}#{msg}"
end

#break_up_long_str(str, threshold, punct) ⇒ Object



153
154
155
# File 'lib/utils/log.rb', line 153

def break_up_long_str(str, threshold, punct)
  Metanorma::Utils.break_up_long_str(str, threshold, punct)
end

#context(node) ⇒ Object



77
78
79
80
81
82
# File 'lib/utils/log.rb', line 77

def context(node)
  node.is_a? String and return nil
  node.respond_to?(:to_xml) and return human_readable_xml(node)
  node.respond_to?(:to_s) and return node.to_s
  nil
end

#create_entry(loc, msg) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/utils/log.rb', line 23

def create_entry(loc, msg)
  msg = msg.encode("UTF-8", invalid: :replace, undef: :replace)
  item = { location: current_location(loc),
           message: msg, context: context(loc), line: line(loc, msg) }
  if item[:message].include?(" :: ")
    a = item[:message].split(" :: ", 2)
    item[:context] = a[1]
    item[:message] = a[0]
  end
  item
end

#current_location(node) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/utils/log.rb', line 35

def current_location(node)
  if node.nil? then ""
  elsif node.respond_to?(:id) && !node.id.nil? then "ID #{node.id}"
  elsif node.respond_to?(:id) && node.id.nil? && node.respond_to?(:parent)
    while !node.nil? && node.id.nil?
      node = node.parent
    end
    node.nil? ? "" : "ID #{node.id}"
  elsif node.respond_to?(:to_xml) && node.respond_to?(:parent)
    while !node.nil? && node["id"].nil? && node.respond_to?(:parent)
      node = node.parent
    end
    node.respond_to?(:parent) ? "ID #{node['id']}" : ""
  elsif node.is_a? String then node
  elsif node.respond_to?(:lineno) && !node.lineno.nil? &&
      !node.lineno.empty?
    "Asciidoctor Line #{'%06d' % node.lineno}"
  elsif node.respond_to?(:line) && !node.line.nil?
    "XML Line #{'%06d' % node.line}"
  elsif node.respond_to?(:parent)
    while !node.nil? &&
        (!node.respond_to?(:level) || node.level.positive?) &&
        (!node.respond_to?(:context) || node.context != :section)
      node = node.parent
      return "Section: #{node.title}" if node.respond_to?(:context) &&
        node&.context == :section
    end
    "??"
  else "??"
  end
end

#human_readable_xml(node) ⇒ Object

try to approximate input, at least for maths



85
86
87
88
89
90
91
92
93
# File 'lib/utils/log.rb', line 85

def human_readable_xml(node)
  ret = node.dup
  ret.xpath(".//*[local-name() = 'stem']").each do |s|
    sub = s.at("./*[local-name() = 'asciimath'] | " \
               "./*[local-name() = 'latexmath']")
    sub and s.replace(sub)
  end
  ret.to_xml
end

#line(node, msg) ⇒ Object



67
68
69
70
71
72
73
74
75
# File 'lib/utils/log.rb', line 67

def line(node, msg)
  if node.respond_to?(:line) && !node.line.nil?
    "#{'%06d' % node.line}"
  elsif /^XML Line /.match?(msg)
    msg.sub(/^XML Line /, "").sub(/:.*$/, "")
  else
    "000000"
  end
end


140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/utils/log.rb', line 140

def loc_link(entry)
  loc = entry[:location]
  loc.nil? || loc.empty? and loc = "--"
  if /^ID /.match?(loc)
    loc.sub!(/^ID /, "")
    loc = @mapid[loc] while @mapid[loc]
    url = "#{@filename}##{loc}"
  end
  loc &&= break_up_long_str(loc, 10, 2)
  url and loc = "<a href='#{url}'>#{loc}</a>"
  loc
end

#log_hdr(file) ⇒ Object



95
96
97
98
99
100
101
# File 'lib/utils/log.rb', line 95

def log_hdr(file)
  "    <html><head><title>\#{file} errors</title>\n    <style> pre { white-space: pre-wrap; } </style>\n    </head><body><h1>\#{file} errors</h1>\n  HTML\nend\n"

#mapid(old, new) ⇒ Object



136
137
138
# File 'lib/utils/log.rb', line 136

def mapid(old, new)
  @mapid[old] = new
end

#write(file) ⇒ Object



103
104
105
106
107
108
109
110
# File 'lib/utils/log.rb', line 103

def write(file)
  @filename = file.sub(".err.html", ".html")
  File.open(file, "w:UTF-8") do |f|
    f.puts log_hdr(file)
    @log.each_key { |key| write_key(f, key) }
    f.puts "</body></html>\n"
  end
end

#write1(file, entry) ⇒ Object



125
126
127
128
129
130
131
132
133
134
# File 'lib/utils/log.rb', line 125

def write1(file, entry)
  line = entry[:line]
  line = nil if line == "000000"
  loc = loc_link(entry)
  msg = break_up_long_str(entry[:message], 10, 2)
    .gsub(/`([^`]+)`/, "<code>\\1</code>")
  entry[:context] and context = entry[:context].split("\n").first(5)
    .join("\n").gsub("><", "> <")
  write_entry(file, line, loc, msg, context)
end

#write_entry(file, line, loc, msg, context) ⇒ Object



157
158
159
160
161
162
# File 'lib/utils/log.rb', line 157

def write_entry(file, line, loc, msg, context)
  context &&= @c.encode(break_up_long_str(context, 40, 2))
  file.print "    <tr><td>\#{line}</td><th><code>\#{loc}</code></th><td>\#{msg}</td><td><pre>\#{context}</pre></td></tr>\n  HTML\nend\n"

#write_key(file, key) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/utils/log.rb', line 112

def write_key(file, key)
  file.puts "    <h2>\#{key}</h2>\\n<table border=\"1\">\n    <thead><th width=\"5%\">Line</th><th width=\"20%\">ID</th><th width=\"30%\">Message</th><th width=\"45%\">Context</th></thead>\n    <tbody>\n  HTML\n  @log[key].sort_by { |a| [a[:line], a[:location], a[:message]] }\n    .each do |n|\n    write1(file, n)\n  end\n  file.puts \"</tbody></table>\\n\"\nend\n"