lib/asciidoctor/standoc/macros.rb in metanorma-standoc-1.3.17 vs lib/asciidoctor/standoc/macros.rb in metanorma-standoc-1.3.18

- old
+ new

@@ -1,8 +1,9 @@ require "asciidoctor/extensions" require "fileutils" require "uuidtools" +require_relative "./macros_plantuml.rb" module Asciidoctor module Standoc class AltTermInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor use_dsl @@ -152,110 +153,9 @@ 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 PlantUMLBlockMacroBackend - # https://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby - def self.plantuml_installed? - cmd = "plantuml" - exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] - ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| - exts.each do |ext| - exe = File.join(path, "#{cmd}#{ext}") - return exe if File.executable?(exe) && !File.directory?(exe) - end - end - nil - end - - def self.run umlfile, outfile - system "plantuml #{umlfile.path}" or (warn $? and return false) - i = 0 - until !Gem.win_platform? || File.exist?(outfile) || i == 15 - sleep(1) - i += 1 - end - File.exist?(outfile) - end - - # if no :imagesdir: leave image file in plantuml - # sleep need for windows because dot works in separate process and - # plantuml process may finish earlier then dot, as result png file - # maybe not created yet after plantuml finish - def self.generate_file parent, reader - localdir = Utils::localdir(parent.document) - - imagesdir = parent.document.attr('imagesdir') - umlfile, outfile = save_plantuml parent, reader, localdir - - # TODO: this should raise failure if there is no image output!! - run(umlfile, outfile) or return - umlfile.unlink - - path = Pathname.new(localdir) + (imagesdir || "plantuml") - path.mkpath - - # TODO: this should raise failure if the destination path already exists! - File.exist?(path) or return - - # TODO: this should raise failure if the destination path is not writable! - File.writable?(path) or return - - # Warning for Heisenbug: metanorma/metanorma-standoc#187 - # Windows Ruby 2.4 will crash if a Tempfile is "mv"ed. - # This is why we need to copy and then unlink. - filename = File.basename(outfile.to_s) - FileUtils.cp(outfile, path) && outfile.unlink - - imagesdir ? filename : File.join(path, filename) - end - - def self.save_plantuml parent, reader, localdir - src = reader.source - reader.lines.first.sub(/\s+$/, "").match /^@startuml($| )/ or - src = "@startuml\n#{src}\n@enduml\n" - /^@startuml (?<fn>[^\n]+)\n/ =~ src - Tempfile.open(["plantuml", ".pml"], :encoding => "utf-8") do |f| - f.write(src) - [f, File.join(File.dirname(f.path), - (fn || File.basename(f.path, ".pml")) + ".png")] - end - end - - def self.generate_attrs attrs - through_attrs = %w(id align float title role width height alt). - inject({}) do |memo, key| - memo[key] = attrs[key] if attrs.has_key? key - memo - end - end - end - - class PlantUMLBlockMacro < Asciidoctor::Extensions::BlockProcessor - use_dsl - named :plantuml - on_context :literal - parse_content_as :raw - - def abort(parent, reader, attrs, msg) - # TODO: Abort should really raise an error - warn msg - attrs["language"] = "plantuml" - create_listing_block parent, reader.source, attrs.reject { |k, v| k == 1 } - end - - def process(parent, reader, attrs) - PlantUMLBlockMacroBackend.plantuml_installed? or - return abort(parent, reader, attrs, "PlantUML not installed") - filename = PlantUMLBlockMacroBackend.generate_file(parent, reader) or - return abort(parent, reader, attrs, "Failed to process PlantUML") - through_attrs = PlantUMLBlockMacroBackend.generate_attrs attrs - through_attrs["target"] = filename - create_image_block parent, through_attrs end end end end