Class: Metanorma::Standoc::PlantUMLBlockMacroBackend

Inherits:
Object
  • Object
show all
Defined in:
lib/metanorma/standoc/macros_plantuml.rb

Class Method Summary collapse

Class Method Details

.generate_attrs(attrs) ⇒ Object



81
82
83
84
85
86
87
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 81

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.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 36

def self.generate_file(parent, reader)
  localdir = Metanorma::Utils::localdir(parent.document)
  imagesdir = parent.document.attr("imagesdir")
  umlfile, outfile = save_plantuml parent, reader, localdir
  run(umlfile, outfile) or
    raise "No image output from PlantUML (#{umlfile}, #{outfile})!"
  umlfile.unlink

  path = path_prep(localdir, imagesdir)
  filename = File.basename(outfile.to_s)
  FileUtils.cp(outfile, path) and outfile.unlink

  imagesdir ? filename : File.join(path, filename)
end

.path_prep(localdir, imagesdir) ⇒ Object



51
52
53
54
55
56
57
58
59
60
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 51

def self.path_prep(localdir, imagesdir)
  path = Pathname.new(localdir) + (imagesdir || "plantuml")
  File.writable?(localdir) or
    raise "Destination path #{path} not writable for PlantUML!"
  path.mkpath
  File.writable?(path) or
    raise "Destination path #{path} not writable for PlantUML!"
  # File.exist?(path) or raise "Destination path #{path} already exists for PlantUML!"
  path
end

.plantuml_binObject



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

Returns:

  • (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



72
73
74
75
76
77
78
79
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 72

def self.prep_source(reader)
  src = reader.source
  reader.lines.first.sub(/\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) ⇒ Object



18
19
20
21
22
23
24
25
26
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 18

def self.run(umlfile, outfile)
  system "#{plantuml_bin} #{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

.save_plantuml(_parent, reader, _localdir) ⇒ Object



62
63
64
65
66
67
68
69
70
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 62

def self.save_plantuml(_parent, reader, _localdir)
  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')}.png")]
  end
end

.which(cmd) ⇒ Object



90
91
92
93
94
95
96
97
98
99
# File 'lib/metanorma/standoc/macros_plantuml.rb', line 90

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