Class: Metanorma::Plugin::Plantuml::Backend

Inherits:
Object
  • Object
show all
Defined in:
lib/metanorma/plugin/plantuml/backend.rb

Overview

Backend class for PlantUML diagram generation Adapted from metanorma-standoc’s PlantUMLBlockMacroBackend

Class Method Summary collapse

Class Method Details

.generate_attrs(attrs) ⇒ Object



147
148
149
150
151
152
# File 'lib/metanorma/plugin/plantuml/backend.rb', line 147

def generate_attrs(attrs)
  %w[id align float title role width height alt]
    .each_with_object({}) do |key, memo|
    memo[key] = attrs[key] if attrs.key?(key)
  end
end

.generate_file(parent, reader, format_override: nil, options: {}) ⇒ Object

rubocop:disable Metrics/AbcSize, Metrics/MethodLength



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/metanorma/plugin/plantuml/backend.rb', line 23

def generate_file( # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  parent, reader, format_override: nil, options: {}
)
  ldir, imagesdir, fmt = generate_file_prep(parent)
  fmt = format_override if format_override
  plantuml_content = prep_source(parent, reader)

  # Extract filename from PlantUML source if specified
  filename = generate_unique_filename(fmt)
  extracted_filename = extract_plantuml_filename(plantuml_content)

  filename = "#{extracted_filename}.#{fmt}" if extracted_filename

  absolute_path, relative_path = path_prep(ldir, imagesdir)
  output_file = File.join(absolute_path, filename)

  result = Wrapper.generate(
    plantuml_content,
    format: fmt,
    output_file: output_file,
    includedirs: options[:includedirs],
    layout: options[:layout],
  )

  raise "No image output from PlantUML: #{result[:error].message}" unless result[:success]

  File.join(relative_path, filename)
end

.generate_file_prep(parent) ⇒ Object

rubocop:disable Metrics/AbcSize,Metrics/MethodLength



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/metanorma/plugin/plantuml/backend.rb', line 71

def generate_file_prep(parent) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
  imagesdir = if parent.document.attr("docfile") &&
      parent.document.attr("imagesdir")
                File.expand_path(
                  File.join(
                    File.dirname(parent.document.attr("docfile")),
                    parent.document.attr("imagesdir"),
                  ),
                )
              else
                parent.document.attr("imagesdir")
              end

  ldir = localdir(parent)
  fmt = parent.document
    .attr("plantuml-image-format")&.strip&.downcase ||
    Wrapper::DEFAULT_FORMAT
  [ldir, imagesdir, fmt]
end

.generate_multiple_files(parent, reader, formats, attrs, options: {}) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/metanorma/plugin/plantuml/backend.rb', line 52

def generate_multiple_files(
  parent, reader, formats, attrs, options: {}
)
  # Generate files for each format
  filenames = formats.map do |format|
    generate_file(parent, reader, format, options: options)
  end

  # Return data for BlockProcessor to create image block
  through_attrs = generate_attrs attrs
  through_attrs["target"] = filenames.first

  # Store additional formats for potential future use
  through_attrs["data-formats"] = formats.join(",")
  through_attrs["data-files"] = filenames.join(",")

  through_attrs
end

.localdir(parent) ⇒ Object



91
92
93
94
95
96
# File 'lib/metanorma/plugin/plantuml/backend.rb', line 91

def localdir(parent)
  ret = Utils.localdir(parent.document)
  return ret if File.writable?(ret)

  raise "Destination directory #{ret} not writable for PlantUML!"
end

.path_prep(localdir, imagesdir) ⇒ Object

rubocop:disable Metrics/AbcSize,Metrics/MethodLength



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/metanorma/plugin/plantuml/backend.rb', line 98

def path_prep(localdir, imagesdir) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
  # Determine source path
  sourcepath = if imagesdir.nil?
                 localdir
               elsif Pathname.new(imagesdir).absolute?
                 imagesdir
               else
                 File.join(localdir, imagesdir)
               end

  # Determine PlantUML images destination absolute path
  path = Pathname.new(
    File.expand_path(File.join(localdir, "_plantuml_images")),
  )
  path.mkpath

  unless File.writable?(path)
    raise "Destination path #{path} not writable for PlantUML!"
  end

  [
    path,
    Pathname.new(path)
      .relative_path_from(Pathname.new(sourcepath)).to_s,
  ]
end

.plantuml_available?Boolean

Returns:

  • (Boolean)


19
20
21
# File 'lib/metanorma/plugin/plantuml/backend.rb', line 19

def plantuml_available?
  Wrapper.available?
end

.plantuml_installed?Boolean

Returns:

  • (Boolean)


13
14
15
16
17
# File 'lib/metanorma/plugin/plantuml/backend.rb', line 13

def plantuml_installed?
  return true if plantuml_available?

  raise "PlantUML not installed"
end

.prep_source(parent, reader) ⇒ Object

rubocop:disable Metrics/MethodLength



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/metanorma/plugin/plantuml/backend.rb', line 125

def prep_source(parent, reader) # rubocop:disable Metrics/MethodLength
  src = if reader.respond_to?(:source)
          # get content from BlockProcessor
          reader.source
        else
          # get content from ImageBlockMacroProcessor
          docfile_directory = File.dirname(
            parent.document.attributes["docfile"] || ".",
          )

          resolved_path = parent.document
            .path_resolver
            .system_path(reader, docfile_directory)

          File.read(resolved_path, encoding: "UTF-8")
        end

  # Validate that we have matching start/end pairs
  validate_plantuml_delimiters(src)
  src
end