stepmod-utils 0.2.7 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.