require "asciidoctor/extensions" require "fileutils" require "uuidtools" require "yaml" require_relative "./macros_plantuml.rb" require_relative "./datamodel/attributes_table_preprocessor.rb" require_relative "./datamodel/diagram_preprocessor.rb" require "metanorma-plugin-datastruct" require "metanorma-plugin-lutaml" module Asciidoctor module Standoc class AltTermInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor use_dsl named :alt parse_content_as :text using_format :short def process(parent, _target, attrs) out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert %{#{out}} end end class DeprecatedTermInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor use_dsl named :deprecated parse_content_as :text using_format :short def process(parent, _target, attrs) out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert %{#{out}} end end class DomainTermInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor use_dsl named :domain parse_content_as :text using_format :short def process(parent, _target, attrs) out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert %{#{out}} end end class InheritInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor use_dsl named :inherit parse_content_as :text using_format :short def process(parent, _target, attrs) out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert %{#{out}} end end class ConceptInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor use_dsl named :concept name_positional_attributes "id", "word", "term" # match %r{concept:(?[^\[]*)\[(?|.*?[^\\])\]$} match /\{\{(?|.*?[^\\])\}\}/ using_format :short # deal with locality attrs and their disruption of positional attrs def preprocess_attrs(attrs) attrs.delete("term") if attrs["term"] && !attrs["word"] attrs.delete(3) if attrs[3] == attrs["term"] a = attrs.keys.reject { |k| k.is_a?(String) || [1, 2].include?(k) } attrs["word"] ||= attrs[a[0]] if !a.empty? attrs["term"] ||= attrs[a[1]] if a.length > 1 attrs end def process(parent, _target, attr) attr = preprocess_attrs(attr) localities = attr.keys.reject { |k| %w(id word term).include? k }. reject { |k| k.is_a? Numeric }. map { |k| "#{k}=#{attr[k]}" }.join(",") text = [localities, attr["word"]].reject{ |k| k.nil? || k.empty? }. join(",") out = Asciidoctor::Inline.new(parent, :quoted, text).convert %{#{out}} end end class PseudocodeBlockMacro < Asciidoctor::Extensions::BlockProcessor use_dsl named :pseudocode on_context :example, :sourcecode def init_indent(s) /^(?[ \t]*)(?.*)$/ =~ s prefix = prefix.gsub(/\t/, "\u00a0\u00a0\u00a0\u00a0") .gsub(/ /, "\u00a0") prefix + suffix end def supply_br(lines) ignore = false lines.each_with_index do |l, i| /^(--+|====+|\|===|\.\.\.\.+|\*\*\*\*+|\+\+\+\++|\`\`\`\`+|____\+)$/.match(l) && (ignore = !ignore) next if l.empty? || l.match(/ \+$/) next if /^\[.*\]$/.match(l) next if ignore next if i == lines.size - 1 || i < lines.size - 1 && lines[i + 1].empty? lines[i] += " +" end lines end def process(parent, reader, attrs) attrs["role"] = "pseudocode" lines = reader.lines.map { |m| init_indent(m) } ret = create_block(parent, :example, supply_br(lines), attrs, content_model: :compound) ret end end class HTML5RubyMacro < Asciidoctor::Extensions::InlineMacroProcessor use_dsl named :ruby parse_content_as :text option :pos_attrs, %w(rpbegin rt rpend) def process(_parent, target, attributes) rpbegin = "(" rpend = ")" if (attributes.size == 1) && attributes.key?("text") rt = attributes["text"] elsif (attributes.size == 2) && attributes.key?(1) && attributes.key?("rpbegin") # for example, html5ruby:楽聖少女[がくせいしょうじょ] rt = attributes[1] || "" else rpbegin = attributes["rpbegin"] rt = attributes["rt"] rpend = attributes["rpend"] end "#{target}#{rpbegin}#{rt}"\ "#{rpend}" end end class ToDoAdmonitionBlock < Extensions::BlockProcessor use_dsl named :TODO on_contexts :example, :paragraph def process(parent, reader, attrs) attrs["name"] = "todo" attrs["caption"] = "TODO" create_block parent, :admonition, reader.lines, attrs, content_model: :compound end end class ToDoInlineAdmonitionBlock < Extensions::Treeprocessor def process(document) (document.find_by context: :paragraph).each do |para| next unless /^TODO: /.match para.lines[0] parent = para.parent para.set_attr("name", "todo") para.set_attr("caption", "TODO") para.lines[0].sub!(/^TODO: /, "") todo = Block.new parent, :admonition, attributes: para.attributes, source: para.lines, content_model: :compound parent.blocks[parent.blocks.index(para)] = todo end end end class AutonumberInlineMacro < Extensions::InlineMacroProcessor use_dsl named :autonumber parse_content_as :text def process(parent, target, attrs) out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert %{#{out}} end end class VariantInlineMacro < Extensions::InlineMacroProcessor use_dsl named :lang parse_content_as :text def process(parent, target, attrs) /^(?[^-]*)(-(?