stepmod-utils 0.2.7 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe9caf0ee63e637eb1a73289d7394a495b5f8a313c6ee3d69aff2bdcc150e57f
4
- data.tar.gz: 791c199203956d117839a900869fd61362ead66703f6723cd4b5c0c8d871ccc4
3
+ metadata.gz: e4b01b98d2e819f59adda9b7583eb65e0f3f17c67b57e297d4c63a28587a9c81
4
+ data.tar.gz: 274c0b90422ffb4f51134c49c4b1f8b9b8d4319b4369fd26baccf6191cf11183
5
5
  SHA512:
6
- metadata.gz: 1910feb532333a698daa864f4387ccefdbcdeb6ccbcf3a962d3e7ec5dfa0a0c0f17643e8eba22ed625aa2a308595b0c30ea7d49ce5bed2de0a8c638cb1e2e00d
7
- data.tar.gz: 19757106a503652a64052eb823750bb5a618750b68bf42abdc3833dde6be9d3345dbc80c5051d37cea2507fe07c87b0669cf3af60c66cf6579ace1cd02f9bf96
6
+ metadata.gz: 74483e26bbfdbb7dd5827ebf8d1b7270b13cf35765107830a7d5ce29239d4fa865804e6384ba092f7209fdc7ab91387f8841791822deb6da45d97f37d1621e82
7
+ data.tar.gz: 9d130371dc91aa996896c79c3d3a7ff4be703d258030e9d2aee64212add70b79f8fdc9962c9d3d2d1d309d8e5c771817a22f44ff515f3702c014c859c9013dd0
@@ -16,19 +16,9 @@ jobs:
16
16
  strategy:
17
17
  fail-fast: false
18
18
  matrix:
19
- ruby: [ '2.7', '2.6', '2.5', '2.4' ]
19
+ ruby: [ '3.0', '2.7', '2.6', '2.5', '2.4' ]
20
20
  os: [ ubuntu-latest, windows-latest, macos-latest ]
21
21
  experimental: [ false ]
22
- include:
23
- - ruby: '3.0'
24
- os: 'ubuntu-latest'
25
- experimental: true
26
- - ruby: '3.0'
27
- os: 'windows-latest'
28
- experimental: true
29
- - ruby: '3.0'
30
- os: 'macos-latest'
31
- experimental: true
32
22
  steps:
33
23
  - uses: actions/checkout@v2
34
24
  with:
@@ -9,7 +9,7 @@ on:
9
9
  description: |
10
10
  Next release version. Possible values: x.y.z, major, minor, patch or pre|rc|etc
11
11
  required: true
12
- default: 'patch'
12
+ default: 'skip'
13
13
  push:
14
14
  tags: [ v* ]
15
15
 
@@ -22,10 +22,11 @@ jobs:
22
22
  - uses: ruby/setup-ruby@v1
23
23
  with:
24
24
  ruby-version: '2.6'
25
+ bundler-cache: true
25
26
 
26
27
  - run: gem install gem-release
27
28
 
28
- - if: ${{ github.event_name == 'workflow_dispatch' }}
29
+ - if: ${{ github.event_name == 'workflow_dispatch' }} && ${{ github.event.inputs.next_version != 'skip' }}
29
30
  run: |
30
31
  git config user.name github-actions
31
32
  git config user.email github-actions@github.com
@@ -36,7 +37,7 @@ jobs:
36
37
  RUBYGEMS_API_KEY: ${{secrets.METANORMA_CI_RUBYGEMS_API_KEY}}
37
38
  run: |
38
39
  gem install gem-release
39
- cat > ~/.gem/credentials << EOF
40
+ envsubst << 'EOF' > ~/.gem/credentials
40
41
  ---
41
42
  :rubygems_api_key: ${RUBYGEMS_API_KEY}
42
43
  EOF
data/.hound.yml ADDED
@@ -0,0 +1,5 @@
1
+ # Auto-generated by Cimas: Do not edit it manually!
2
+ # See https://github.com/metanorma/cimas
3
+ ruby:
4
+ enabled: true
5
+ config_file: .rubocop.yml
data/.rubocop.yml ADDED
@@ -0,0 +1,10 @@
1
+ # Auto-generated by Cimas: Do not edit it manually!
2
+ # See https://github.com/metanorma/cimas
3
+ inherit_from:
4
+ - https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
5
+
6
+ # local repo-specific modifications
7
+ # ...
8
+
9
+ AllCops:
10
+ TargetRubyVersion: 2.4
@@ -17,134 +17,103 @@ class Gem::Specification
17
17
  end
18
18
 
19
19
  require 'bundler/setup'
20
- require 'stepmod/utils/stepmod_definition_converter'
21
- require 'stepmod/utils/bibdata'
22
- require 'stepmod/utils/concept'
23
- require 'ptools'
24
-
25
- ReverseAdoc.config.unknown_tags = :bypass
26
-
27
- parsed_terms = []
28
- parsed_bibliography = []
29
- encountered_terms = {}
20
+ require 'stepmod/utils/terms_extractor'
30
21
 
31
22
  stepmod_dir = ARGV.first || Dir.pwd
32
23
 
24
+ general_concepts,
25
+ resource_concepts,
26
+ parsed_bibliography,
27
+ part_concepts,
28
+ part_resources,
29
+ part_modules = Stepmod::Utils::TermsExtractor.call(stepmod_dir)
30
+
31
+ def part_to_title(bibdata)
32
+ case bibdata.part.to_i
33
+ when 41
34
+ "Part 41"
35
+ when 42
36
+ "Geometric and topological representation"
37
+ when 43
38
+ "Foundation representation"
39
+ when 44
40
+ "Product structure, concept and configuration"
41
+ when 45
42
+ "Part 45"
43
+ when 46
44
+ "Visual presentation"
45
+ when 47
46
+ "Shape tolerance"
47
+ when 51
48
+ "Mathematical representation"
49
+ else
50
+ bibdata.title_en
51
+ end
52
+ end
53
+
33
54
  def log message
34
55
  puts "[stepmod-utils] #{message}"
35
56
  end
36
57
 
37
- stepmod_path = Pathname.new(stepmod_dir).realpath
38
-
39
- # If we are using the stepmod CVS repository, provide the revision number per file
40
- has_cvs = File.which("cvs")
41
- cvs_mode = has_cvs && Dir.exists?(stepmod_path.join('CVS'))
42
-
43
- log "INFO: STEPmod directory set to #{stepmod_dir}."
44
-
45
- if cvs_mode
46
- log "INFO: STEPmod directory is a CVS repository and will detect revisions."
47
- log "INFO: [CVS] Detecting file revisions can be slow, please be patient!"
48
- else
49
- log "INFO: STEPmod directory is not a CVS repository, skipping revision detection."
58
+ part_concepts.each do |(bibdata, current_part_concepts)|
59
+ fn = "03x-stepmod-#{bibdata.part}.adoc"
60
+ File.open(fn, 'w') { |file|
61
+ file.puts("== #{part_to_title(bibdata)}\n\n")
62
+ file.puts(current_part_concepts.map(&:to_mn_adoc).join("\n"))
63
+ }
64
+ log "INFO: written to: #{fn}"
50
65
  end
51
66
 
52
- log "INFO: Detecting paths..."
53
-
54
- files = %w(
55
- resource.xml
56
- application_protocol.xml
57
- business_object_model.xml
58
- module.xml
59
- ).inject([]) do |acc, t|
60
- acc << Dir["#{stepmod_dir}/**/#{t}"]
61
- end.flatten.sort.uniq
62
-
63
- files.each do |file_path|
64
- file_path = Pathname.new(file_path).realpath
65
- fpath = file_path.relative_path_from(stepmod_path)
66
-
67
- log "INFO: Processing XML file #{fpath}"
68
- current_document = Nokogiri::XML(File.read(file_path)).root
69
-
70
- bibdata = nil
71
- begin
72
- bibdata = Stepmod::Utils::Bibdata.new(document: current_document)
73
- rescue
74
- log "WARNING: Unknown file #{fpath}, skipped"
75
- next
76
- end
77
-
78
- # TODO: we may want a command line option to override this in the future
79
- unless %w(IS DIS FDIS TS).include? bibdata.doctype
80
- log "INFO: skipped #{bibdata.docid} as it is not IS, DIS or TS"
81
- next
82
- end
83
67
 
84
- if bibdata.part.to_s.empty?
85
- log "FATAL: missing `part` attribute: #{fpath}"
86
- log "INFO: skipped #{bibdata.docid} as it is missing `part` attribute."
87
- next
88
- end
68
+ part_resources.each do |(bibdata, current_part_resources)|
69
+ fn = "04x-stepmod-entities-resources-#{bibdata.part}.adoc"
70
+ File.open(fn, 'w') { |file|
71
+ file.puts("== #{part_to_title(bibdata)}\n\n")
72
+ file.puts(current_part_resources.map(&:to_mn_adoc).join("\n"))
73
+ }
74
+ log "INFO: written to: #{fn}"
75
+ end
89
76
 
90
- revision_string = "\n// CVS: revision not detected"
91
- if cvs_mode
92
- # Run `cvs status` to find out version
93
-
94
- log "INFO: Detecting CVS revision..."
95
- Dir.chdir(stepmod_path) do
96
- status = `cvs status #{fpath}`
97
-
98
- unless status.empty?
99
- working_rev = status.split(/\n/).grep(/Working revision:/).first.match(/revision:\s+(.+)$/)[1]
100
- repo_rev = status.split(/\n/).grep(/Repository revision:/).first.match(/revision:\t(.+)\t/)[1]
101
- log "INFO: CVS working rev (#{working_rev}), repo rev (#{repo_rev})"
102
- revision_string = "\n// CVS working rev: (#{working_rev}), repo rev (#{repo_rev})\n" +
103
- "// CVS: revision #{working_rev == repo_rev ? 'up to date' : 'differs'}"
104
- end
105
- end
106
- end
107
77
 
108
- # read definitions
109
- current_document.xpath('//definition').each.with_index(1) do |definition, index|
78
+ part_modules.each do |(bibdata, part_modules_arm, part_modules_mim)|
79
+ fn = "05x-stepmod-entities-modules-#{bibdata.part}.adoc"
80
+ File.open(fn, 'w') { |file|
81
+ file.puts("")
82
+ unless part_modules_arm.empty?
83
+ schema_name = part_modules_arm.first.first
84
+ concepts = part_modules_arm.first.last
110
85
 
111
- term_id = definition['id']
112
- unless term_id.nil?
113
- if encountered_terms[term_id]
114
- log "FATAL: Duplicated term with id: #{term_id}, #{fpath}"
115
- end
116
- encountered_terms[term_id] = true
86
+ # puts "SCHEMA NAME ARM: #{schema_name}"
87
+ file.puts("== #{schema_name}\n\n")
88
+ file.puts(concepts.map(&:to_mn_adoc).join("\n"))
117
89
  end
118
90
 
119
- # Assume that definition is located in clause 3 of the ISO document
120
- # in order. We really don't have a good reference here.
121
- ref_clause = "3.#{index}"
122
-
123
- concept = Stepmod::Utils::Concept.parse(
124
- definition,
125
- reference_anchor: bibdata.anchor,
126
- reference_clause: ref_clause,
127
- file_path: fpath + revision_string
128
- )
91
+ file.puts("")
129
92
 
130
- parsed_terms << concept
131
- parsed_bibliography << bibdata
132
- end
93
+ unless part_modules_mim.empty?
94
+ schema_name = part_modules_mim.first.first
133
95
 
134
- log "INFO: Completed processing XML file #{fpath}"
96
+ # puts "SCHEMA NAME MIM: #{schema_name}"
97
+ concepts = part_modules_mim.first.last
98
+ file.puts("== #{schema_name}\n\n")
99
+ file.puts(concepts.map(&:to_mn_adoc).join("\n"))
100
+ end
135
101
 
102
+ }
103
+ log "INFO: written to: #{fn}"
136
104
  end
137
105
 
138
- parsed_bibliography
139
-
140
- File.open('031-generated-terms.adoc', 'w') { |file|
141
- file.puts(parsed_terms.map(&:to_mn_adoc).join("\n"))
106
+ File.open('031-stepmod-general.adoc', 'w') { |file|
107
+ file.puts(general_concepts.map(&:to_mn_adoc).join("\n"))
142
108
  }
109
+ log "INFO: written to: 031-stepmod-general.adoc"
143
110
 
144
- log "INFO: written to: 031-generated-terms.adoc"
111
+ File.open('041-stepmod-entities-resources.adoc', 'w') { |file|
112
+ file.puts(resource_concepts.map(&:to_mn_adoc).join("\n"))
113
+ }
114
+ log "INFO: written to: 041-stepmod-entities-resources.adoc"
145
115
 
146
116
  File.open('991-generated-bibliography.adoc', 'w') { |file|
147
- file.puts(parsed_bibliography.map(&:to_mn_adoc).uniq.join("\n"))
117
+ file.puts(parsed_bibliography.map(&:to_mn_adoc).sort.uniq.join("\n"))
148
118
  }
149
-
150
119
  log "INFO: written to: 991-generated-bibliography.adoc"
@@ -67,6 +67,8 @@ module Stepmod
67
67
  "ISO/CD #{DOCNUMBER}-#{part}"
68
68
  when "DIS"
69
69
  "ISO/DIS #{DOCNUMBER}-#{part}"
70
+ when "FDIS"
71
+ "ISO/FDIS #{DOCNUMBER}-#{part}"
70
72
  when "TS"
71
73
  "ISO/TS #{DOCNUMBER}-#{part}"
72
74
  when "CD-TS"
@@ -20,22 +20,96 @@ module Stepmod
20
20
  end
21
21
  end
22
22
 
23
- def self.parse(definition_xml, reference_anchor:, reference_clause:, file_path:)
24
- new(
25
- converted_definition: Stepmod::Utils::StepmodDefinitionConverter.convert(definition_xml),
26
- reference_anchor: reference_anchor,
27
- reference_clause: reference_clause,
28
- file_path: file_path
29
- )
23
+ class << self
24
+ def parse(definition_xml, reference_anchor:, reference_clause:, file_path:)
25
+ converted_definition = Stepmod::Utils::StepmodDefinitionConverter.convert(
26
+ definition_xml,
27
+ {
28
+ # We don't want examples and notes
29
+ no_notes_examples: true,
30
+ reference_anchor: reference_anchor
31
+ }
32
+ )
33
+
34
+ return nil if converted_definition.nil? || converted_definition.strip.empty?
35
+
36
+ if definition_xml.name == 'ext_description'
37
+ converted_definition = <<~TEXT
38
+ #{converted_definition}
39
+
40
+ NOTE: This term is incompletely defined in this document.
41
+ Reference <<#{reference_anchor}>> for the complete definition.
42
+ TEXT
43
+ end
44
+ # https://github.com/metanorma/stepmod-utils/issues/86
45
+ if definition_xml.name == 'definition'
46
+ designation = definition_designation(definition_xml)
47
+ definition = definition_xml_definition(definition_xml, reference_anchor)
48
+ converted_definition = definition_xml_converted_definition(designation, definition).strip
49
+ end
50
+ new(
51
+ designation: designation,
52
+ definition: definition,
53
+ converted_definition: converted_definition,
54
+ reference_anchor: reference_anchor,
55
+ reference_clause: reference_clause,
56
+ file_path: file_path
57
+ )
58
+ end
59
+
60
+ def definition_designation(definition_xml)
61
+ alts = definition_xml.xpath('.//def/p').map(&:text)
62
+ {
63
+ accepted: definition_xml.xpath('.//term').first&.text,
64
+ alt: alts
65
+ }
66
+ end
67
+
68
+ def definition_xml_definition(definition_xml, reference_anchor)
69
+ text_nodes = definition_xml
70
+ .xpath('.//def')
71
+ .first
72
+ .children
73
+ .reject { |n| n.name == 'p' }
74
+ wrapper = "<def>#{text_nodes.map(&:to_s).join}</def>"
75
+ Stepmod::Utils::Converters::Def
76
+ .new
77
+ .convert(
78
+ Nokogiri::XML(wrapper).root,
79
+ {
80
+ # We don't want examples and notes
81
+ no_notes_examples: true,
82
+ reference_anchor: reference_anchor
83
+ })
84
+ end
85
+
86
+ def definition_xml_converted_definition(designation, definition)
87
+ if designation[:alt].length.positive?
88
+ alt_notation = "alt:[#{designation[:alt].map(&:strip).join(',')}]"
89
+ end
90
+ result = <<~TEXT
91
+ === #{designation[:accepted]}
92
+ TEXT
93
+ if alt_notation
94
+ result += <<~TEXT
95
+
96
+ #{alt_notation}
97
+ TEXT
98
+ end
99
+ <<~TEXT
100
+ #{result}
101
+ #{definition}
102
+ TEXT
103
+ end
30
104
  end
31
105
 
32
106
  def to_mn_adoc
33
107
  <<~TEXT
34
- // STEPmod path: #{file_path}
108
+ // STEPmod path:#{!file_path.empty? ? " #{file_path}" : ""}
35
109
  #{converted_definition}
36
110
 
37
111
  [.source]
38
- <<#{reference_anchor},clause=#{reference_clause}>>
112
+ <<#{reference_anchor}#{reference_clause ? ",clause=" + reference_clause : ""}>>
39
113
 
40
114
  TEXT
41
115
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Stepmod
4
+ module Utils
5
+ module Converters
6
+ class Arm < ReverseAdoc::Converters::Base
7
+ def convert(node, state = {})
8
+ treat_children(node, state)
9
+ end
10
+
11
+ private
12
+
13
+ def treat_children(node, state)
14
+ res = node.children.map { |child| treat(child, state) }
15
+ res.map(&:strip).reject(&:empty?).join("\n\n")
16
+ end
17
+ end
18
+
19
+ ReverseAdoc::Converters.register :arm, Arm.new
20
+ end
21
+ end
22
+ end
@@ -12,13 +12,15 @@ module Stepmod
12
12
 
13
13
  def treat_children(node, state)
14
14
  converted = node.children.each_with_object({}) do |child, res|
15
- content = treat(child, state).strip
16
- next if content.empty?
17
15
 
18
- res[child] = content
19
- end
16
+ content = treat(child, state)
17
+ next if content.strip.empty?
18
+
19
+ res[child] = content
20
+ end
20
21
  previous = nil
21
22
  result = ''
23
+
22
24
  converted.each.with_index do |(child, content), i|
23
25
  if block_tag?(child, previous)
24
26
  result += "\n\n"
@@ -30,6 +32,11 @@ module Stepmod
30
32
  result += content
31
33
  previous = child
32
34
  end
35
+
36
+ # Remove double newlines for every line
37
+ result = result.gsub(/\n\n+/, "\n\n")
38
+ result = result.squeeze(' ')
39
+
33
40
  result.strip
34
41
  end
35
42
 
@@ -50,8 +57,9 @@ module Stepmod
50
57
  return unless can_transform_to_alt?(first_child_tag)
51
58
 
52
59
  result = Stepmod::Utils::Converters::Synonym
53
- .new
54
- .convert(first_child_tag)
60
+ .new
61
+ .convert(first_child_tag)
62
+
55
63
  first_child_tag.remove
56
64
  "#{result}\n\n"
57
65
  end
@@ -71,6 +79,7 @@ module Stepmod
71
79
  end
72
80
 
73
81
  ReverseAdoc::Converters.register :def, Def.new
82
+ ReverseAdoc::Converters.register :description, Def.new
74
83
  end
75
84
  end
76
85
  end
@@ -5,10 +5,21 @@ module Stepmod
5
5
  module Converters
6
6
  class Example < ReverseAdoc::Converters::Base
7
7
  def convert(node, state = {})
8
- "\n\n[example]\n====\n#{treat_children(node, state).strip}\n====\n\n"
8
+
9
+ # If we want to skip this node
10
+ return '' if state[:no_notes_examples]
11
+
12
+ <<~TEMPLATE
13
+
14
+ [example]
15
+ ====
16
+ #{treat_children(node, state).strip}
17
+ ====
18
+
19
+ TEMPLATE
9
20
  end
10
21
  end
11
22
  ReverseAdoc::Converters.register :example, Example.new
12
23
  end
13
24
  end
14
- end
25
+ end
@@ -4,9 +4,11 @@ module Stepmod
4
4
  class ExtDescription < ReverseAdoc::Converters::Base
5
5
  def convert(node, state = {})
6
6
  state = state.merge(schema_name: node['linkend'])
7
+ child_text = treat_children(node, state).strip
8
+
7
9
  <<~TEMPLATE
8
10
  (*"#{node['linkend']}"
9
- #{treat_children(node, state).strip}
11
+ #{child_text}
10
12
  *)
11
13
  TEMPLATE
12
14
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ require 'reverse_adoc/converters/figure'
3
+
4
+ module Stepmod
5
+ module Utils
6
+ module Converters
7
+ class Figure < ReverseAdoc::Converters::Figure
8
+ def convert(node, state = {})
9
+ # If we want to skip this node
10
+ return '' if state[:no_notes_examples]
11
+
12
+ super
13
+ end
14
+ end
15
+ # This replaces the converter
16
+ ReverseAdoc::Converters.register :figure, Figure.new
17
+ end
18
+ end
19
+ end
20
+
@@ -13,10 +13,14 @@ module Stepmod
13
13
  # We take the text value of the element and convert to this:
14
14
 
15
15
  # term:[individual products]
16
- if node['linkend'].split(':').length > 1
17
- ref = node.text
16
+
17
+ ref = node.text.strip
18
+ if !ref.empty?
19
+ " term:[#{normalized_ref(ref)}] "
20
+ elsif
21
+ ref = node['linkend'].split(':').first
22
+ " *#{ref}*"
18
23
  end
19
- " term:[#{normalized_ref(ref)}] "
20
24
  end
21
25
 
22
26
  private
@@ -5,10 +5,21 @@ module Stepmod
5
5
  module Converters
6
6
  class Note < ReverseAdoc::Converters::Base
7
7
  def convert(node, state = {})
8
- "\n\n[NOTE]\n--\n#{treat_children(node, state).strip}\n--\n\n"
8
+
9
+ # If we want to skip this node
10
+ return '' if state[:no_notes_examples]
11
+
12
+ <<~TEMPLATE
13
+
14
+ [NOTE]
15
+ --
16
+ #{treat_children(node, state).strip}
17
+ --
18
+
19
+ TEMPLATE
9
20
  end
10
21
  end
11
22
  ReverseAdoc::Converters.register :note, Note.new
12
23
  end
13
24
  end
14
- end
25
+ end
@@ -0,0 +1,44 @@
1
+ module Stepmod
2
+ module Utils
3
+ module Converters
4
+ class StepmodExtDescription < ReverseAdoc::Converters::Base
5
+ def convert(node, state = {})
6
+ state = state.merge(schema_name: node['linkend'])
7
+ linkend = node['linkend'].split('.')
8
+
9
+ # We only want ENTITY entries, not their attributes
10
+ # https://github.com/metanorma/iso-10303-2/issues/36#issuecomment-841300092
11
+ return nil if linkend.length != 2
12
+
13
+ child_text = treat_children(node, state).strip
14
+ return nil if child_text.empty?
15
+
16
+ # Only taking the first paragraph of the definition
17
+ child_text = child_text.split("\n").first
18
+
19
+ # # Only taking the first sentence
20
+ # if child_text.contains?(".")
21
+ # child_text = child_text.split(".").first
22
+ # end
23
+
24
+ domain = case linkend.first
25
+ when /_mim$/, /_arm$/
26
+ "STEP module"
27
+ # when /_schema$/
28
+ else
29
+ "STEP resource"
30
+ end
31
+
32
+ <<~TEMPLATE
33
+ === #{linkend.last}
34
+
35
+ #{domain ? "domain:[" + domain + "]" : ""}
36
+
37
+ #{child_text}
38
+ TEMPLATE
39
+ end
40
+ end
41
+ ReverseAdoc::Converters.register :ext_description, StepmodExtDescription.new
42
+ end
43
+ end
44
+ end
@@ -30,8 +30,8 @@ module Stepmod
30
30
  def treat_text(node)
31
31
  text = node.text
32
32
  text = preserve_nbsp(text)
33
- # text = remove_border_newlines(text)
34
33
  text = remove_inner_newlines(text)
34
+ text = remove_border_newlines(text)
35
35
 
36
36
  text = preserve_keychars_within_backticks(text)
37
37
  text = preserve_tags(text)
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'stepmod/utils/converters/synonym'
4
+
5
+ module Stepmod
6
+ module Utils
7
+ module Converters
8
+ class Uof < ReverseAdoc::Converters::Base
9
+ def convert(node, state = {})
10
+
11
+ # WARNING: <uof> tag content is deprecated
12
+ return ""
13
+
14
+ #
15
+ # <<~TEXT
16
+ # === #{node['name'].strip}
17
+
18
+ # <STEP module> #{treat_children(node, state).strip}
19
+ # TEXT
20
+ end
21
+ end
22
+
23
+ ReverseAdoc::Converters.register :uof, Uof.new
24
+ end
25
+ end
26
+ end
@@ -64,4 +64,4 @@ module Stepmod
64
64
  end
65
65
  end
66
66
  end
67
- end
67
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'reverse_adoc'
4
+ require 'stepmod/utils/converters/arm'
4
5
  require 'stepmod/utils/converters/clause_ref'
5
6
  require 'stepmod/utils/converters/express_ref'
6
7
  require 'stepmod/utils/converters/module_ref'
@@ -11,8 +12,11 @@ require 'stepmod/utils/converters/example'
11
12
  require 'stepmod/utils/converters/note'
12
13
  require 'stepmod/utils/converters/ol'
13
14
  require 'stepmod/utils/converters/stem'
15
+ require 'stepmod/utils/converters/stepmod_ext_description'
14
16
  require 'stepmod/utils/converters/term'
15
17
  require 'stepmod/utils/converters/synonym'
18
+ require 'stepmod/utils/converters/uof'
19
+ require 'stepmod/utils/converters/figure'
16
20
 
17
21
  require 'reverse_adoc/converters/a'
18
22
  require 'reverse_adoc/converters/blockquote'
@@ -37,19 +41,21 @@ module Stepmod
37
41
  module Utils
38
42
  class StepmodDefinitionConverter
39
43
  def self.convert(input, options = {})
40
- root = if input.is_a?(String)
41
- then Nokogiri::XML(input).root
42
- elsif input.is_a?(Nokogiri::XML::Document)
43
- then input.root
44
- elsif input.is_a?(Nokogiri::XML::Node)
45
- then input
46
- end
44
+ root = case input
45
+ when String
46
+ Nokogiri::XML(input).root
47
+ when Nokogiri::XML::Document
48
+ input.root
49
+ when Nokogiri::XML::Node
50
+ input
51
+ end
47
52
 
48
- root || (return '')
53
+ return '' unless root
49
54
 
50
55
  ReverseAdoc.config.with(options) do
51
- result = ReverseAdoc::Converters.lookup(root.name).convert(root)
52
- ReverseAdoc.cleaner.tidy(result)
56
+ result = ReverseAdoc::Converters.lookup(root.name).convert(root, options)
57
+ return '' unless result
58
+ ReverseAdoc.cleaner.tidy(result.dup)
53
59
  end
54
60
  end
55
61
  end
@@ -0,0 +1,326 @@
1
+ require 'stepmod/utils/stepmod_definition_converter'
2
+ require 'stepmod/utils/bibdata'
3
+ require 'stepmod/utils/concept'
4
+
5
+ ReverseAdoc.config.unknown_tags = :bypass
6
+
7
+ module Stepmod
8
+ module Utils
9
+ class TermsExtractor
10
+ # TODO: we may want a command line option to override this in the future
11
+ ACCEPTED_STAGES = %w(IS DIS FDIS TS)
12
+
13
+ attr_reader :stepmod_path,
14
+ :stepmod_dir,
15
+ :general_concepts,
16
+ :resource_concepts,
17
+ :parsed_bibliography,
18
+ :encountered_terms,
19
+ :cvs_mode,
20
+ :part_concepts,
21
+ :part_resources,
22
+ :part_modules,
23
+ :stdout
24
+
25
+ def self.call(stepmod_dir, stdout = STDOUT)
26
+ new(stepmod_dir, stdout).call
27
+ end
28
+
29
+ def initialize(stepmod_dir, stdout)
30
+ @stdout = stdout
31
+ @stepmod_dir = stepmod_dir
32
+ @stepmod_path = Pathname.new(stepmod_dir).realpath
33
+ @general_concepts = []
34
+ @resource_concepts = []
35
+ @parsed_bibliography = []
36
+ @part_concepts = []
37
+ @part_resources = []
38
+ @part_modules = []
39
+ @encountered_terms = {}
40
+ end
41
+
42
+ def log message
43
+ stdout.puts "[stepmod-utils] #{message}"
44
+ end
45
+
46
+ def term_special_category(bibdata)
47
+ case bibdata.part.to_i
48
+ when 41,42,43,44,45,46,47,51
49
+ true
50
+ when [56..112]
51
+ true
52
+ else
53
+ false
54
+ end
55
+ end
56
+
57
+ def call
58
+ # If we are using the stepmod CVS repository, provide the revision number per file
59
+ @cvs_mode = if Dir.exists?(stepmod_path.join('CVS'))
60
+ require 'ptools'
61
+ # ptools provides File.which
62
+ File.which("cvs")
63
+ end
64
+
65
+ log "INFO: STEPmod directory set to #{stepmod_dir}."
66
+
67
+ if cvs_mode
68
+ log "INFO: STEPmod directory is a CVS repository and will detect revisions."
69
+ log "INFO: [CVS] Detecting file revisions can be slow, please be patient!"
70
+ else
71
+ log "INFO: STEPmod directory is not a CVS repository, skipping revision detection."
72
+ end
73
+
74
+ log "INFO: Detecting paths..."
75
+
76
+ repo_index = Nokogiri::XML(File.read(stepmod_path.join('repository_index.xml'))).root
77
+
78
+ files = []
79
+
80
+ # add module paths
81
+ repo_index.xpath('//module').each do |x|
82
+ path = Pathname.new("#{stepmod_dir}/modules/#{x['name']}/module.xml")
83
+ files << path if File.exists? path
84
+ end
85
+
86
+ # add resource_docs paths
87
+ repo_index.xpath('//resource_doc').each do |x|
88
+ path = Pathname.new("#{stepmod_dir}/resource_docs/#{x['name']}/resource.xml")
89
+ files << path if File.exists? path
90
+ end
91
+
92
+ # add business_object_models paths
93
+ repo_index.xpath('//business_object_model').each do |x|
94
+ path = Pathname.new("#{stepmod_dir}/business_object_models/#{x['name']}/business_object_model.xml")
95
+ files << path if File.exists? path
96
+ end
97
+
98
+ # add application_protocols paths
99
+ repo_index.xpath('//application_protocol').each do |x|
100
+ path = Pathname.new("#{stepmod_dir}/application_protocols/#{x['name']}/application_protocol.xml")
101
+ files << path if File.exists? path
102
+ end
103
+
104
+ files.sort!.uniq!
105
+ process_term_files(files)
106
+
107
+ [
108
+ general_concepts,
109
+ resource_concepts,
110
+ parsed_bibliography,
111
+ part_concepts,
112
+ part_resources,
113
+ part_modules
114
+ ]
115
+ end
116
+
117
+ private
118
+
119
+ def process_term_files(files)
120
+ parsed_schema_names = {}
121
+ files.each do |file_path|
122
+ file_path = file_path.realpath
123
+ fpath = file_path.relative_path_from(stepmod_path)
124
+
125
+ log "INFO: Processing XML file #{fpath}"
126
+ current_document = Nokogiri::XML(File.read(file_path)).root
127
+
128
+ bibdata = nil
129
+ begin
130
+ bibdata = Stepmod::Utils::Bibdata.new(document: current_document)
131
+ rescue
132
+ log "WARNING: Unknown file #{fpath}, skipped"
133
+ next
134
+ end
135
+
136
+ unless ACCEPTED_STAGES.include? bibdata.doctype
137
+ log "INFO: skipped #{bibdata.docid} as it is not one of (#{ACCEPTED_STAGES.join(", ")})."
138
+ next
139
+ end
140
+
141
+ if bibdata.part.to_s.empty?
142
+ log "FATAL: missing `part` attribute: #{fpath}"
143
+ log "INFO: skipped #{bibdata.docid} as it is missing `part` attribute."
144
+ next
145
+ end
146
+
147
+ revision_string = "\n// CVS: revision not detected"
148
+ if cvs_mode
149
+ # Run `cvs status` to find out version
150
+
151
+ log "INFO: Detecting CVS revision..."
152
+ Dir.chdir(stepmod_path) do
153
+ status = `cvs status #{fpath}`
154
+
155
+ unless status.empty?
156
+ working_rev = status.split(/\n/).grep(/Working revision:/).first.match(/revision:\s+(.+)$/)[1]
157
+ repo_rev = status.split(/\n/).grep(/Repository revision:/).first.match(/revision:\t(.+)\t/)[1]
158
+ log "INFO: CVS working rev (#{working_rev}), repo rev (#{repo_rev})"
159
+ revision_string = "\n// CVS working rev: (#{working_rev}), repo rev (#{repo_rev})\n" +
160
+ "// CVS: revision #{working_rev == repo_rev ? 'up to date' : 'differs'}"
161
+ end
162
+ end
163
+ end
164
+
165
+ # read definitions
166
+ current_part_concepts = []
167
+ definition_index = 0
168
+ current_document.xpath('//definition').each do |definition|
169
+ definition_index += 1
170
+ term_id = definition['id']
171
+ unless term_id.nil?
172
+ if encountered_terms[term_id]
173
+ log "FATAL: Duplicated term with id: #{term_id}, #{fpath}"
174
+ end
175
+ encountered_terms[term_id] = true
176
+ end
177
+
178
+ # Assume that definition is located in clause 3 of the ISO document
179
+ # in order. We really don't have a good reference here.
180
+ ref_clause = "3.#{definition_index}"
181
+
182
+ concept = Stepmod::Utils::Concept.parse(
183
+ definition,
184
+ reference_anchor: bibdata.anchor,
185
+ reference_clause: ref_clause,
186
+ file_path: fpath + revision_string
187
+ )
188
+ next unless concept
189
+
190
+ unless term_special_category(bibdata)
191
+ # log "INFO: this part is generic"
192
+ general_concepts << concept
193
+ else
194
+ # log "INFO: this part is special"
195
+ current_part_concepts << concept
196
+ end
197
+
198
+ parsed_bibliography << bibdata
199
+ end
200
+
201
+ current_part_resources = []
202
+ current_part_modules_arm = {}
203
+ current_part_modules_mim = {}
204
+
205
+ log "INFO: FILE PATH IS #{file_path}"
206
+ case file_path.to_s
207
+ when /resource.xml$/
208
+ log "INFO: Processing resource.xml for #{file_path}"
209
+ # Assumption: every schema is only linked by a single resource_docs document.
210
+ current_document.xpath('//schema').each do |schema_node|
211
+ schema_name = schema_node['name']
212
+ if parsed_schema_names[schema_name]
213
+ log "ERROR: We have encountered this schema before: #{schema_name} from path #{parsed_schema_names[schema_name]}, now at #{file_path}"
214
+ next
215
+ else
216
+ parsed_schema_names[schema_name] = file_path
217
+ end
218
+
219
+ Dir["#{stepmod_path}/resources/#{schema_name}/descriptions.xml"].each do |description_xml_path|
220
+ log "INFO: Processing resources schema #{description_xml_path}"
221
+ description_document = Nokogiri::XML(File.read(description_xml_path)).root
222
+ description_document.xpath('//ext_description').each do |ext_description|
223
+
224
+ # log "INFO: Processing linkend[#{ext_description['linkend']}]"
225
+
226
+ concept = Stepmod::Utils::Concept.parse(
227
+ ext_description,
228
+ reference_anchor: bibdata.anchor,
229
+ reference_clause: nil,
230
+ file_path: Pathname.new(description_xml_path).relative_path_from(stepmod_path)
231
+ )
232
+ next unless concept
233
+
234
+ unless term_special_category(bibdata)
235
+ # log "INFO: this part is generic"
236
+ resource_concepts << concept
237
+ else
238
+ # log "INFO: this part is special"
239
+ current_part_resources << concept
240
+ end
241
+
242
+ parsed_bibliography << bibdata
243
+ end
244
+ end
245
+ end
246
+
247
+ when /module.xml$/
248
+ log "INFO: Processing module.xml for #{file_path}"
249
+ # Assumption: every schema is only linked by a single module document.
250
+ # puts current_document.xpath('//module').length
251
+ schema_name = current_document.xpath('//module').first['name']
252
+ if parsed_schema_names[schema_name]
253
+ log "ERROR: We have encountered this schema before: #{schema_name} from path #{parsed_schema_names[schema_name]}, now at #{file_path}"
254
+ next
255
+ else
256
+ parsed_schema_names[schema_name] = file_path
257
+ end
258
+
259
+ description_xml_path = "#{stepmod_path}/modules/#{schema_name}/arm_descriptions.xml"
260
+ log "INFO: Processing modules schema #{description_xml_path}"
261
+
262
+ if File.exists?(description_xml_path)
263
+ description_document = Nokogiri::XML(File.read(description_xml_path)).root
264
+ description_document.xpath('//ext_description').each do |ext_description|
265
+
266
+ linkend_schema = ext_description['linkend'].split('.').first
267
+ concept = Stepmod::Utils::Concept.parse(
268
+ ext_description,
269
+ reference_anchor: bibdata.anchor,
270
+ reference_clause: nil,
271
+ file_path: Pathname.new(description_xml_path).relative_path_from(stepmod_path)
272
+ )
273
+ next unless concept
274
+
275
+ current_part_modules_arm[linkend_schema] ||= []
276
+ current_part_modules_arm[linkend_schema] << concept
277
+ # puts part_modules_arm.inspect
278
+ parsed_bibliography << bibdata
279
+ end
280
+ end
281
+
282
+ description_xml_path = "#{stepmod_path}/modules/#{schema_name}/mim_descriptions.xml"
283
+ log "INFO: Processing modules schema #{description_xml_path}"
284
+
285
+ if File.exists?(description_xml_path)
286
+ description_document = Nokogiri::XML(File.read(description_xml_path)).root
287
+ description_document.xpath('//ext_description').each do |ext_description|
288
+
289
+ linkend_schema = ext_description['linkend'].split('.').first
290
+
291
+ concept = Stepmod::Utils::Concept.parse(
292
+ ext_description,
293
+ reference_anchor: bibdata.anchor,
294
+ reference_clause: nil,
295
+ file_path: Pathname.new(description_xml_path).relative_path_from(stepmod_path)
296
+ )
297
+ next unless concept
298
+
299
+ current_part_modules_mim[linkend_schema] ||= []
300
+ current_part_modules_mim[linkend_schema] << concept
301
+
302
+ parsed_bibliography << bibdata
303
+ end
304
+ end
305
+
306
+ end
307
+
308
+ log "INFO: Completed processing XML file #{fpath}"
309
+ if current_part_concepts.empty?
310
+ log "INFO: Skipping #{fpath} (#{bibdata.docid}) because it contains no concepts."
311
+ elsif current_part_concepts.length < 3
312
+ log "INFO: Skipping #{fpath} (#{bibdata.docid}) because it only has #{current_part_concepts.length} terms."
313
+
314
+ current_part_concepts.each do |x|
315
+ general_concepts << x
316
+ end
317
+ else
318
+ part_concepts << [bibdata, current_part_concepts] unless current_part_concepts.empty?
319
+ end
320
+ part_resources << [bibdata, current_part_resources] unless current_part_resources.empty?
321
+ part_modules << [bibdata, current_part_modules_arm, current_part_modules_mim] if current_part_modules_arm.size + current_part_modules_mim.size > 0
322
+ end
323
+ end
324
+ end
325
+ end
326
+ end
@@ -1,5 +1,5 @@
1
1
  module Stepmod
2
2
  module Utils
3
- VERSION = "0.2.7"
3
+ VERSION = "0.3.5"
4
4
  end
5
5
  end
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
31
31
 
32
32
  spec.add_runtime_dependency "thor", ">= 0.20.3"
33
33
  spec.add_runtime_dependency "reverse_adoc", ">= 0.2.9"
34
- spec.add_runtime_dependency "ptools", '~> 1.3'
35
34
  spec.add_runtime_dependency "concurrent-ruby"
35
+ spec.add_runtime_dependency "ptools"
36
36
  spec.add_development_dependency "byebug", "~> 11.1"
37
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stepmod-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-04 00:00:00.000000000 Z
11
+ date: 2021-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -39,21 +39,21 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.2.9
41
41
  - !ruby/object:Gem::Dependency
42
- name: ptools
42
+ name: concurrent-ruby
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '1.3'
47
+ version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '1.3'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: concurrent-ruby
56
+ name: ptools
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -98,7 +98,9 @@ files:
98
98
  - ".github/workflows/rake.yml"
99
99
  - ".github/workflows/release.yml"
100
100
  - ".gitignore"
101
+ - ".hound.yml"
101
102
  - ".rspec"
103
+ - ".rubocop.yml"
102
104
  - CODE_OF_CONDUCT.md
103
105
  - Gemfile
104
106
  - Makefile
@@ -117,6 +119,7 @@ files:
117
119
  - lib/stepmod/utils/cleaner.rb
118
120
  - lib/stepmod/utils/concept.rb
119
121
  - lib/stepmod/utils/converters/a.rb
122
+ - lib/stepmod/utils/converters/arm.rb
120
123
  - lib/stepmod/utils/converters/blockquote.rb
121
124
  - lib/stepmod/utils/converters/br.rb
122
125
  - lib/stepmod/utils/converters/bypass.rb
@@ -138,6 +141,7 @@ files:
138
141
  - lib/stepmod/utils/converters/express_ref_express_description.rb
139
142
  - lib/stepmod/utils/converters/ext_description.rb
140
143
  - lib/stepmod/utils/converters/ext_descriptions.rb
144
+ - lib/stepmod/utils/converters/figure.rb
141
145
  - lib/stepmod/utils/converters/fund_cons.rb
142
146
  - lib/stepmod/utils/converters/head.rb
143
147
  - lib/stepmod/utils/converters/hr.rb
@@ -153,6 +157,7 @@ files:
153
157
  - lib/stepmod/utils/converters/schema.rb
154
158
  - lib/stepmod/utils/converters/schema_diag.rb
155
159
  - lib/stepmod/utils/converters/stem.rb
160
+ - lib/stepmod/utils/converters/stepmod_ext_description.rb
156
161
  - lib/stepmod/utils/converters/strong.rb
157
162
  - lib/stepmod/utils/converters/sub.rb
158
163
  - lib/stepmod/utils/converters/sup.rb
@@ -160,11 +165,13 @@ files:
160
165
  - lib/stepmod/utils/converters/table.rb
161
166
  - lib/stepmod/utils/converters/term.rb
162
167
  - lib/stepmod/utils/converters/text.rb
168
+ - lib/stepmod/utils/converters/uof.rb
163
169
  - lib/stepmod/utils/html_to_asciimath.rb
164
170
  - lib/stepmod/utils/smrl_description_converter.rb
165
171
  - lib/stepmod/utils/smrl_resource_converter.rb
166
172
  - lib/stepmod/utils/stepmod_definition_converter.rb
167
173
  - lib/stepmod/utils/stepmod_file_annotator.rb
174
+ - lib/stepmod/utils/terms_extractor.rb
168
175
  - lib/stepmod/utils/version.rb
169
176
  - migrating_from_cvs.adoc
170
177
  - resource_example.xml
@@ -188,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
188
195
  - !ruby/object:Gem::Version
189
196
  version: '0'
190
197
  requirements: []
191
- rubygems_version: 3.0.3
198
+ rubygems_version: 3.1.6
192
199
  signing_key:
193
200
  specification_version: 4
194
201
  summary: Stepmod-utils is a toolkit that works on STEPmod data.