require "htmlentities" require "uri" module Asciidoctor module Standoc module Section @biblio = false @term_def = false @norm_ref = false def in_biblio? @biblio end def in_terms? @term_def end def in_norm_ref? @norm_ref end def sectiontype(node) ret = node&.attr("heading")&.downcase || node.title.gsub(/<[^>]+>/, "").downcase return ret if ["symbols and abbreviated terms", "abbreviations", "abbreviated terms", "symbols"].include? ret return nil unless node.level == 1 return nil if @seen_headers.include? ret @seen_headers << ret ret end def section(node) a = { id: Utils::anchor_or_uuid(node) } noko do |xml| case sectiontype(node) when "introduction" then introduction_parse(a, xml, node) when "normative references" then norm_ref_parse(a, xml, node) when "terms and definitions", "terms, definitions, symbols and abbreviated terms", "terms, definitions, symbols and abbreviations", "terms, definitions and symbols", "terms, definitions and abbreviations", "terms, definitions and abbreviated terms" @term_def = true term_def_parse(a, xml, node, true) @term_def = false when "symbols and abbreviated terms", "symbols", "abbreviated terms", "abbreviations" symbols_parse(a, xml, node) when "bibliography" then bibliography_parse(a, xml, node) else if @term_def then term_def_subclause_parse(a, xml, node) elsif @definitions then symbols_parse(a, xml, node) elsif @biblio then bibliography_parse(a, xml, node) elsif node.attr("style") == "bibliography" bibliography_parse(a, xml, node) elsif node.attr("style") == "abstract" abstract_parse(a, xml, node) elsif node.attr("style") == "appendix" && node.level == 1 annex_parse(a, xml, node) else clause_parse(a, xml, node) end end end.join("\n") end def set_obligation(attrs, node) attrs[:obligation] = if node.attributes.has_key?("obligation") node.attr("obligation") elsif node.parent.attributes.has_key?("obligation") node.parent.attr("obligation") else "normative" end end def abstract_parse(attrs, xml, node) xml.abstract **attr_code(attrs) do |xml_section| xml_section << node.content end end def clause_parse(attrs, xml, node) attrs["inline-header".to_sym] = node.option? "inline-header" attrs[:bibitem] = true if node.option? "bibitem" attrs[:level] = node.attr("level") set_obligation(attrs, node) xml.send "clause", **attr_code(attrs) do |xml_section| xml_section.title { |n| n << node.title } unless node.title.nil? xml_section << node.content end end def annex_parse(attrs, xml, node) attrs["inline-header".to_sym] = node.option? "inline-header" set_obligation(attrs, node) xml.annex **attr_code(attrs) do |xml_section| xml_section.title { |name| name << node.title } xml_section << node.content end end def bibliography_parse(attrs, xml, node) node.attr("style") == "bibliography" or warn "Section not marked up as [bibliography]!" @biblio = true xml.references **attr_code(attrs) do |xml_section| title = node.level == 1 ? "Bibliography" : node.title xml_section.title { |t| t << title } xml_section << node.content end @biblio = false end def nonterm_symbols_parse(attrs, xml, node) @definitions = false clause_parse(attrs, xml, node) @definitions = true end def symbols_parse(attrs, xml, node) node.role == "nonterm" and return nonterm_symbols_parse(attrs, xml, node) xml.definitions **attr_code(attrs) do |xml_section| xml_section.title { |t| t << node.title } defs = @definitions termdefs = @term_def @definitions = true @term_def = false xml_section << node.content @definitions = defs @term_def = termdefs end end SYMBOLS_TITLES = ["symbols and abbreviated terms", "symbols", "abbreviated terms"].freeze def nonterm_term_def_subclause_parse(attrs, xml, node) @term_def = false clause_parse(attrs, xml, node) @term_def = true end # subclause contains subclauses def term_def_subclause_parse(attrs, xml, node) node.role == "nonterm" and return nonterm_term_def_subclause_parse(attrs, xml, node) return symbols_parse(attrs, xml, node) if @definitions sub = node.find_by(context: :section) { |s| s.level == node.level + 1 } sub.empty? || (return term_def_parse(attrs, xml, node, false)) SYMBOLS_TITLES.include?(node.title.downcase) and (return symbols_parse(attrs, xml, node)) xml.term **attr_code(attrs) do |xml_section| xml_section.preferred { |name| name << node.title } xml_section << node.content end end def term_def_title(toplevel, node) return node.title unless toplevel sub = node.find_by(context: :section) do |s| SYMBOLS_TITLES.include? s.title.downcase end return "Terms and definitions" if sub.empty? "Terms, definitions, symbols and abbreviated terms" end def term_def_parse(attrs, xml, node, toplevel) xml.terms **attr_code(attrs) do |section| section.title { |t| t << term_def_title(toplevel, node) } (s = node.attr("source")) && s.split(/,/).each do |s1| section.termdocsource(nil, **attr_code(bibitemid: s1)) end section << node.content end end def norm_ref_parse(attrs, xml, node) @norm_ref = true xml.references **attr_code(attrs) do |xml_section| xml_section.title { |t| t << "Normative References" } xml_section << node.content end @norm_ref = false end def introduction_parse(attrs, xml, node) xml.introduction **attr_code(attrs) do |xml_section| xml_section.title = "Introduction" content = node.content xml_section << content end end end end end