Class: Metanorma::Standoc::PlantUMLBlockMacroBackend
- Inherits:
-
Object
- Object
- Metanorma::Standoc::PlantUMLBlockMacroBackend
- Defined in:
- lib/metanorma/standoc/macros_plantuml.rb
Class Method Summary collapse
- .generate_attrs(attrs) ⇒ Object
-
.generate_file(parent, reader) ⇒ Object
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.
- .generate_file_prep(parent) ⇒ Object
- .localdir(parent) ⇒ Object
- .path_prep(localdir, imagesdir) ⇒ Object
- .plantuml_bin ⇒ Object
- .plantuml_installed? ⇒ Boolean
- .prep_source(reader) ⇒ Object
- .run(umlfile, outfile, fmt) ⇒ Object
- .save_plantuml(_parent, reader, _localdir, fmt) ⇒ Object
- .which(cmd) ⇒ Object
Class Method Details
.generate_attrs(attrs) ⇒ Object
98 99 100 101 102 103 104 |
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 98 def self.generate_attrs(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 |
.generate_file(parent, reader) ⇒ Object
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
# Warning: 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.
41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 41 def self.generate_file(parent, reader) ldir, imagesdir, fmt = generate_file_prep(parent) umlfile, outfile = save_plantuml parent, reader, ldir, fmt run(umlfile, outfile, fmt) or raise "No image output from PlantUML (#{umlfile}, #{outfile})!" umlfile.unlink absolute_path, relative_path = path_prep(ldir, imagesdir) filename = File.basename(outfile.to_s) FileUtils.cp(outfile, absolute_path) and outfile.unlink #imagesdir ? filename : File.join(path, filename) File.join(relative_path, filename) end |
.generate_file_prep(parent) ⇒ Object
54 55 56 57 58 59 60 |
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 54 def self.generate_file_prep(parent) ldir = localdir(parent) imagesdir = parent.document.attr("imagesdir") fmt = parent.document.attr("plantuml-image-format")&.strip&.downcase || "png" [ldir, imagesdir, fmt] end |
.localdir(parent) ⇒ Object
62 63 64 65 66 67 |
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 62 def self.localdir(parent) ret = Metanorma::Utils::localdir(parent.document) File.writable?(ret) or raise "Destination directory #{ret} not writable for PlantUML!" ret end |
.path_prep(localdir, imagesdir) ⇒ Object
69 70 71 72 73 74 75 76 77 |
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 69 def self.path_prep(localdir, imagesdir) #path = Pathname.new(localdir) + (imagesdir || "plantuml") path = Pathname.new(File.join(localdir, "_plantuml_images")) sourcepath = imagesdir ? File.join(localdir, imagesdir) : localdir path.mkpath File.writable?(path) or raise "Destination path #{path} not writable for PlantUML!" [path, Pathname.new(path).relative_path_from(Pathname.new(sourcepath)).to_s] end |
.plantuml_bin ⇒ Object
10 11 12 13 14 15 16 |
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 10 def self.plantuml_bin if Gem.win_platform? || which("plantumlc") "plantumlc" else "plantuml" end end |
.plantuml_installed? ⇒ Boolean
4 5 6 7 8 |
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 4 def self.plantuml_installed? unless which("plantuml") raise "PlantUML not installed" end end |
.prep_source(reader) ⇒ Object
89 90 91 92 93 94 95 96 |
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 89 def self.prep_source(reader) src = reader.source reader.lines.first.sub(/(?<!\s)\s+$/, "").match /^@startuml($| )/ or src = "@startuml\n#{src}\n@enduml\n" %r{@enduml\s*$}m.match?(src) or raise "@startuml without matching @enduml in PlantUML!" src end |
.run(umlfile, outfile, fmt) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 18 def self.run(umlfile, outfile, fmt) valid_formats = %w[png svg eps] unless valid_formats.include?(fmt) raise ArgumentError, "Invalid format: #{fmt}. Allowed formats are: #{valid_formats.join(', ')}" end system(plantuml_bin, umlfile.path, "-t#{fmt}") 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 |
.save_plantuml(_parent, reader, _localdir, fmt) ⇒ Object
79 80 81 82 83 84 85 86 87 |
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 79 def self.save_plantuml(_parent, reader, _localdir, fmt) src = prep_source(reader) /^@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')}.#{fmt}")] end end |
.which(cmd) ⇒ Object
107 108 109 110 111 112 113 114 115 116 |
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 107 def self.which(cmd) 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 |