Class: RelatonBib::Renderer::BibXML

Inherits:
Object
  • Object
show all
Defined in:
lib/relaton_bib/renderer/bibxml.rb

Instance Method Summary collapse

Constructor Details

#initialize(bib) ⇒ BibXML

Returns a new instance of BibXML.



4
5
6
# File 'lib/relaton_bib/renderer/bibxml.rb', line 4

def initialize(bib)
  @bib = bib
end

Instance Method Details

#address_contact(contact) ⇒ Object

rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity



145
146
147
148
149
150
151
# File 'lib/relaton_bib/renderer/bibxml.rb', line 145

def address_contact(contact) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
  addr = contact.detect do |c|
    c.is_a?(Address) && (c.city || c.postcode || c.country || c.state || c.street.any?)
  end
  cont = contact.select { |c| c.is_a?(Contact) }
  [addr, cont]
end

#ref_attrsHash<Symbol=>String>

Create reference attributes

Returns:

  • (Hash<Symbol=>String>)

    attributes



88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/relaton_bib/renderer/bibxml.rb', line 88

def ref_attrs # rubocop:disable Metrics/AbcSize
  discopes = %w[anchor docName number]
  attrs = @bib.docidentifier.each_with_object({}) do |di, h|
    next unless discopes.include?(di.scope)

    h[di.scope.to_sym] = di.id
  end
  return attrs if attrs.any?

  @bib.docidentifier.first&.tap do |di|
    anchor = di.type == "IANA" ? di.id.split[1..].join(" ").upcase : di.id
    return { anchor: anchor.gsub(" ", ".") }
  end
end

#render(builder: nil, include_keywords: true) ⇒ String, Nokogiri::XML::Builder::NodeBuilder

Render BibXML (RFC)

Parameters:

  • builder (Nokogiri::XML::Builder, nil) (defaults to: nil)
  • include_keywords (Boolean) (defaults to: true)

    (false)

Returns:

  • (String, Nokogiri::XML::Builder::NodeBuilder)

    XML



16
17
18
19
20
21
22
23
24
# File 'lib/relaton_bib/renderer/bibxml.rb', line 16

def render(builder: nil, include_keywords: true)
  if builder
    render_bibxml builder, include_keywords
  else
    Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
      render_bibxml xml, include_keywords
    end.doc.root.to_xml
  end
end

#render_abstract(builder) ⇒ Object

Render abstract

Parameters:

  • builder (Nokogiri::XML::Builder)

    xml builder



262
263
264
265
266
# File 'lib/relaton_bib/renderer/bibxml.rb', line 262

def render_abstract(builder)
  return unless @bib.abstract.any?

  builder.abstract { |xml| xml << @bib.abstract[0].content.gsub(/(<\/?)p(>)/, '\1t\2') }
end

#render_address(builder, contrib) ⇒ Object

Render address

Parameters:



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/relaton_bib/renderer/bibxml.rb', line 126

def render_address(builder, contrib) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
  address, contact = address_contact contrib.entity.contact
  if address || contact.any?
    builder.address do |xml|
      # address = contrib.entity.contact.detect { |cn| cn.is_a? Address }
      if address
        xml.postal do
          xml.city address.city if address.city
          xml.code address.postcode if address.postcode
          xml.country address.country if address.country
          xml.region address.state if address.state
          xml.street address.street[0] if address.street.any?
        end
      end
      render_contact xml, contact
    end
  end
end

#render_authors(builder) ⇒ Object

Render authors

Parameters:

  • builder (Nokogiri::XML::Builder)

    xml builder



108
109
110
111
112
113
114
115
116
117
118
# File 'lib/relaton_bib/renderer/bibxml.rb', line 108

def render_authors(builder) # rubocop:disable Metrics/AbcSize
  @bib.contributor.each do |c|
    builder.author do |xml|
      xml.parent[:role] = "editor" if c.role.detect { |r| r.type == "editor" }
      if c.entity.is_a?(Person) then render_person xml, c.entity
      else render_organization xml, c.entity, c.role
      end
      render_address xml, c
    end
  end
end

#render_bibxml(builder, include_keywords) ⇒ Object

Render BibXML (RFC, BCP)

Parameters:

  • builder (Nokogiri::XML::Builder)
  • include_bibdata (Boolean)


32
33
34
35
36
37
38
39
40
41
42
# File 'lib/relaton_bib/renderer/bibxml.rb', line 32

def render_bibxml(builder, include_keywords) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
  target = @bib.link.detect { |l| l.type.casecmp("src").zero? } ||
    @bib.link.detect { |l| l.type.casecmp("doi").zero? }
  bxml = if @bib.docnumber&.match(/^BCP/) || (@bib.docidentifier.detect(&:primary)&.id ||
              @bib.docidentifier[0].id).include?("BCP")
           render_bibxml_refgroup(builder, include_keywords)
         else
           render_bibxml_ref(builder, include_keywords)
         end
  bxml[:target] = target.content.to_s if target
end

#render_bibxml_ref(builder, include_keywords) ⇒ Object

Render BibXML (RFC)

Parameters:

  • builder (Nokogiri::XML::Builder)
  • include_keywords (Boolean)


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/relaton_bib/renderer/bibxml.rb', line 64

def render_bibxml_ref(builder, include_keywords) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
  builder.reference(**ref_attrs) do |xml|
    if @bib.title.any? || @bib.contributor.any? || @bib.date.any? || @bib.abstract.any? ||
        @bib.editorialgroup&.technical_committee&.any? ||
        (include_keywords && @bib.keyword.any?)
      xml.front do
        xml.title @bib.title[0].title.content if @bib.title.any?
        render_authors xml
        render_date xml
        render_workgroup xml
        render_keyword xml if include_keywords
        render_abstract xml
      end
    end
    render_seriesinfo xml
    render_format xml
  end
end

#render_bibxml_refgroup(builder, include_keywords) ⇒ Object

Render BibXML (BCP)

Parameters:

  • builder (Nokogiri::XML::Builder)
  • include_keywords (Boolean)


50
51
52
53
54
55
56
# File 'lib/relaton_bib/renderer/bibxml.rb', line 50

def render_bibxml_refgroup(builder, include_keywords)
  builder.referencegroup(**ref_attrs) do |b|
    @bib.relation.each do |r|
      r.bibitem.to_bibxml(b, include_keywords: include_keywords) if r.type == "includes"
    end
  end
end

#render_contact(builder, addr) ⇒ Object

Render contact

Parameters:



159
160
161
162
163
164
# File 'lib/relaton_bib/renderer/bibxml.rb', line 159

def render_contact(builder, addr)
  %w[phone email uri].each do |type|
    cont = addr.detect { |cn| cn.is_a?(Contact) && cn.type == type }
    builder.send type, cont.value if cont
  end
end

#render_date(builder) ⇒ Object

Render date

Parameters:

  • builder (Nokogiri::XML::Builder)

    xml builder



221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/relaton_bib/renderer/bibxml.rb', line 221

def render_date(builder) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
  dt = @bib.date.detect { |d| d.type == "published" }
  return unless dt

  elm = builder.date
  y = dt.on(:year) || dt.from(:year) || dt.to(:year)
  elm[:year] = y if y
  m = dt.on(:month) || dt.from(:month) || dt.to(:month)
  elm[:month] = Date::MONTHNAMES[m] if m
  # rfcs = %w[RFC BCP FYI STD]
  # unless rfcs.include?(doctype) && docidentifier.detect { |di| rfcs.include? di.type }
  d = dt.on(:day) || dt.from(:day) || dt.to(:day)
  elm[:day] = d if d
  # end
end

#render_format(builder) ⇒ Object



289
290
291
292
293
# File 'lib/relaton_bib/renderer/bibxml.rb', line 289

def render_format(builder)
  @bib.link.select { |l| l.type == "TXT" }.each do |l|
    builder.format type: l.type, target: l.content
  end
end

#render_keyword(builder) ⇒ Object

Render keyword

Parameters:

  • builder (Nokogiri::XML::Builder)

    xml builder



253
254
255
# File 'lib/relaton_bib/renderer/bibxml.rb', line 253

def render_keyword(builder)
  @bib.keyword.each { |kw| builder.keyword kw.content }
end

#render_organization(builder, org, _role = []) ⇒ Object

Render organization

Parameters:



202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/relaton_bib/renderer/bibxml.rb', line 202

def render_organization(builder, org, _role = []) # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/AbcSize
  abbrev = org&.abbreviation&.content
  orgname = org&.name&.first&.content
  orgname = if BibXMLParser::ORGNAMES.key?(abbrev) then abbrev
            else BibXMLParser::ORGNAMES.key(orgname) || orgname || abbrev
            end
  # if role.detect { |r| r.description.detect { |d| d.content == "BibXML author" } }
  #   builder.parent[:fullname] = orgname
  # else
  org = builder.organization orgname
  org[:abbrev] = abbrev if abbrev
  # end
end

#render_person(builder, person) ⇒ Object

Render person

Parameters:



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/relaton_bib/renderer/bibxml.rb', line 172

def render_person(builder, person) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
  render_organization builder, person.affiliation.first&.organization
  if person.name.completename
    builder.parent[:fullname] = person.name.completename.content
  elsif person.name.forename.any?
    builder.parent[:fullname] = person.name.forename.map do |n|
      n.content || n.initial
    end.join " "
  end
  if person.name.initials
    builder.parent[:initials] = person.name.initials.content
  elsif person.name.forename.any?
    builder.parent[:initials] = person.name.forename.map do |f|
      "#{f.initial || f.content[0]}."
    end.join
  end
  if person.name.surname
    if !person.name.completename && person.name.forename.any? && person.name.surname
      builder.parent[:fullname] += " #{person.name.surname}"
    end
    builder.parent[:surname] = person.name.surname.content
  end
end

#render_seriesinfo(builder) ⇒ Object

Render seriesinfo

Parameters:

  • builder (Nokogiri::XML::Builder)

    xml builder



273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# File 'lib/relaton_bib/renderer/bibxml.rb', line 273

def render_seriesinfo(builder) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
  @bib.docidentifier.each do |di|
    if BibXMLParser::SERIESINFONAMES.include?(di.type) && di.scope != "trademark"
      builder.seriesInfo(name: di.type, value: di.id)
    end
  end
  # di_types = docidentifier.map(&:type)
  @bib.series.select do |s|
    s.title && # !di_types.include?(s.title.title.to_s) &&
      !BibXMLParser::SERIESINFONAMES.include?(s.title.title.to_s)
  end.uniq { |s| s.title.title.to_s }.each do |s|
    si = builder.seriesInfo(name: s.title.title.to_s)
    si[:value] = s.number if s.number
  end
end

#render_workgroup(builder) ⇒ Object

Render workgroup

Parameters:

  • builder (Nokogiri::XML::Builder)

    xml builder



242
243
244
245
246
# File 'lib/relaton_bib/renderer/bibxml.rb', line 242

def render_workgroup(builder)
  @bib.editorialgroup&.technical_committee&.each do |tc|
    builder.workgroup tc.workgroup.name
  end
end