stepmod-utils 0.3.22 → 0.3.24

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,111 @@
1
+ module Stepmod
2
+ module Utils
3
+ class ExpressBibdata
4
+ DOCNUMBER = 10303
5
+
6
+ attr_accessor *%w(
7
+ type doctype part title_en version pub_year pubid published_info number
8
+ )
9
+
10
+ def initialize(schema:)
11
+ # module, resource, application_protocol, business_object_model
12
+ # @type = document.name
13
+
14
+ # raise "UnknownFileError" unless %w(module resource
15
+ # application_protocol business_object_model).include?(@type)
16
+
17
+ @published_info = schema.find("__published_in")&.remarks&.first
18
+ @number = schema.find("__identifier")&.remarks&.first&.split("N")&.last
19
+ @schema = schema
20
+
21
+ if !published_info.nil?
22
+ @pubid = Pubid::Iso::Identifier.parse(published_info)
23
+
24
+ @part = pubid.part
25
+ @version = pubid.edition
26
+ @pub_year = pubid.year
27
+ elsif !schema.version.nil?
28
+ @part = schema.version.items.find { |i| i.name == "part" }.value
29
+ @version = schema.version.items.find { |i| i.name == "part" }.value
30
+ @pub_year = schema.version.items.find { |i| i.name == "part" }.value
31
+ else
32
+ raise "PublishedInfoNotFound"
33
+ end
34
+
35
+ @doctype = schema.find("__status")&.remarks&.first
36
+ self
37
+ end
38
+
39
+ def title_en
40
+ @title_en ||= @schema.find("__title")
41
+ .remarks
42
+ .first
43
+ .gsub("_", " ")
44
+ .capitalize
45
+ .gsub("2d", "2D")
46
+ .gsub("3d", "3D")
47
+ end
48
+
49
+ def docid
50
+ no_date = case doctype
51
+ when "IS"
52
+ "ISO #{DOCNUMBER}-#{part}"
53
+ when "WD"
54
+ "ISO/WD #{DOCNUMBER}-#{part}"
55
+ when "CD"
56
+ "ISO/CD #{DOCNUMBER}-#{part}"
57
+ when "DIS"
58
+ "ISO/DIS #{DOCNUMBER}-#{part}"
59
+ when "FDIS"
60
+ "ISO/FDIS #{DOCNUMBER}-#{part}"
61
+ when "TS"
62
+ "ISO/TS #{DOCNUMBER}-#{part}"
63
+ when "CD-TS"
64
+ "ISO/CD TS #{DOCNUMBER}-#{part}"
65
+ else
66
+ "UNKNOWN DOCTYPE: (#{doctype})"
67
+ end
68
+
69
+ if pub_year
70
+ "#{no_date}:#{pub_year}"
71
+ else
72
+ no_date
73
+ end
74
+ end
75
+
76
+ def part_title
77
+ case part
78
+ when [200..299]
79
+ "Application protocol: #{title_en}"
80
+ when [300..399]
81
+ "Abstract test suite: #{title_en}"
82
+ when [400..499]
83
+ "Application module: #{title_en}"
84
+ when [500..599]
85
+ "Application interpreted construct: #{title_en}"
86
+ when [1000..1799]
87
+ "Application module: #{title_en}"
88
+ else
89
+ title_en
90
+ end
91
+ end
92
+
93
+ def full_title
94
+ "Industrial automation systems and integration -- Product data" \
95
+ " representation and exchange -- Part #{part}: #{part_title}"
96
+ end
97
+
98
+ def anchor
99
+ docid.gsub("/", "-").gsub(" ", "_").gsub(":", "_")
100
+ end
101
+
102
+ def to_mn_adoc
103
+ if title_en
104
+ "* [[[#{anchor},#{docid}]]], _#{full_title}_"
105
+ else
106
+ "* [[[#{anchor},#{docid}]]]"
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -15,6 +15,7 @@ require "stepmod/utils/converters/ext_descriptions"
15
15
  require "stepmod/utils/converters/head"
16
16
  require "stepmod/utils/converters/hr"
17
17
  require "stepmod/utils/converters/ignore"
18
+ require "stepmod/utils/converters/module_ref_express_description"
18
19
  require "stepmod/utils/converters/note"
19
20
  require "stepmod/utils/converters/p"
20
21
  require "stepmod/utils/converters/pass_through"
@@ -15,6 +15,7 @@ require "stepmod/utils/converters/dt"
15
15
  require "stepmod/utils/converters/drop"
16
16
  require "stepmod/utils/converters/example"
17
17
  require "stepmod/utils/converters/express_g"
18
+ require "stepmod/utils/converters/figure"
18
19
  require "stepmod/utils/converters/fund_cons"
19
20
  require "stepmod/utils/converters/eqn"
20
21
  require "stepmod/utils/converters/head"
@@ -25,6 +26,7 @@ require "stepmod/utils/converters/note"
25
26
  require "stepmod/utils/converters/ol"
26
27
  require "stepmod/utils/converters/p"
27
28
  require "stepmod/utils/converters/pass_through"
29
+ require "stepmod/utils/converters/module_ref"
28
30
  require "stepmod/utils/converters/q"
29
31
  require "stepmod/utils/converters/resource"
30
32
  require "stepmod/utils/converters/schema_diag"
@@ -36,7 +38,6 @@ require "stepmod/utils/converters/table"
36
38
  require "stepmod/utils/converters/text"
37
39
  require "stepmod/utils/cleaner"
38
40
 
39
- require "reverse_adoc/converters/figure"
40
41
  require "reverse_adoc/converters/img"
41
42
  require "reverse_adoc/converters/li"
42
43
  require "reverse_adoc/converters/tr"
@@ -17,6 +17,7 @@ require "stepmod/utils/converters/term"
17
17
  require "stepmod/utils/converters/synonym"
18
18
  require "stepmod/utils/converters/uof"
19
19
  require "stepmod/utils/converters/figure"
20
+ require "stepmod/utils/converters/table"
20
21
  require "stepmod/utils/cleaner"
21
22
 
22
23
  require "reverse_adoc/converters/a"
@@ -3,6 +3,11 @@ require "stepmod/utils/smrl_description_converter"
3
3
  require "stepmod/utils/smrl_resource_converter"
4
4
  require "stepmod/utils/converters/express_note"
5
5
  require "stepmod/utils/converters/express_example"
6
+ require "stepmod/utils/converters/express_figure"
7
+ require "stepmod/utils/converters/express_table"
8
+ require "expressir"
9
+ require "expressir/express/parser"
10
+ require "pubid-iso"
6
11
 
7
12
  module Stepmod
8
13
  module Utils
@@ -15,26 +20,37 @@ module Stepmod
15
20
  @express_file = express_file
16
21
  @resource_docs_cache_file = resource_docs_cache_file
17
22
  @stepmod_dir = stepmod_dir || Dir.pwd
23
+ @added_bibdata = {}
24
+
25
+ @schema_name = Expressir::Express::Parser.from_file(express_file)
26
+ .schemas
27
+ .first
28
+ .id
18
29
  end
19
30
 
20
31
  def call
21
32
  match = File.basename(express_file).match('^(arm|mim|bom)\.exp$')
22
33
  descriptions_base = match ? "#{match.captures[0]}_descriptions.xml" : "descriptions.xml"
34
+
23
35
  descriptions_file = File.join(File.dirname(express_file),
24
36
  descriptions_base)
37
+
25
38
  output_express = File.read(express_file)
26
- resource_docs_cache = JSON.parse(File.read(resource_docs_cache_file))
39
+ converted_description = ""
40
+ base_linked = ""
27
41
 
28
42
  if File.exists?(descriptions_file)
29
43
  descriptions = Nokogiri::XML(File.read(descriptions_file)).root
30
44
  added_resource_descriptions = {}
45
+
31
46
  descriptions.xpath("ext_description").each do |description|
32
47
  # Add base resource from linked path if exists, eg "language_schema.language.wr:WR1" -> "language_schema"
33
48
  base_linked = description["linkend"].to_s.split(".").first
49
+
34
50
  if added_resource_descriptions[base_linked].nil?
35
51
  base_reource_doc_dir = resource_docs_cache[description["linkend"].to_s.split(".").first]
36
52
  if base_reource_doc_dir
37
- output_express << convert_from_resource_file(
53
+ converted_description << convert_from_resource_file(
38
54
  base_reource_doc_dir, stepmod_dir, base_linked, descriptions_file
39
55
  )
40
56
  end
@@ -45,7 +61,7 @@ module Stepmod
45
61
  # when a schema description is available from resource.xml and also descriptions.xml, the description from resource.xml is only used.
46
62
  # https://github.com/metanorma/annotated-express/issues/32#issuecomment-792609078
47
63
  if description.text.strip.length.positive? && resource_docs_dir.nil?
48
- output_express << convert_from_description_text(
64
+ converted_description << convert_from_description_text(
49
65
  descriptions_file, description
50
66
  )
51
67
  end
@@ -58,26 +74,70 @@ module Stepmod
58
74
  end
59
75
  end
60
76
 
61
- output_express
77
+ bib_file_name = extract_bib_file_name(match, resource_docs_cache[@schema_name || ""])
78
+ bib_file = if match
79
+ File.join(File.dirname(express_file), bib_file_name)
80
+ else
81
+ resource_docs_file_path(stepmod_dir, bib_file_name)
82
+ end
83
+
84
+ output_express << if bib_file && File.exists?(bib_file)
85
+ prepend_bibdata(
86
+ converted_description || "",
87
+ # bib_file will not be present for resouces
88
+ # that are not in resource_docs cache.
89
+ # e.g hierarchy_schema
90
+ bib_file,
91
+ @schema_name,
92
+ match,
93
+ )
94
+ else
95
+ converted_description
96
+ end
97
+
98
+ sanitize(output_express)
99
+ rescue StandardError => e
100
+ puts "[ERROR]!!! #{e.message}"
101
+ puts e.backtrace
62
102
  end
63
103
 
64
104
  private
65
105
 
106
+ def sanitize(file_content)
107
+ file_content.gsub("(*)", "(`*`)")
108
+ end
109
+
110
+ def resource_docs_cache
111
+ @resource_docs_cache ||= JSON.parse(File.read(resource_docs_cache_file))
112
+ end
113
+
66
114
  def convert_from_description_text(descriptions_file, description)
67
115
  Dir.chdir(File.dirname(descriptions_file)) do
68
116
  wrapper = "<ext_descriptions>#{description}</ext_descriptions>"
69
117
  notes = description.xpath("note")
70
118
  examples = description.xpath("example")
119
+ figures = description.xpath("figure")
120
+ tables = description.xpath("table")
71
121
 
72
122
  converted_description = <<~DESCRIPTION
73
123
 
74
124
  #{Stepmod::Utils::SmrlDescriptionConverter.convert(wrapper, no_notes_examples: true)}
75
125
  DESCRIPTION
76
126
 
77
- converted_examples = examples.map do |example|
78
- Stepmod::Utils::Converters::ExpressExample
127
+ if description["linkend"].nil?
128
+ raise StandardError.new("[stepmod-file-annotator] ERROR: no linkend for #{descriptions_file}!")
129
+ end
130
+
131
+ converted_figures = figures.map do |figure|
132
+ Stepmod::Utils::Converters::ExpressFigure
79
133
  .new
80
- .convert(example, schema_and_entity: description["linkend"])
134
+ .convert(figure, schema_and_entity: description["linkend"])
135
+ end.join
136
+
137
+ converted_tables = tables.map do |table|
138
+ Stepmod::Utils::Converters::ExpressTable
139
+ .new
140
+ .convert(table, schema_and_entity: description["linkend"])
81
141
  end.join
82
142
 
83
143
  converted_notes = notes.map do |note|
@@ -86,22 +146,186 @@ module Stepmod
86
146
  .convert(note, schema_and_entity: description["linkend"])
87
147
  end.join
88
148
 
89
- "#{converted_description}#{converted_examples}#{converted_notes}"
149
+ converted_examples = examples.map do |example|
150
+ Stepmod::Utils::Converters::ExpressExample
151
+ .new
152
+ .convert(example, schema_and_entity: description["linkend"])
153
+ end.join
154
+
155
+ [
156
+ converted_description,
157
+ converted_figures,
158
+ converted_tables,
159
+ converted_examples,
160
+ converted_notes,
161
+ ].join("")
162
+ end
163
+ end
164
+
165
+ def prepend_bibdata(description, bibdata_file, schema_and_entity, match)
166
+ bib = Nokogiri::XML(File.read(bibdata_file)).root
167
+ bibdata = extract_bib_data(match, bib, schema_and_entity)
168
+
169
+ return description.to_s if @added_bibdata[schema_and_entity]
170
+
171
+ published_in = <<~PUBLISHED_IN
172
+
173
+ (*"#{schema_and_entity}.__published_in"
174
+ #{bibdata[:identifier]}
175
+ *)
176
+ PUBLISHED_IN
177
+
178
+ identifier = <<~IDENTIFIER if bibdata[:number]
179
+ (*"#{schema_and_entity}.__identifier"
180
+ ISO/TC 184/SC 4/WG 12 N#{bibdata[:number]}
181
+ *)
182
+ IDENTIFIER
183
+
184
+ supersedes = <<~SUPERSEDES if bibdata[:supersedes_concept]
185
+ (*"#{schema_and_entity}.__supersedes"
186
+ ISO/TC 184/SC 4/WG 12 N#{bibdata[:supersedes_concept]}
187
+ *)
188
+ SUPERSEDES
189
+
190
+ status = <<~STATUS if bibdata[:status]
191
+ (*"#{schema_and_entity}.__status"
192
+ #{bibdata[:status]}
193
+ *)
194
+ STATUS
195
+
196
+ title = <<~TITLE if bibdata[:title]
197
+ (*"#{schema_and_entity}.__title"
198
+ #{bibdata[:title]}
199
+ *)
200
+ TITLE
201
+
202
+ document = <<~DOCUMENT if bibdata_file
203
+ (*"#{schema_and_entity}.__schema_file"
204
+ #{Pathname(bibdata_file).relative_path_from(@stepmod_dir)}
205
+ *)
206
+ DOCUMENT
207
+
208
+ @added_bibdata[schema_and_entity] = true
209
+
210
+ [
211
+ published_in,
212
+ identifier,
213
+ supersedes,
214
+ status,
215
+ title,
216
+ description,
217
+ document,
218
+ ].compact.join("\n")
219
+ end
220
+
221
+ def module?(match)
222
+ match && %w[arm mim].include?(match.captures[0])
223
+ end
224
+
225
+ def bom?(match)
226
+ match && %w[bom].include?(match.captures[0])
227
+ end
228
+
229
+ def extract_bib_file_name(match, default_file_name = "")
230
+ return default_file_name || "" unless match
231
+
232
+ if %w[arm mim].include?(match.captures[0])
233
+ "module.xml"
234
+ else
235
+ "business_object_model.xml"
236
+ end
237
+ end
238
+
239
+ def extract_bib_data(match, bib, schema_and_entity)
240
+ return resource_bib_data(bib, schema_and_entity) unless match
241
+
242
+ if module?(match)
243
+ module_bib_data(bib, match.captures[0])
244
+ elsif bom?(match)
245
+ bom_bib_data(bib)
90
246
  end
91
247
  end
92
248
 
249
+ def identifier(bib)
250
+ part = bib.attributes["part"].value
251
+ year = bib.attributes["publication.year"].value
252
+
253
+ # year="tbd" in data/modules/geometric_tolerance/module.xml and
254
+ # probabaly in some other places as well
255
+ year = "" if year == "tbd"
256
+ edition = bib.attributes["version"].value
257
+
258
+ pubid = Pubid::Iso::Identifier.new(
259
+ publisher: "ISO",
260
+ number: 10303,
261
+ )
262
+
263
+ pubid.part = part if part && !part.empty?
264
+ pubid.year = year.split("-").first if year && !year.empty?
265
+ pubid.edition = edition if edition && !edition.empty?
266
+
267
+ pubid.to_s(with_edition: true)
268
+ end
269
+
270
+ def resource_bib_data(bib, schema_and_entity)
271
+ schema = bib.xpath("schema[@name='#{schema_and_entity}']").first
272
+
273
+ {
274
+ identifier: identifier(bib),
275
+ number: schema.attributes["number"],
276
+ supersedes_concept: schema.attributes["number.supersedes"],
277
+ status: bib.attributes["status"],
278
+ title: bib.attributes["title"] || bib.attributes["name"],
279
+ }
280
+ end
281
+
282
+ def module_bib_data(bib, type)
283
+ {
284
+ identifier: identifier(bib),
285
+ number: bib.attributes["wg.number.#{type}"],
286
+ supersedes_concept: bib.attributes["wg.number.#{type}.supersedes"],
287
+ status: bib.attributes["status"],
288
+ title: bib.attributes["title"] || bib.attributes["name"],
289
+ }
290
+ end
291
+
292
+ def bom_bib_data(bib)
293
+ {
294
+ identifier: identifier(bib),
295
+ number: bib.attributes["wg.number.bom.exp"],
296
+ supersedes_concept: bib.attributes["wg.number.bom.supersedes"],
297
+ status: bib.attributes["status"],
298
+ title: bib.attributes["title"] || bib.attributes["name"],
299
+ }
300
+ end
301
+
93
302
  def convert_from_resource_file(resource_docs_dir, stepmod_dir, linked, descriptions_file)
94
- resource_docs_file = File.join(stepmod_dir, "data/resource_docs",
95
- resource_docs_dir, "resource.xml")
96
- puts(resource_docs_file)
303
+ resource_docs_file = resource_docs_file_path(stepmod_dir, resource_docs_dir)
304
+
97
305
  resource_docs = Nokogiri::XML(File.read(resource_docs_file)).root
98
306
  schema = resource_docs.xpath("schema[@name='#{linked}']")
99
307
 
100
308
  Dir.chdir(File.dirname(descriptions_file)) do
101
309
  wrapper = "<resource>#{schema}</resource>"
102
- "\n#{Stepmod::Utils::SmrlResourceConverter.convert(wrapper, no_notes_examples: true)}"
310
+
311
+ "\n" + Stepmod::Utils::SmrlResourceConverter.convert(
312
+ wrapper,
313
+ {
314
+ no_notes_examples: false,
315
+ schema_and_entity: linked,
316
+ },
317
+ )
103
318
  end
104
319
  end
320
+
321
+ def resource_docs_file_path(stepmod_dir, resource_docs_dir)
322
+ File.join(
323
+ stepmod_dir,
324
+ "data/resource_docs",
325
+ resource_docs_dir,
326
+ "resource.xml",
327
+ )
328
+ end
105
329
  end
106
330
  end
107
331
  end
@@ -7,9 +7,9 @@ module Stepmod
7
7
  attr_accessor :acronym
8
8
 
9
9
  def to_mn_adoc
10
- mn_adoc = ["=== #{definition}"]
10
+ mn_adoc = ["=== #{definition.map(&:content).join}"]
11
11
  mn_adoc << "\nalt:[#{acronym}]" if acronym
12
- mn_adoc << "\n\n#{designations.join(", ")}" if designations&.any?
12
+ mn_adoc << "\n\n#{designations.map(&:designation).join(", ")}" if designations&.any?
13
13
 
14
14
  mn_adoc.join
15
15
  end
@@ -18,15 +18,28 @@ module Stepmod
18
18
  def from_h(hash)
19
19
  _, definition, acronym = treat_acronym(hash["definition"])
20
20
 
21
- hash["definition"] = definition
21
+ hash["definition"] = [definition]
22
+
22
23
  hash["acronym"] = acronym.gsub(/\(|\)/, "") if acronym
23
- hash["designations"] = hash["synonyms"]
24
+ add_designations(hash, hash["synonyms"]) if hash["synonyms"]
24
25
 
25
- super(hash.reject { |k, _| k == "synonyms" })
26
+ new(hash.reject { |k, _| k == "synonyms" })
26
27
  end
27
28
 
28
29
  private
29
30
 
31
+ def add_designations(hash, synonyms)
32
+ hash["designations"] ||= []
33
+ hash["designations"] << designation_hash(synonyms) if synonyms
34
+ end
35
+
36
+ def designation_hash(value, type = "expression")
37
+ {
38
+ "designation" => value,
39
+ "type" => type,
40
+ }
41
+ end
42
+
30
43
  def treat_acronym(term_def)
31
44
  return [nil, term_def.strip, nil] unless term_def.match?(/.+\(.+?\)$/)
32
45