metanorma-standoc 1.11.4 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +3 -31
  3. data/.gitignore +23 -0
  4. data/Gemfile +0 -1
  5. data/lib/asciidoctor/standoc/base.rb +2 -145
  6. data/lib/asciidoctor/standoc/blocks.rb +2 -238
  7. data/lib/asciidoctor/standoc/blocks_notes.rb +2 -100
  8. data/lib/asciidoctor/standoc/cleanup.rb +2 -208
  9. data/lib/asciidoctor/standoc/cleanup_amend.rb +2 -53
  10. data/lib/asciidoctor/standoc/cleanup_block.rb +2 -172
  11. data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +2 -212
  12. data/lib/asciidoctor/standoc/cleanup_footnotes.rb +2 -108
  13. data/lib/asciidoctor/standoc/cleanup_image.rb +2 -69
  14. data/lib/asciidoctor/standoc/cleanup_inline.rb +2 -189
  15. data/lib/asciidoctor/standoc/cleanup_maths.rb +2 -221
  16. data/lib/asciidoctor/standoc/cleanup_ref.rb +2 -169
  17. data/lib/asciidoctor/standoc/cleanup_ref_dl.rb +2 -103
  18. data/lib/asciidoctor/standoc/cleanup_reqt.rb +2 -110
  19. data/lib/asciidoctor/standoc/cleanup_section.rb +2 -184
  20. data/lib/asciidoctor/standoc/cleanup_section_names.rb +2 -91
  21. data/lib/asciidoctor/standoc/cleanup_symbols.rb +2 -47
  22. data/lib/asciidoctor/standoc/cleanup_table.rb +2 -67
  23. data/lib/asciidoctor/standoc/cleanup_terms.rb +2 -139
  24. data/lib/asciidoctor/standoc/cleanup_terms_designations.rb +2 -198
  25. data/lib/asciidoctor/standoc/cleanup_text.rb +2 -95
  26. data/lib/asciidoctor/standoc/cleanup_toc.rb +3 -0
  27. data/lib/asciidoctor/standoc/cleanup_xref.rb +2 -106
  28. data/lib/asciidoctor/standoc/converter.rb +2 -123
  29. data/lib/asciidoctor/standoc/datamodel/attributes_table_preprocessor.rb +2 -56
  30. data/lib/asciidoctor/standoc/datamodel/diagram_preprocessor.rb +2 -102
  31. data/lib/asciidoctor/standoc/datamodel/plantuml_renderer.rb +3 -404
  32. data/lib/asciidoctor/standoc/deprecated.rb +5 -0
  33. data/lib/asciidoctor/standoc/front.rb +2 -223
  34. data/lib/asciidoctor/standoc/front_contributor.rb +2 -191
  35. data/lib/asciidoctor/standoc/inline.rb +2 -231
  36. data/lib/asciidoctor/standoc/lists.rb +2 -119
  37. data/lib/asciidoctor/standoc/macros.rb +2 -203
  38. data/lib/asciidoctor/standoc/macros_form.rb +2 -62
  39. data/lib/asciidoctor/standoc/macros_note.rb +2 -44
  40. data/lib/asciidoctor/standoc/macros_plantuml.rb +2 -112
  41. data/lib/asciidoctor/standoc/macros_terms.rb +2 -180
  42. data/lib/asciidoctor/standoc/ref.rb +2 -251
  43. data/lib/asciidoctor/standoc/ref_sect.rb +2 -153
  44. data/lib/asciidoctor/standoc/ref_utility.rb +2 -0
  45. data/lib/asciidoctor/standoc/render.rb +2 -114
  46. data/lib/asciidoctor/standoc/reqt.rb +2 -89
  47. data/lib/asciidoctor/standoc/section.rb +2 -207
  48. data/lib/asciidoctor/standoc/table.rb +2 -84
  49. data/lib/asciidoctor/standoc/term_lookup_cleanup.rb +2 -178
  50. data/lib/asciidoctor/standoc/terms.rb +2 -159
  51. data/lib/asciidoctor/standoc/utils.rb +2 -100
  52. data/lib/asciidoctor/standoc/validate.rb +2 -157
  53. data/lib/asciidoctor/standoc/validate_section.rb +2 -54
  54. data/lib/isodoc/html/htmlstyle.css +25 -19
  55. data/lib/isodoc/html/htmlstyle.scss +7 -2
  56. data/lib/metanorma/standoc/base.rb +163 -0
  57. data/lib/{asciidoctor → metanorma}/standoc/basicdoc.rng +5 -3
  58. data/lib/{asciidoctor → metanorma}/standoc/biblio.rng +7 -5
  59. data/lib/metanorma/standoc/blocks.rb +239 -0
  60. data/lib/metanorma/standoc/blocks_notes.rb +101 -0
  61. data/lib/metanorma/standoc/cleanup.rb +157 -0
  62. data/lib/metanorma/standoc/cleanup_amend.rb +54 -0
  63. data/lib/metanorma/standoc/cleanup_block.rb +173 -0
  64. data/lib/metanorma/standoc/cleanup_boilerplate.rb +213 -0
  65. data/lib/metanorma/standoc/cleanup_footnotes.rb +109 -0
  66. data/lib/metanorma/standoc/cleanup_image.rb +184 -0
  67. data/lib/metanorma/standoc/cleanup_inline.rb +190 -0
  68. data/lib/metanorma/standoc/cleanup_maths.rb +222 -0
  69. data/lib/metanorma/standoc/cleanup_ref.rb +170 -0
  70. data/lib/metanorma/standoc/cleanup_ref_dl.rb +104 -0
  71. data/lib/metanorma/standoc/cleanup_reqt.rb +111 -0
  72. data/lib/metanorma/standoc/cleanup_section.rb +212 -0
  73. data/lib/metanorma/standoc/cleanup_section_names.rb +92 -0
  74. data/lib/metanorma/standoc/cleanup_symbols.rb +48 -0
  75. data/lib/metanorma/standoc/cleanup_table.rb +68 -0
  76. data/lib/metanorma/standoc/cleanup_terms.rb +140 -0
  77. data/lib/metanorma/standoc/cleanup_terms_designations.rb +199 -0
  78. data/lib/metanorma/standoc/cleanup_text.rb +74 -0
  79. data/lib/metanorma/standoc/cleanup_toc.rb +98 -0
  80. data/lib/metanorma/standoc/cleanup_xref.rb +114 -0
  81. data/lib/metanorma/standoc/converter.rb +126 -0
  82. data/lib/metanorma/standoc/datamodel/attributes_table_preprocessor.rb +57 -0
  83. data/lib/metanorma/standoc/datamodel/diagram_preprocessor.rb +103 -0
  84. data/lib/metanorma/standoc/datamodel/plantuml_renderer.rb +409 -0
  85. data/lib/metanorma/standoc/front.rb +224 -0
  86. data/lib/metanorma/standoc/front_contributor.rb +192 -0
  87. data/lib/metanorma/standoc/inline.rb +232 -0
  88. data/lib/{asciidoctor → metanorma}/standoc/isodoc.rng +108 -1
  89. data/lib/metanorma/standoc/lists.rb +120 -0
  90. data/lib/metanorma/standoc/macros.rb +205 -0
  91. data/lib/metanorma/standoc/macros_embed.rb +72 -0
  92. data/lib/metanorma/standoc/macros_form.rb +63 -0
  93. data/lib/metanorma/standoc/macros_note.rb +45 -0
  94. data/lib/metanorma/standoc/macros_plantuml.rb +113 -0
  95. data/lib/metanorma/standoc/macros_terms.rb +194 -0
  96. data/lib/metanorma/standoc/ref.rb +248 -0
  97. data/lib/metanorma/standoc/ref_sect.rb +153 -0
  98. data/lib/{asciidoctor/standoc/ref_date_id.rb → metanorma/standoc/ref_utility.rb} +45 -6
  99. data/lib/metanorma/standoc/render.rb +115 -0
  100. data/lib/metanorma/standoc/reqt.rb +90 -0
  101. data/lib/{asciidoctor → metanorma}/standoc/reqt.rng +0 -0
  102. data/lib/metanorma/standoc/section.rb +209 -0
  103. data/lib/metanorma/standoc/table.rb +85 -0
  104. data/lib/metanorma/standoc/term_lookup_cleanup.rb +181 -0
  105. data/lib/metanorma/standoc/terms.rb +163 -0
  106. data/lib/metanorma/standoc/utils.rb +101 -0
  107. data/lib/metanorma/standoc/validate.rb +163 -0
  108. data/lib/metanorma/standoc/validate_section.rb +55 -0
  109. data/lib/metanorma/standoc/version.rb +1 -1
  110. data/lib/{asciidoctor → metanorma}/standoc/views/datamodel/model_representation.adoc.erb +0 -0
  111. data/lib/{asciidoctor → metanorma}/standoc/views/datamodel/plantuml_representation.adoc.erb +0 -0
  112. data/lib/metanorma-standoc.rb +1 -1
  113. data/metanorma-standoc.gemspec +1 -1
  114. data/spec/assets/a1.adoc +8 -0
  115. data/spec/assets/a2.adoc +8 -0
  116. data/spec/assets/a3.adoc +9 -0
  117. data/spec/assets/a4.adoc +4 -0
  118. data/spec/{asciidoctor → metanorma}/base_spec.rb +453 -409
  119. data/spec/{asciidoctor → metanorma}/blank_spec.rb +1 -1
  120. data/spec/{asciidoctor → metanorma}/blocks_spec.rb +1 -1
  121. data/spec/{asciidoctor → metanorma}/cleanup_blocks_spec.rb +137 -1
  122. data/spec/{asciidoctor → metanorma}/cleanup_sections_spec.rb +1 -1
  123. data/spec/{asciidoctor → metanorma}/cleanup_spec.rb +8 -8
  124. data/spec/{asciidoctor → metanorma}/cleanup_terms_spec.rb +204 -204
  125. data/spec/{asciidoctor → metanorma}/datamodel/attributes_table_preprocessor_spec.rb +1 -1
  126. data/spec/{asciidoctor → metanorma}/datamodel/diagram_preprocessor_spec.rb +1 -1
  127. data/spec/{asciidoctor → metanorma}/inline_spec.rb +1 -1
  128. data/spec/{asciidoctor → metanorma}/isobib_cache_spec.rb +3 -3
  129. data/spec/{asciidoctor → metanorma}/lists_spec.rb +1 -1
  130. data/spec/{asciidoctor → metanorma}/macros_json2text_spec.rb +0 -0
  131. data/spec/{asciidoctor → metanorma}/macros_plantuml_spec.rb +3 -3
  132. data/spec/{asciidoctor → metanorma}/macros_spec.rb +158 -6
  133. data/spec/{asciidoctor → metanorma}/macros_yaml2text_spec.rb +0 -0
  134. data/spec/metanorma/refs_dl_spec.rb +863 -0
  135. data/spec/{asciidoctor → metanorma}/refs_spec.rb +580 -66
  136. data/spec/{asciidoctor → metanorma}/section_spec.rb +42 -17
  137. data/spec/{asciidoctor → metanorma}/table_spec.rb +1 -1
  138. data/spec/{asciidoctor → metanorma}/validate_spec.rb +2 -2
  139. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +46 -46
  140. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +10 -10
  141. data/spec/vcr_cassettes/hide_refs.yml +599 -0
  142. data/spec/vcr_cassettes/isobib_get_123.yml +12 -12
  143. data/spec/vcr_cassettes/isobib_get_123_1.yml +23 -23
  144. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +85 -85
  145. data/spec/vcr_cassettes/isobib_get_123_2001.yml +12 -12
  146. data/spec/vcr_cassettes/isobib_get_124.yml +13 -13
  147. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
  148. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +60 -50
  149. metadata +88 -32
  150. data/spec/asciidoctor/refs_dl_spec.rb +0 -864
@@ -1,124 +1,3 @@
1
- require "asciidoctor"
2
- require "metanorma/util"
3
- require "metanorma/standoc/version"
4
- require "asciidoctor/standoc/base"
5
- require "asciidoctor/standoc/front"
6
- require "asciidoctor/standoc/lists"
7
- require "asciidoctor/standoc/ref"
8
- require "asciidoctor/standoc/inline"
9
- require "asciidoctor/standoc/blocks"
10
- require "asciidoctor/standoc/section"
11
- require "asciidoctor/standoc/table"
12
- require "asciidoctor/standoc/validate"
13
- require "asciidoctor/standoc/utils"
14
- require "asciidoctor/standoc/cleanup"
15
- require "asciidoctor/standoc/reqt"
16
- require_relative "./macros"
1
+ require "asciidoctor/standoc/deprecated"
2
+ require "metanorma/standoc/converter"
17
3
 
18
- module Asciidoctor
19
- module Standoc
20
- # A {Converter} implementation that generates Standoc output, and a document
21
- # schema encapsulation of the document for validation
22
- class Converter
23
- Asciidoctor::Extensions.register do
24
- preprocessor Asciidoctor::Standoc::Datamodel::AttributesTablePreprocessor
25
- preprocessor Asciidoctor::Standoc::Datamodel::DiagramPreprocessor
26
- preprocessor Metanorma::Plugin::Datastruct::Json2TextPreprocessor
27
- preprocessor Metanorma::Plugin::Datastruct::Yaml2TextPreprocessor
28
- preprocessor Metanorma::Plugin::Lutaml::LutamlPreprocessor
29
- preprocessor Metanorma::Plugin::Lutaml::LutamlUmlAttributesTablePreprocessor
30
- preprocessor Metanorma::Plugin::Lutaml::LutamlUmlDatamodelDescriptionPreprocessor
31
- inline_macro Asciidoctor::Standoc::PreferredTermInlineMacro
32
- inline_macro Asciidoctor::Standoc::AltTermInlineMacro
33
- inline_macro Asciidoctor::Standoc::DeprecatedTermInlineMacro
34
- inline_macro Asciidoctor::Standoc::RelatedTermInlineMacro
35
- inline_macro Asciidoctor::Standoc::DomainTermInlineMacro
36
- inline_macro Asciidoctor::Standoc::InheritInlineMacro
37
- inline_macro Asciidoctor::Standoc::HTML5RubyMacro
38
- inline_macro Asciidoctor::Standoc::ConceptInlineMacro
39
- inline_macro Asciidoctor::Standoc::AutonumberInlineMacro
40
- inline_macro Asciidoctor::Standoc::VariantInlineMacro
41
- inline_macro Asciidoctor::Standoc::FootnoteBlockInlineMacro
42
- inline_macro Asciidoctor::Standoc::TermRefInlineMacro
43
- inline_macro Asciidoctor::Standoc::SymbolRefInlineMacro
44
- inline_macro Asciidoctor::Standoc::IndexXrefInlineMacro
45
- inline_macro Asciidoctor::Standoc::IndexRangeInlineMacro
46
- inline_macro Asciidoctor::Standoc::AddMacro
47
- inline_macro Asciidoctor::Standoc::DelMacro
48
- inline_macro Asciidoctor::Standoc::FormInputMacro
49
- inline_macro Asciidoctor::Standoc::FormLabelMacro
50
- inline_macro Asciidoctor::Standoc::FormTextareaMacro
51
- inline_macro Asciidoctor::Standoc::FormSelectMacro
52
- inline_macro Asciidoctor::Standoc::FormOptionMacro
53
- inline_macro Asciidoctor::Standoc::ToCInlineMacro
54
- inline_macro Asciidoctor::Standoc::PassInlineMacro
55
- inline_macro Metanorma::Plugin::Lutaml::LutamlFigureInlineMacro
56
- inline_macro Metanorma::Plugin::Lutaml::LutamlTableInlineMacro
57
- block_macro Metanorma::Plugin::Lutaml::LutamlDiagramBlockMacro
58
- block Asciidoctor::Standoc::ToDoAdmonitionBlock
59
- treeprocessor Asciidoctor::Standoc::ToDoInlineAdmonitionBlock
60
- block Asciidoctor::Standoc::PlantUMLBlockMacro
61
- block Metanorma::Plugin::Lutaml::LutamlDiagramBlock
62
- block Asciidoctor::Standoc::PseudocodeBlockMacro
63
- end
64
-
65
- include ::Asciidoctor::Converter
66
- include ::Asciidoctor::Writer
67
-
68
- include ::Asciidoctor::Standoc::Base
69
- include ::Asciidoctor::Standoc::Front
70
- include ::Asciidoctor::Standoc::Lists
71
- include ::Asciidoctor::Standoc::Refs
72
- include ::Asciidoctor::Standoc::Inline
73
- include ::Asciidoctor::Standoc::Blocks
74
- include ::Asciidoctor::Standoc::Section
75
- include ::Asciidoctor::Standoc::Table
76
- include ::Asciidoctor::Standoc::Utils
77
- include ::Asciidoctor::Standoc::Cleanup
78
- include ::Asciidoctor::Standoc::Validate
79
-
80
- register_for "standoc"
81
-
82
- $xreftext = {}
83
-
84
- def initialize(backend, opts)
85
- super
86
- basebackend "html"
87
- outfilesuffix ".xml"
88
- @libdir = File.dirname(self.class::_file || __FILE__)
89
- end
90
-
91
- class << self
92
- attr_accessor :_file
93
- end
94
-
95
- def self.inherited(konv) # rubocop:disable Lint/MissingSuper
96
- konv._file = caller_locations(1..1).first.absolute_path
97
- end
98
-
99
- # path to isodoc assets in child gems
100
- def html_doc_path(file)
101
- File.join(@libdir, "../../isodoc/html", file)
102
- end
103
-
104
- def content(node)
105
- node.content
106
- end
107
-
108
- def skip(node, name = nil)
109
- name = name || node.node_name
110
- w = "converter missing for #{name} node in Metanorma backend"
111
- @log.add("AsciiDoc Input", node, w)
112
- nil
113
- end
114
-
115
- alias_method :embedded, :content
116
- alias_method :verse, :quote
117
- alias_method :audio, :skip
118
- alias_method :video, :skip
119
- alias_method :inline_button, :skip
120
- alias_method :inline_kbd, :skip
121
- alias_method :inline_menu, :skip
122
- end
123
- end
124
- end
@@ -1,57 +1,3 @@
1
- # frozen_string_literal: true
1
+ require "asciidoctor/standoc/deprecated"
2
+ require "metanorma/standoc/datamodel/attributes_table_preprocessor"
2
3
 
3
- require "erb"
4
-
5
- module Asciidoctor
6
- module Standoc
7
- module Datamodel
8
- class AttributesTablePreprocessor < Asciidoctor::Extensions::Preprocessor
9
- BLOCK_START_REGEXP = /\{(.+?)\.\*,(.+),(.+)\}/
10
- BLOCK_END_REGEXP = /\A\{[A-Z]+\}\z/
11
- MARCO_REGEXP = /\[datamodel_attributes_table,([^,]+),?(.+)?\]/
12
- TEMPLATES_PATH = File.expand_path("../views/datamodel", __dir__).freeze
13
- # search document for block `datamodel_attributes_table`
14
- # read include derectives that goes after that in block and transform
15
- # into yaml2text blocks
16
- def process(document, reader)
17
- input_lines = reader.readlines.to_enum
18
- Reader.new(processed_lines(document, input_lines))
19
- end
20
-
21
- private
22
-
23
- def processed_lines(document, input_lines)
24
- input_lines.each_with_object([]) do |line, result|
25
- if match = line.match(MARCO_REGEXP)
26
- yaml_path = match[1]
27
- result.push(*parse_marco(yaml_path, document))
28
- else
29
- result.push(line)
30
- end
31
- end
32
- end
33
-
34
- def parse_marco(yaml_path, document)
35
- model_representation(yaml_relative_path(yaml_path, document))
36
- .split("\n")
37
- end
38
-
39
- def model_representation(model_path)
40
- template = File.read(File.join(
41
- TEMPLATES_PATH,
42
- "model_representation.adoc.erb",
43
- ))
44
- file_name = File.basename(model_path).gsub(/\.ya?ml/, "")
45
- ERB
46
- .new(template)
47
- .result(binding)
48
- end
49
-
50
- def yaml_relative_path(file_path, document)
51
- directory = File.dirname(document.attributes["docfile"] || ".")
52
- document.path_resolver.system_path(file_path, directory)
53
- end
54
- end
55
- end
56
- end
57
- end
@@ -1,103 +1,3 @@
1
- # frozen_string_literal: true
1
+ require "asciidoctor/standoc/deprecated"
2
+ require "metanorma/standoc/datamodel/diagram_preprocessor"
2
3
 
3
- require "erb"
4
- require "asciidoctor/standoc/datamodel/plantuml_renderer"
5
-
6
- module Asciidoctor
7
- module Standoc
8
- module Datamodel
9
- class DiagramPreprocessor < Asciidoctor::Extensions::Preprocessor
10
- BLOCK_START_REGEXP = /\{(.+?)\.\*,(.+),(.+)\}/.freeze
11
- BLOCK_END_REGEXP = /\A\{[A-Z]+\}\z/.freeze
12
- MARCO_REGEXP = /\[datamodel_diagram,([^,]+),?(.+)?\]/.freeze
13
- TEMPLATES_PATH = File.expand_path("../views/datamodel", __dir__).freeze
14
- # search document for block `datamodel_diagram`
15
- # read include derectives that goes after that in block and transform
16
- # into plantuml block
17
- def process(document, reader)
18
- input_lines = reader.readlines.to_enum
19
- Reader.new(processed_lines(document, input_lines))
20
- end
21
-
22
- private
23
-
24
- def processed_lines(document, input_lines)
25
- input_lines.each_with_object([]) do |line, result|
26
- if match = line.match(MARCO_REGEXP)
27
- result
28
- .push(*parse_datamodel_marco(match[1], match[2], document))
29
- else
30
- result.push(line)
31
- end
32
- end
33
- end
34
-
35
- def parse_datamodel_marco(yaml_path, include_path, document)
36
- include_path ||= File.join(File.dirname(yaml_path), "..", "models")
37
- include_path = yaml_relative_path(include_path, document)
38
- yaml_relative_to_doc_path = yaml_relative_path(yaml_path, document)
39
- view_hash = YAML.safe_load(File.read(yaml_relative_to_doc_path))
40
- plantuml_representations(view_hash,
41
- yaml_relative_to_doc_path,
42
- include_path)
43
- end
44
-
45
- def yaml_relative_path(file_path, document)
46
- docfile = document.attributes["docfile"] || "."
47
- docfile_directory = File.dirname(docfile)
48
- document.path_resolver.system_path(file_path, docfile_directory)
49
- end
50
-
51
- def import_format(include_path, import_name, values)
52
- include_content = File.read(File.join(
53
- include_path,
54
- "#{import_name}.yml",
55
- ))
56
- content = YAML.safe_load(include_content)
57
- if values
58
- content["skipSection"] = values["skipSection"]
59
- end
60
- content
61
- end
62
-
63
- def format_import_directives(imports, include_path)
64
- imports
65
- .each_with_object({}) do |(import_name, values), res|
66
- full_model_name = import_name.split("/").join
67
- content = import_format(include_path, import_name, values)
68
- res[content["name"] || full_model_name] = content
69
- end.compact
70
- end
71
-
72
- def prepare_view_hash(view_hash, all_imports)
73
- view_hash.merge!(
74
- "classes" => model_type(all_imports, "class"),
75
- "enums" => model_type(all_imports, "enum"),
76
- "relations" => view_hash["relations"] || [],
77
- "fidelity" => (view_hash["fidelity"] || {})
78
- .merge!("classes" => model_type(all_imports,
79
- "class")),
80
- )
81
- end
82
-
83
- def model_type(imports, type)
84
- imports
85
- .select do |_name, elem|
86
- elem["modelType"] == type
87
- end
88
- end
89
-
90
- def plantuml_representations(view_hash, view_path, include_path)
91
- yaml_directory = File.dirname(view_path)
92
- all_imports = format_import_directives(view_hash["imports"],
93
- include_path)
94
- prepare_view_hash(view_hash, all_imports)
95
- Asciidoctor::Datamodel::PlantumlRenderer
96
- .new(view_hash, File.join(yaml_directory, ".."))
97
- .render
98
- .split("\n")
99
- end
100
- end
101
- end
102
- end
103
- end
@@ -1,409 +1,8 @@
1
- # frozen_string_literal: true
2
-
3
- require "erb"
1
+ require "asciidoctor/standoc/deprecated"
2
+ require "metanorma/standoc/datamodel/plantuml_renderer"
4
3
 
5
4
  module Asciidoctor
6
5
  module Datamodel
7
- class PlantumlRenderer
8
- TEMPLATES_PATH = File.expand_path("../views/datamodel", __dir__).freeze
9
-
10
- attr_reader :yml, :plantuml_path
11
-
12
- def initialize(yml, plantuml_path)
13
- @yml = yml
14
- @plantuml_path = plantuml_path
15
- end
16
-
17
- def join_as_plantuml(*ary)
18
- ary.compact.join("\n").sub(/\s+\Z/, "")
19
- end
20
-
21
- def render
22
- ERB.new(
23
- File.read(
24
- File.join(TEMPLATES_PATH, "plantuml_representation.adoc.erb")
25
- )
26
- ).result(binding)
27
- end
28
-
29
- def diagram_caption
30
- yml["caption"]
31
- end
32
-
33
- def imports_yml_to_plantuml
34
- return if empty?(yml, "imports")
35
-
36
- <<~TEMPLATE
37
- '******* IMPORTS ******************************************************
38
- !include #{plantuml_path}/style.uml.inc
39
- TEMPLATE
40
- end
41
-
42
- def class_defs_yml_to_plantuml
43
- return if empty?(yml, "classes") && empty?(yml, "enums")
44
-
45
- <<~TEMPLATE
46
- '******* CLASS DEFINITIONS ********************************************
47
- #{join_as_plantuml(
48
- classes_to_classes_plantuml(yml['classes']),
49
- enums_to_enums_plantuml(yml['enums'])
50
- )}
51
- TEMPLATE
52
- end
53
-
54
- def class_groups_yml_to_plantuml
55
- return if empty?(yml, "groups")
56
-
57
- <<~TEMPLATE
58
- '******* CLASS GROUPS *************************************************
59
- #{join_as_plantuml(
60
- groups_to_plantuml(yml['groups'])
61
- )}
62
- TEMPLATE
63
- end
64
-
65
- def class_relations_yml_to_plantuml
66
- return if empty?(yml, "classes") && empty?(yml, "relations")
67
-
68
- <<~TEMPLATE
69
- '******* CLASS RELATIONS **********************************************
70
- #{join_as_plantuml(
71
- classes_to_relations_plantuml(yml['classes']),
72
- relations_to_plantuml(nil, yml['relations'])
73
- )}
74
- TEMPLATE
75
- end
76
-
77
- def diagram_options_yml_to_plantuml
78
- return if empty?(yml, "diagram_options")
79
-
80
- <<~TEMPLATE
81
- '******* DIAGRAM SPECIFIC CONFIG **************************************
82
- #{join_as_plantuml(
83
- diagram_options_to_plantuml(yml['diagram_options'])
84
- )}
85
- TEMPLATE
86
- end
87
-
88
- def bottom_yml_to_plantuml
89
- return if empty?(yml, "bottom")
90
-
91
- <<~TEMPLATE
92
- '******* BOTTOM OVERRIDE CONFIG **************************************
93
- #{join_as_plantuml(bottom_to_plantuml(yml['bottom']))}
94
- TEMPLATE
95
- end
96
-
97
- def fidelity_yml_to_plantuml
98
- return if empty?(yml, "fidelity")
99
-
100
- <<~TEMPLATE
101
- '******* FIDELITY *****************************************************
102
- #{join_as_plantuml(fidelity_to_plantuml(yml['fidelity']))}
103
- TEMPLATE
104
- end
105
-
106
- def classes_to_classes_plantuml(classes)
107
- classes ||= {}
108
-
109
- return if classes.empty?
110
-
111
- classes.map do |(class_name, class_hash)|
112
- class_to_plantuml(class_name, class_hash)
113
- end.join("\n")
114
- end
115
-
116
- def class_to_plantuml(class_name, class_hash)
117
- return unless class_name
118
-
119
- class_hash ||= {}
120
-
121
- <<~TEMPLATE
122
- class #{class_name}#{model_stereotype_to_plantuml(class_hash['type'])} {
123
- #{join_as_plantuml(
124
- attributes_to_plantuml(class_hash['attributes']),
125
- constraints_to_plantuml(class_hash['constraints'])
126
- )}
127
- }
128
- TEMPLATE
129
- end
130
-
131
- def attributes_to_plantuml(attributes)
132
- return unless attributes
133
-
134
- attributes.map do |(attr_name, attr_hash)|
135
- attribute_to_plantuml(attr_name, attr_hash)
136
- end.join("").sub(/\n\Z/, "")
137
- end
138
-
139
- def attribute_to_plantuml(attr_name, attr_hash)
140
- <<~TEMPLATE
141
- +#{attr_name}: #{attr_hash['type']}#{attribute_cardinality_plantuml(attr_hash['cardinality'])}
142
- TEMPLATE
143
- end
144
-
145
- def attribute_cardinality_plantuml(cardinality, with_bracket = true)
146
- return "" if cardinality.nil? ||
147
- (cardinality["min"] == cardinality["max"] &&
148
- cardinality["min"] == 1)
149
-
150
- card = "#{cardinality['min']}..#{cardinality['max']}"
151
- return card unless with_bracket
152
-
153
- "[#{card}]"
154
- end
155
-
156
- def constraints_to_plantuml(constraints)
157
- constraints ||= []
158
-
159
- return if constraints.empty?
160
-
161
- constraints_output = constraints.map do |constraint|
162
- " {#{constraint}}"
163
- end
164
-
165
- <<~TEMPLATE
166
- __ constraints __
167
- #{join_as_plantuml(
168
- *constraints_output
169
- )}
170
- TEMPLATE
171
- end
172
-
173
- def classes_to_relations_plantuml(classes)
174
- output_ary = classes.map do |(class_name, class_hash)|
175
- class_hash ||= {}
176
- relations = class_hash["relations"]
177
- relations_to_plantuml(class_name, relations)
178
- end
179
-
180
- join_as_plantuml(*output_ary)
181
- end
182
-
183
- def relations_to_plantuml(class_name, relations)
184
- return unless relations
185
-
186
- output_ary = relations.map do |relation|
187
- source = class_name || relation["source"]
188
- relation_to_plantuml(source,
189
- relation["target"],
190
- relation)
191
- end
192
-
193
- join_as_plantuml(*output_ary)
194
- end
195
-
196
- def relation_arrow(relationship, relation)
197
- [
198
- relationship_type_to_plantuml("source",
199
- relationship["source"]["type"]),
200
- (relation["direction"]).to_s,
201
- relationship_type_to_plantuml("target",
202
- relationship["target"]["type"]),
203
- ].compact.join("-")
204
- end
205
-
206
- def relation_label(action)
207
- return "" unless action
208
-
209
- case action["direction"]
210
- when "source"
211
- " : < #{action['verb']}"
212
- when "target"
213
- " : #{action['verb']} >"
214
- else
215
- ""
216
- end
217
- end
218
-
219
- def source_arrow_end(source, relationship)
220
- source_attribute = relationship_cardinality_to_plantuml(
221
- relationship["source"]["attribute"]
222
- )
223
- [source, source_attribute].join(" ")
224
- end
225
-
226
- def target_arrow_end(target, relationship, action)
227
- target_attribute = relationship_cardinality_to_plantuml(
228
- relationship["target"]["attribute"]
229
- )
230
- [
231
- [target_attribute, target].join(" "),
232
- relation_label(action),
233
- ].join
234
- end
235
-
236
- def relation_association(source, target, association)
237
- return unless association
238
-
239
- "\n(#{source}, #{target}) . #{association}"
240
- end
241
-
242
- def relation_to_plantuml(source, target, relation)
243
- relationship = relation["relationship"] || {}
244
- relationship["source"] ||= {}
245
- relationship["target"] ||= {}
246
- relation_output_lines(source, target, relation, relationship)
247
- end
248
-
249
- def relation_output_lines(source, target, relation, relationship)
250
- output_lines = [
251
- source_arrow_end(source, relationship),
252
- relation_arrow(relationship, relation),
253
- target_arrow_end(target, relationship, relation["action"]),
254
- relation_association(source, target, relationship["association"]),
255
- ].join(" ")
256
-
257
- join_as_plantuml(*output_lines)
258
- end
259
-
260
- def relationship_type_to_plantuml(relation_end, relationship_type)
261
- is_source = (relation_end == "source")
262
- mappings = {
263
- "direct" => is_source ? "<" : ">",
264
- "inheritance" => is_source ? "<|" : "|>",
265
- "composition" => "*",
266
- "aggregation" => "o",
267
- }
268
- mappings.fetch(relationship_type, "")
269
- end
270
-
271
- def relationship_cardinality_to_plantuml(attribute)
272
- attribute_name = (attribute || {}).keys.first
273
-
274
- return unless attribute_name
275
-
276
- attribute_hash = attribute[attribute_name] || {}
277
- card = attribute_cardinality(attribute_hash["cardinality"])
278
- "\"+#{attribute_name}#{card}\""
279
- end
280
-
281
- def attribute_cardinality(attribute_cardinality)
282
- cardinality = ""
283
- if attribute_cardinality
284
- cardinality = attribute_cardinality_plantuml(
285
- attribute_cardinality,
286
- false
287
- )
288
- cardinality = " #{cardinality}"
289
- end
290
- cardinality
291
- end
292
-
293
- def enums_to_enums_plantuml(enums)
294
- enums ||= {}
295
-
296
- enums.map do |(enum_name, enum_hash)|
297
- enum_to_plantuml(enum_name, enum_hash)
298
- end.join("\n\n")
299
- end
300
-
301
- def enum_to_plantuml(enum_name, enum_hash)
302
- enum_hash ||= {}
303
-
304
- <<~TEMPLATE
305
- enum #{enum_name}#{model_stereotype_to_plantuml(enum_hash['type'])} {
306
- #{join_as_plantuml(enum_values_to_plantuml(enum_hash['values']))}
307
- }
308
- TEMPLATE
309
- end
310
-
311
- def model_stereotype_to_plantuml(model_stereotype)
312
- return "" unless model_stereotype
313
-
314
- " <<#{model_stereotype}>>"
315
- end
316
-
317
- def enum_values_to_plantuml(enum_values)
318
- output_ary = enum_values.map do |(enum_value, _enum_value_hash)|
319
- " #{enum_value}"
320
- end
321
-
322
- join_as_plantuml(*output_ary)
323
- end
324
-
325
- def groups_to_plantuml(groups)
326
- groups ||= []
327
- return if groups.empty?
328
-
329
- groups.reduce("") do |output, group|
330
- output += "\ntogether {\n"
331
- group.each do |class_name|
332
- output += "\nclass #{class_name}\n"
333
- end
334
- output += "\n}\n"
335
- output
336
- end
337
- end
338
-
339
- def diagram_options_to_plantuml(diagram_options)
340
- diagram_options ||= []
341
- return if diagram_options.empty?
342
-
343
- "#{diagram_options.join("\n")}\n"
344
- end
345
-
346
- def bottom_to_plantuml(bottom)
347
- bottom ||= []
348
- return if bottom.empty?
349
-
350
- "#{bottom.join("\n")}\n"
351
- end
352
-
353
- def format_hidden_class(accum, fidelity_classes, class_hash)
354
- return accum if class_hash["relations"].nil?
355
-
356
- class_hash["relations"].each_with_object(accum) do |relation, acc|
357
- format_source_target_relation(relation, fidelity_classes, acc)
358
- format_association_relation(relation, fidelity_classes, acc)
359
- end
360
- end
361
-
362
- def format_source_target_relation(relation, fidelity_classes, acc)
363
- %w[source target].each do |type|
364
- next unless relation[type] && !fidelity_classes.key?(relation[type])
365
-
366
- acc.merge!(relation[type] => true)
367
- end
368
- end
369
-
370
- def format_association_relation(relation, fidelity_classes, acc)
371
- return unless relation["relationship"] &&
372
- relation["relationship"]["association"]
373
-
374
- association = relation["relationship"]["association"]
375
- return unless association && !fidelity_classes.key?(association)
376
-
377
- acc.merge!(association => true)
378
- end
379
-
380
- def hide_other_classes(fidelity)
381
- return "" if fidelity.nil? || fidelity["classes"].nil?
382
-
383
- output = ""
384
- hidden_classes = fidelity["classes"]
385
- .reduce({}) do |acc, (_class_name, class_hash)|
386
- format_hidden_class(acc, fidelity["classes"], class_hash)
387
- end
388
-
389
- hidden_classes.each_key do |hidden_class_name|
390
- output += "\nhide #{hidden_class_name}\n"
391
- end
392
- output
393
- end
394
-
395
- def fidelity_to_plantuml(fidelity)
396
- return "" if fidelity.nil?
397
-
398
- output = ""
399
- output += hide_other_classes(fidelity) if fidelity["hideOtherClasses"]
400
- output += "\nhide members\n" if fidelity["hideMembers"]
401
- output
402
- end
403
-
404
- def empty?(yml, prop)
405
- yml[prop].nil? || yml[prop].length.zero?
406
- end
407
- end
6
+ PlantumlRenderer = Metanorma::Datamodel::PlantumlRenderer
408
7
  end
409
8
  end