require "date"
require "nokogiri"
require "htmlentities"
require "json"
require "pathname"
require "open-uri"
require "pp"
module Asciidoctor
module Standoc
module Cleanup
def para_cleanup(xmldoc)
xmldoc.xpath("//p[not(@id)]").each do |x|
x["id"] = Utils::anchor_or_uuid
end
xmldoc.xpath("//note[not(@id)][not(ancestor::bibitem)]"\
"[not(ancestor::table)]").each do |x|
x["id"] = Utils::anchor_or_uuid
end
end
# move Key dl after table footer
def dl_table_cleanup(xmldoc)
q = "//table/following-sibling::*[1][self::p]"
xmldoc.xpath(q).each do |s|
if s.text =~ /^\s*key[^a-z]*$/i && !s.next_element.nil? &&
s.next_element.name == "dl"
s.previous_element << s.next_element.remove
s.remove
end
end
end
def insert_thead(s)
thead = s.at("./thead")
return thead unless thead.nil?
if tname = s.at("./name")
thead = tname.add_next_sibling("").first
return thead
end
s.children.first.add_previous_sibling("").first
end
def header_rows_cleanup(xmldoc)
xmldoc.xpath("//table[@headerrows]").each do |s|
thead = insert_thead(s)
(thead.xpath("./tr").size...s["headerrows"].to_i).each do
row = s.at("./tbody/tr")
row.parent = thead
end
s.delete("headerrows")
end
end
def table_cleanup(xmldoc)
dl_table_cleanup(xmldoc)
notes_table_cleanup(xmldoc)
header_rows_cleanup(xmldoc)
end
# move notes into table
def notes_table_cleanup(xmldoc)
nomatches = false
until nomatches
q = "//table/following-sibling::*[1][self::note]"
nomatches = true
xmldoc.xpath(q).each do |n|
n.previous_element << n.remove
nomatches = false
end
end
end
# include where definition list inside stem block
def formula_cleanup(x)
q = "//formula/following-sibling::*[1][self::p]"
x.xpath(q).each do |s|
if s.text =~ /^\s*where[^a-z]*$/i && !s.next_element.nil? &&
s.next_element.name == "dl"
s.previous_element << s.next_element.remove
s.remove
end
end
end
# include key definition list inside figure
def figure_dl_cleanup(xmldoc)
q = "//figure/following-sibling::*[self::p]"
xmldoc.xpath(q).each do |s|
if s.text =~ /^\s*key[^a-z]*$/i && !s.next_element.nil? &&
s.next_element.name == "dl"
s.previous_element << s.next_element.remove
s.remove
end
end
end
# examples containing only figures become subfigures of figures
def subfigure_cleanup(xmldoc)
nodes = xmldoc.xpath("//example/figure")
while !nodes.empty?
nodes[0].parent.name = "figure"
nodes = xmldoc.xpath("//example/figure")
end
end
def figure_cleanup(xmldoc)
figure_footnote_cleanup(xmldoc)
figure_dl_cleanup(xmldoc)
subfigure_cleanup(xmldoc)
end
def make_preface(x, s)
if x.at("//foreword | //introduction")
preface = s.add_previous_sibling("").first
foreword = x.at("//foreword")
preface.add_child foreword.remove if foreword
introduction = x.at("//introduction")
preface.add_child introduction.remove if introduction
end
end
def make_bibliography(x, s)
if x.at("//sections/references")
biblio = s.add_next_sibling("").first
x.xpath("//sections/references").each do |r|
biblio.add_child r.remove
end
end
end
ELEMS_ALLOW_NOTES =
# %w[p formula quote sourcecode example admonition ul ol dl figure]
%w[p formula ul ol dl figure].freeze
# if a note is at the end of a section, it is left alone
# if a note is followed by a non-note block,
# it is moved inside its preceding block if it is not delimited
# (so there was no way of making that block include the note)
def note_cleanup(xmldoc)
q = "//note[following-sibling::*[not(local-name() = 'note')]]"
xmldoc.xpath(q).each do |n|
next unless n.ancestors("table").empty?
prev = n.previous_element || next
n.parent = prev if ELEMS_ALLOW_NOTES.include? prev.name
end
end
def sections_order_cleanup(x)
s = x.at("//sections")
make_preface(x, s)
make_bibliography(x, s)
x.xpath("//sections/annex").reverse_each { |r| s.next = r.remove }
end
def maxlevel(x)
max = 5
x.xpath("//clause[@level]").each do |c|
max = c["level"].to_i if max < c["level"].to_i
end
max
end
def sections_level_cleanup(x)
m = maxlevel(x)
return if m < 6
m.downto(6).each do |l|
x.xpath("//clause[@level = '#{l}']").each do |c|
c.delete("level")
c.previous_element << c.remove
end
end
end
def sections_cleanup(x)
sections_order_cleanup(x)
sections_level_cleanup(x)
end
def obligations_cleanup(x)
obligations_cleanup_info(x)
obligations_cleanup_norm(x)
obligations_cleanup_inherit(x)
end
def obligations_cleanup_info(x)
(s = x.at("//foreword")) && s["obligation"] = "informative"
(s = x.at("//introduction")) && s["obligation"] = "informative"
x.xpath("//references").each { |r| r["obligation"] = "informative" }
end
def obligations_cleanup_norm(x)
(s = x.at("//clause[title = 'Scope']")) && s["obligation"] = "normative"
(s = x.at("//clause[title = 'Symbols and Abbreviated Terms']")) &&
s["obligation"] = "normative"
x.xpath("//terms").each { |r| r["obligation"] = "normative" }
x.xpath("//symbols-abbrevs").each { |r| r["obligation"] = "normative" }
end
def obligations_cleanup_inherit(x)
x.xpath("//annex | //clause").each do |r|
r["obligation"] = "normative" unless r["obligation"]
end
x.xpath(Utils::SUBCLAUSE_XPATH).each do |r|
r["obligation"] = r.at("./ancestor::*/@obligation").text
end
end
end
end
end