pubid-iso 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,60 +1,115 @@
1
1
  module Pubid::Iso::Renderer
2
2
  class Base < Pubid::Core::Renderer::Base
3
+ attr_accessor :prerendered_params
4
+
5
+ TYPE_VALUES = {
6
+ tr: "TR",
7
+ ts: "TS",
8
+ isp: "ISP",
9
+ guide: "Guide",
10
+ pas: "PAS",
11
+ dpas: "DPAS",
12
+ }.freeze
13
+
14
+ # Prerender parameters
15
+ def prerender(with_edition: true, **args)
16
+ @params[:type_stage] = @params.slice(:stage, :type) if @params[:stage] || @params[:type]
17
+ super
18
+ end
19
+
20
+ def render_supplement(supplement_params, **args)
21
+ if supplement_params[:base].type == :amd
22
+ # render inner amendment (cor -> amd -> base)
23
+ render_supplement(supplement_params[:base].get_params, **args)
24
+ else
25
+ self.class.new(supplement_params[:base].get_params).render_base_identifier(
26
+ # always render year for identifiers with supplement
27
+ **args.merge({ with_date: true }),
28
+ )
29
+ end +
30
+ case supplement_params[:typed_stage].type.type
31
+ when :amd
32
+ render_amendments(
33
+ [Pubid::Iso::Amendment.new(**supplement_params.slice(:number, :year, :typed_stage, :edition, :iteration))],
34
+ args,
35
+ nil,
36
+ )
37
+ when :cor
38
+ render_corrigendums(
39
+ [Pubid::Iso::Corrigendum.new(**supplement_params.slice(:number, :year, :typed_stage, :edition, :iteration))],
40
+ args,
41
+ nil,
42
+ )
43
+ # copy parameters from Identifier only supported by Corrigendum
44
+ end +
45
+ (supplement_params[:base].language ? render_language(supplement_params[:base].language, args, nil) : "")
46
+ end
47
+
3
48
  # Render identifier
4
49
  # @param with_edition [Boolean] include edition in output
5
50
  # @see Pubid::Core::Renderer::Base for another options
6
- def render(with_edition: true, **args)
7
- params = prerender_params(@params,
8
- { with_edition: with_edition }.merge(args))
9
- # render empty string when the key is not exist
10
- params.default = ""
51
+ def render(with_edition: true, with_language_code: :iso, with_date: true, **args)
52
+ # super(**args.merge({ with_edition: with_edition }))
53
+ if %i(amd cor).include? @params[:typed_stage]&.type&.type
54
+ render_supplement(@params, **args.merge({ with_date: with_date,
55
+ with_language_code: with_language_code,
56
+ with_edition: with_edition }))
57
+ else
58
+ render_base_identifier(**args.merge({ with_date: with_date,
59
+ with_language_code: with_language_code,
60
+ with_edition: with_edition })) +
61
+ @prerendered_params[:language].to_s
62
+ end
11
63
 
12
- render_identifier(params)
13
64
  end
14
65
 
15
66
  def render_identifier(params)
16
- if @params[:type] && @params[:stage]
17
- if %w(DIS FDIS).include?(@params[:stage].abbr)
18
- render_base(params, "#{render_short_stage(@params[:stage].abbr)}#{@params[:type]}")
19
- else
20
- if params[:copublisher] && !params[:copublisher].empty?
21
- render_base(params, "%{type}%{stage}" % params)
22
- else
23
- render_base(params, "%{stage}%{type}" % params)
24
- end
25
- end
26
- else
27
- render_base(params, "%{type}%{stage}" % params)
28
- end +
29
- "%{part}%{iteration}%{year}%{amendments}%{corrigendums}%{edition}%{language}" % params
67
+ # typed_stage = if params[:typed_stage] && params[:typed_stage] != ""
68
+ # ((params[:copublisher] && !params[:copublisher].empty?) ? " " : "/") + params[:typed_stage].to_s
69
+ # else
70
+ # ""
71
+ # end
72
+ render_base(params, params[:typed_stage]) +
73
+ ("%{part}%{iteration}%{year}%{amendments}%{corrigendums}%{edition}" % params)
30
74
  end
31
75
 
32
- def render_short_stage(stage)
33
- (params[:copublisher] ? " " : "/") +
34
- case stage
35
- when "DIS"
36
- "D"
37
- when "FDIS"
38
- "FD"
39
- end
76
+ def render_typed_stage(typed_stage, _opts, params)
77
+ (params[:copublisher] ? " " : "/") + typed_stage.to_s
40
78
  end
41
79
 
42
- def render_type(type, opts, params)
43
- if params[:copublisher] || (params[:stage] && params[:stage].abbr != "IS")
44
- " #{type}"
45
- else
46
- "/#{type}"
80
+ # def render_type_stage(values, opts, params)
81
+ #
82
+ # # prerender stage and type before
83
+ # stage = render_stage(values[:stage], opts, params)
84
+ # type = values[:type]&.to_s
85
+ # return unless type || stage
86
+ #
87
+ # if type && stage
88
+ # # don't add prefix for pdf format
89
+ # if %w(DIS FDIS).include?(stage)
90
+ # "#{render_short_stage(stage)}#{type}"
91
+ # else
92
+ # "#{stage} #{type}"
93
+ # end
94
+ # else
95
+ # # when only type or stage
96
+ # "#{type}#{stage}"
97
+ # end
98
+ # end
99
+
100
+ def render_short_stage(stage)
101
+ case stage
102
+ when "DIS"
103
+ "D"
104
+ when "FDIS"
105
+ "FD"
47
106
  end
48
107
  end
49
108
 
50
- def render_stage(stage, opts, params)
51
- return if (stage.abbr == "PRF" and !opts[:with_prf]) || stage.abbr == "IS"
109
+ def render_stage(stage, opts, _params)
110
+ return if stage.nil? || (stage.abbr == "PRF" and !opts[:with_prf]) || stage.abbr == "IS"
52
111
 
53
- if params[:copublisher]
54
- " #{stage.abbr}"
55
- else
56
- "/#{stage.abbr}"
57
- end
112
+ stage.abbr
58
113
  end
59
114
 
60
115
  def render_edition(edition, opts, _params)
@@ -2,7 +2,7 @@ module Pubid::Iso::Renderer
2
2
  class Dir < Base
3
3
 
4
4
  def render_identifier(params)
5
- res = ("%{publisher}%{copublisher} DIR%{dirtype}%{number}%{year}%{supplement}%{language}" % params)
5
+ res = ("%{publisher}%{copublisher} DIR%{dirtype}%{number}%{year}%{supplement}" % params)
6
6
 
7
7
  if params.key?(:joint_document)
8
8
  joint_params = prerender_params(params[:joint_document].get_params, {})
@@ -1,8 +1,13 @@
1
1
  module Pubid::Iso::Renderer
2
2
  class French < Base
3
+ def render_typed_stage(typed_stage, opts, params)
4
+ return nil if typed_stage.type == :guide
5
+
6
+ super
7
+ end
8
+
3
9
  def render_identifier(params)
4
- if params[:type] == " Guide"
5
- params[:type] = ""
10
+ if @params[:typed_stage]&.type == :guide
6
11
  "Guide #{super(params)}"
7
12
  else
8
13
  super
@@ -18,9 +18,16 @@ module Pubid::Iso::Renderer
18
18
  "ISP" => "ИСП",
19
19
  }.freeze
20
20
 
21
+ def render_typed_stage(typed_stage, opts, params)
22
+ return nil if typed_stage.type == :guide
23
+
24
+ return (params[:copublisher] ? " " : "/") + STAGE[typed_stage.to_s] if STAGE.key?(typed_stage.to_s)
25
+
26
+ super
27
+ end
28
+
21
29
  def render_identifier(params)
22
- if params[:type] == " Guide"
23
- params[:type] = ""
30
+ if @params[:typed_stage]&.type == :guide
24
31
  "Руководство #{super(params)}"
25
32
  else
26
33
  super
@@ -43,11 +50,7 @@ module Pubid::Iso::Renderer
43
50
  end
44
51
 
45
52
  def render_stage(stage, _opts, params)
46
- if params[:copublisher]
47
- " #{STAGE[stage.abbr]}"
48
- else
49
- "/#{STAGE[stage.abbr]}"
50
- end
53
+ STAGE[stage.abbr] unless stage.nil?
51
54
  end
52
55
 
53
56
  def render_corrigendums(corrigendums, _opts, _params)
@@ -10,13 +10,42 @@ module Pubid::Iso::Renderer
10
10
  PRF: 50,
11
11
  IS: 60 }.freeze
12
12
 
13
+ def prerender(with_edition: true, **args)
14
+ @params[:type_stage] = @params.slice(:stage, :type) if @params[:stage] || @params[:type]
15
+ super
16
+ end
17
+
18
+ # Render identifier
19
+ # @param with_edition [Boolean] include edition in output
20
+ # @see Pubid::Core::Renderer::Base for another options
21
+ def render(with_edition: true, **args)
22
+ # copy type from typed stage
23
+ @params[:type] = @params[:typed_stage].type if @params[:typed_stage] && @params[:typed_stage].type
24
+ super(**args.merge({ with_edition: with_edition }))
25
+ end
26
+
13
27
  def render_identifier(params)
14
- render_base(params) + "%{stage}"\
15
- "%{corrigendum_stage}%{iteration}%{edition}%{amendments}%{corrigendums}%{language}" % params
28
+ render_base(params) + "%{typed_stage}"\
29
+ "%{corrigendum_stage}%{iteration}%{edition}%{amendments}%{corrigendums}" % params
30
+ end
31
+
32
+ def render_typed_stage(typed_stage, _opts, _params)
33
+ ":stage-#{typed_stage.stage.harmonized_code}" if typed_stage.stage
34
+ end
35
+ # def render_stage(stage, _opts, params)
36
+ # ":stage-#{stage.harmonized_code}"
37
+ # end
38
+
39
+ def render_iteration(iteration, _opts, params)
40
+ ".v#{iteration}" if params[:typed_stage]&.stage
41
+ end
42
+
43
+ def render_type(type, _, _)
44
+ ":#{type.to_s.downcase}" unless type == :is
16
45
  end
17
46
 
18
- def render_stage(stage, _opts, params)
19
- ":stage-#{stage.harmonized_code}"
47
+ def render_year(year, _opts, _params)
48
+ ":#{year}"
20
49
  end
21
50
  end
22
51
  end
@@ -2,17 +2,22 @@ module Pubid::Iso
2
2
  class Stage
3
3
  attr_accessor :abbr, :harmonized_code
4
4
 
5
- STAGES = { PWI: "00.00",
6
- NP: "10.00",
5
+ STAGES = { PWI: %w[00.00 00.20 00.60 00.98 00.99],
6
+ NP: %w[10.00 10.20 10.60 10.98 10.92],
7
7
  AWI: %w[20.00 10.99],
8
8
  WD: %w[20.20 20.60 20.98 20.99],
9
- CD: "30.00",
10
- DIS: "40.00",
11
- FDIS: "50.00",
12
- PRF: "60.00",
13
- IS: "60.60" }.freeze
9
+ CD: %w[30.00 30.20 30.60 30.92 30.98 30.99],
10
+ PRF: "60.00" }.freeze
14
11
 
15
12
 
13
+ STAGE_NAMES = {
14
+ WD: "Working Draft",
15
+ PWI: "Preliminary Work Item",
16
+ NP: "New Proposal",
17
+ CD: "Committee Draft",
18
+ PRF: "Proof of a new International Standard",
19
+ }.freeze
20
+
16
21
  # @param abbr [String, Symbol] abbreviation eg. :PWI, :WD
17
22
  # @param harmonized_code [String, Float, HarmonizedStageCode]
18
23
  def initialize(abbr: nil, harmonized_code: nil)
@@ -22,27 +27,38 @@ module Pubid::Iso
22
27
  @harmonized_code = if harmonized_code.is_a?(HarmonizedStageCode)
23
28
  harmonized_code
24
29
  else
25
- HarmonizedStageCode.new(*harmonized_code.to_s.split("."))
30
+ HarmonizedStageCode.new(harmonized_code)
26
31
  end
27
- @abbr ||= lookup_abbr(@harmonized_code.to_s) || lookup_abbr("#{@harmonized_code.stage}.00")
32
+ @abbr ||= lookup_abbr(@harmonized_code.stages)
33
+ # unless @harmonized_code.fuzzy?
34
+ # @abbr ||= lookup_abbr(@harmonized_code.to_s) || lookup_abbr("#{@harmonized_code.stage}.00")
35
+ # end
28
36
  end
29
37
 
30
38
  if abbr
31
39
  raise Errors::StageInvalidError, "#{abbr} is not valid stage" unless STAGES.key?(abbr.to_sym)
32
40
 
33
- @harmonized_code ||= HarmonizedStageCode.new(*lookup_code(abbr).split("."))
41
+ @harmonized_code ||= HarmonizedStageCode.new(lookup_code(abbr))
34
42
  end
35
43
  end
36
44
 
37
45
  # Lookup for abbreviated code by numeric stage code
38
- # @param lookup_code [String] stage code, e.g. "00.00", "20.20"
46
+ # @param lookup_code [String, Array] stage code or array of stage codes,
47
+ # e.g. "00.00", "20.20", ["00.00", "00.20"]
39
48
  def lookup_abbr(lookup_code)
49
+ lookup_code = lookup_code.first if lookup_code.is_a?(Array) && lookup_code.count == 1
50
+
40
51
  STAGES.each do |abbr, codes|
41
52
  case codes
42
53
  when Array
43
- codes.each do |code|
44
- return abbr if code == lookup_code
54
+ if lookup_code.is_a?(Array)
55
+ return abbr if codes == lookup_code
56
+ else
57
+ return abbr if codes.include?(lookup_code)
45
58
  end
59
+ # codes.each do |code|
60
+ # return abbr if code == lookup_code
61
+ # end
46
62
  when lookup_code
47
63
  return abbr
48
64
  end
@@ -52,8 +68,8 @@ module Pubid::Iso
52
68
  end
53
69
 
54
70
  def lookup_code(lookup_abbr)
55
- code = STAGES[lookup_abbr.to_sym]
56
- code.is_a?(Array) ? code.first : code
71
+ STAGES[lookup_abbr.to_sym]
72
+ # code.is_a?(Array) ? code.first : code
57
73
  end
58
74
 
59
75
  def self.parse(stage)
@@ -66,9 +82,22 @@ module Pubid::Iso
66
82
  end
67
83
  end
68
84
 
85
+ def self.has_stage?(stage)
86
+ if stage.is_a?(Stage)
87
+ STAGES.key?(stage.abbr.to_sym)
88
+ else
89
+ STAGES.key?(stage.to_sym) || /\A[\d.]+\z/.match?(stage)
90
+ end
91
+ end
92
+
69
93
  # Compares one stage with another
70
94
  def ==(other)
71
95
  other&.harmonized_code == harmonized_code
72
96
  end
97
+
98
+ # Return stage name, eg. "Draft International Standard" for "DIS"
99
+ def name
100
+ STAGE_NAMES[abbr.to_sym]
101
+ end
73
102
  end
74
103
  end
@@ -1,34 +1,36 @@
1
1
  module Pubid::Iso
2
2
  class Supplement < Pubid::Core::Supplement
3
- attr_accessor :stage, :publisher, :edition, :iteration
3
+ attr_accessor :typed_stage, :publisher, :edition, :iteration
4
4
 
5
5
  # @param stage [Stage, Symbol, String] stage, e.g. "PWI", "NP", "50.00", Stage.new(abbr: :WD)
6
- # @param publisher [String] publisher, e.g. "ISO", "IEC"
6
+ # @param publisher [String] publisher, e.g. "ISO", "IEC" (only for DIR documents)
7
7
  # @param edition [Integer] edition, e.g. 1, 2, 3
8
8
  # @param iteration [Integer] iteration, e.g. 1, 2, 3
9
9
  # @see Pubid::Core::Supplement for other options
10
- def initialize(stage: nil, publisher: nil, edition: nil, iteration: nil, **args)
10
+ def initialize(typed_stage: nil, publisher: nil, edition: nil, iteration: nil, **args)
11
11
  super(**args)
12
- @stage = stage.is_a?(Stage) ? stage : Stage.parse(stage) if stage
12
+ @typed_stage = TypedStage.parse(typed_stage) if typed_stage
13
+ # for DIR identifiers only
13
14
  @publisher = publisher.to_s
14
15
  @edition = edition&.to_i
15
16
  @iteration = iteration&.to_i
16
17
 
17
- if @iteration && @stage.nil?
18
+ if @iteration && @typed_stage.nil?
18
19
  raise Errors::PublishedIterationError.new("cannot assign iteration to published supplement")
19
20
  end
20
21
  end
21
22
 
22
23
  def render_pubid_stage
23
- ((@stage && @stage.abbr != "IS" && @stage.abbr) || "")
24
+ # @typed_stage.stage.abbr != "IS" &&
25
+ ((@typed_stage && @typed_stage.to_s) || "")
24
26
  end
25
27
 
26
28
  def render_urn_stage
27
- ((@stage && ":stage-#{@stage.harmonized_code}") || "")
29
+ ((@typed_stage&.stage && ":stage-#{@typed_stage.stage.harmonized_code}") || "")
28
30
  end
29
31
 
30
32
  def <=>(other)
31
- (super == 0) && ((stage.nil? || stage == other.stage) && 0 || -1) || super
33
+ (super == 0) && ((typed_stage.nil? || typed_stage == other.typed_stage) && 0 || -1) || super
32
34
  end
33
35
 
34
36
  def render_iteration
@@ -8,13 +8,47 @@ module Pubid::Iso
8
8
  { stage: convert_stage(context[:stage]) }
9
9
  end
10
10
 
11
+ rule(supplements: subtree(:supplements)) do |context|
12
+ context[:supplements] =
13
+ context[:supplements].map do |supplement|
14
+ supplement[:typed_stage] = case supplement[:typed_stage]
15
+ when "PDAM"
16
+ "CD Amd"
17
+ when "pDCOR"
18
+ "CD Cor"
19
+ when "FCOR"
20
+ "FDCor"
21
+ when "FPDAM"
22
+ "DAmd"
23
+ when "FDAM"
24
+ "FDAmd"
25
+ else
26
+ supplement[:typed_stage]
27
+ end
28
+ # Supplement.new(
29
+ # number: supplement[:number],
30
+ # year: supplement[:year],
31
+ # typed_stage:
32
+ # case supplement[:typed_stage]
33
+ # when "FCOR"
34
+ # "FDCor"
35
+ # else
36
+ # supplement[:typed_stage]
37
+ # end,
38
+ # iteration: supplement[:iteration]
39
+ # )
40
+ supplement
41
+ end
42
+ context
43
+ end
44
+
11
45
  rule(amendments: subtree(:amendments)) do |context|
12
46
  context[:amendments] =
13
47
  context[:amendments].map do |amendment|
14
48
  Amendment.new(
15
49
  number: amendment[:number],
16
50
  year: amendment[:year],
17
- stage: amendment[:stage] && convert_stage(amendment[:stage]),
51
+ typed_stage: amendment[:stage] && convert_stage(amendment[:stage]),
18
52
  iteration: amendment[:iteration])
19
53
  end
20
54
  context
@@ -26,7 +60,7 @@ module Pubid::Iso
26
60
  Corrigendum.new(
27
61
  number: corrigendum[:number],
28
62
  year: corrigendum[:year],
29
- stage: corrigendum[:stage] && convert_stage(corrigendum[:stage]),
63
+ typed_stage: corrigendum[:stage] && convert_stage(corrigendum[:stage]),
30
64
  iteration: corrigendum[:iteration])
31
65
  end
32
66
  context
@@ -44,21 +78,26 @@ module Pubid::Iso
44
78
 
45
79
  rule(type: simple(:type)) do
46
80
  russian_type = Renderer::Russian::TYPE.key(type.to_s)
47
- { type: russian_type&.to_s ||
48
- case type
49
- # XXX: can't put 2 alternative Russian translations to dictionary, temporary hack
50
- when "GUIDE", "Руководства"
51
- "Guide"
52
- when "ТС"
53
- "TS"
54
- when "ТО"
55
- "TR"
56
- when "Directives Part", "Directives, Part", "Directives,"
57
- "DIR"
58
- else
59
- type
60
- end
61
- }
81
+ { type: Type.new(russian_type&.downcase&.to_sym ||
82
+ case type
83
+ # XXX: can't put 2 alternative Russian translations to dictionary, temporary hack
84
+ when "GUIDE", "Guide", "Руководства"
85
+ :guide
86
+ when "ТС", "TS"
87
+ :ts
88
+ when "ТО", "TR"
89
+ :tr
90
+ when "Directives Part", "Directives, Part", "Directives,"
91
+ :dir
92
+ when "PAS"
93
+ :pas
94
+ when "DPAS"
95
+ :dpas
96
+ when "DIR"
97
+ :dir
98
+ else
99
+ type
100
+ end) }
62
101
  end
63
102
 
64
103
  rule(copublisher: simple(:copublisher)) do
@@ -119,12 +158,17 @@ module Pubid::Iso
119
158
  "FDIS"
120
159
  when "Fpr"
121
160
  "PRF"
122
- when "pD", "PD"
123
- "CD"
161
+ # when "pD", "PD"
162
+ # "CD"
163
+ when "PDTR"
164
+ "CD TR"
165
+ when "PDTS"
166
+ "CD TS"
124
167
  else
125
168
  code
126
169
  end
127
- Stage.new(abbr: (russian_code || code))
170
+ russian_code || code
171
+ # Stage.new(abbr: (russian_code || code))
128
172
  end
129
173
 
130
174
  def self.convert_language(code)
@@ -0,0 +1,77 @@
1
+ module Pubid::Iso
2
+ class Type
3
+ attr_accessor :type
4
+
5
+ TYPE_NAMES = {
6
+ tr: {
7
+ long: "Technical Report",
8
+ short: "TR",
9
+ },
10
+ ts: {
11
+ long: "Technical Specification",
12
+ short: "TS",
13
+ },
14
+ is: {
15
+ long: "International Standard",
16
+ short: "IS",
17
+ },
18
+ pas: {
19
+ long: "Publicly Available Specification",
20
+ short: "PAS",
21
+ },
22
+ isp: {
23
+ long: "International Standardized Profiles",
24
+ short: "ISP",
25
+ },
26
+ guide: {
27
+ long: "Guide",
28
+ short: "Guide",
29
+ },
30
+ dir: {
31
+ long: "Directives",
32
+ short: "DIR",
33
+ },
34
+ dpas: {
35
+ long: "Publicly Available Specification Draft",
36
+ short: "DPAS",
37
+ },
38
+ cor: {
39
+ short: "Cor",
40
+ },
41
+ amd: {
42
+ short: "Amd",
43
+ },
44
+ }.freeze
45
+
46
+ # Create new type
47
+ # @param type [Symbol]
48
+ def initialize(type)
49
+ raise Errors::WrongTypeError, "#{type} type is not available" unless TYPE_NAMES.key?(type)
50
+
51
+ @type = type
52
+ end
53
+
54
+ def self.parse(type_string)
55
+ TYPE_NAMES.each do |type, values|
56
+ return new(type) if values[:short] == type_string
57
+ end
58
+ raise Errors::ParseTypeError, "Cannot parse '#{type_string}' type"
59
+ end
60
+
61
+ def to_s(format = :short)
62
+ TYPE_NAMES[type][format]
63
+ end
64
+
65
+ def ==(other)
66
+ return type == other if other.is_a?(Symbol)
67
+
68
+ type == other.type
69
+ end
70
+
71
+ def self.has_type?(type)
72
+ TYPE_NAMES.any? do |_, v|
73
+ v[:short] == type
74
+ end
75
+ end
76
+ end
77
+ end