relaton-bib 1.14.5 → 1.14.6
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 +4 -4
- data/.rubocop.yml +1 -1
- data/lib/relaton_bib/bibliographic_item.rb +4 -271
- data/lib/relaton_bib/forename.rb +1 -1
- data/lib/relaton_bib/formatted_string.rb +1 -1
- data/lib/relaton_bib/hash_converter.rb +4 -2
- data/lib/relaton_bib/hit.rb +3 -1
- data/lib/relaton_bib/medium.rb +1 -1
- data/lib/relaton_bib/renderer/bibtex_builder.rb +1 -1
- data/lib/relaton_bib/renderer/bibxml.rb +290 -0
- data/lib/relaton_bib/version.rb +1 -1
- data/lib/relaton_bib.rb +6 -3
- data/relaton-bib.gemspec +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a4d2a5d90a56a9b93f34acc0d037d101130c36b34a4d436c28c6dc8c53496eb
|
4
|
+
data.tar.gz: 2b99e61f20b08a6ca48a2b42c16abef7cfe0e9f4340e413d1e37a4ff3e098969
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d1f0ec61452cdc6bdedde4bd1025a2aa9d3baeeeaa65f3e3b212aa56cd2753afee04dccc13870a1bea5e88b388a97e086adea56353272204a49251b46145384
|
7
|
+
data.tar.gz: 880ddde78e8fc665caf7b7a104efecd476c5787d34f839f73a7f1bc70425b6872dcd68bdaa7305fc751eb7cfe6e5c3395fa9df69771bec0634ceccdfdf66f890
|
data/.rubocop.yml
CHANGED
@@ -151,7 +151,7 @@ module RelatonBib
|
|
151
151
|
# @param series [Array<RelatonBib::Series>]
|
152
152
|
# @param medium [RelatonBib::Medium, nil]
|
153
153
|
# @param place [Array<String, RelatonBib::Place>]
|
154
|
-
# @param extent [Array<
|
154
|
+
# @param extent [Array<RelatonBib::Locality, RelatonBib::LocalityStack>]
|
155
155
|
# @param accesslocation [Array<String>]
|
156
156
|
# @param classification [Array<RelatonBib::Classification>]
|
157
157
|
# @param validity [RelatonBib:Validity, nil]
|
@@ -378,13 +378,7 @@ module RelatonBib
|
|
378
378
|
# @return [String, Nokogiri::XML::Builder::NodeBuilder] XML
|
379
379
|
#
|
380
380
|
def to_bibxml(builder = nil, include_keywords: false)
|
381
|
-
|
382
|
-
render_bibxml builder, include_keywords
|
383
|
-
else
|
384
|
-
Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
|
385
|
-
render_bibxml xml, include_keywords
|
386
|
-
end.doc.root.to_xml
|
387
|
-
end
|
381
|
+
Renderer::BibXML.new(self).render builder: builder, include_keywords: include_keywords
|
388
382
|
end
|
389
383
|
|
390
384
|
# @return [Hash]
|
@@ -499,6 +493,8 @@ module RelatonBib
|
|
499
493
|
ttl = me.title.select do |t|
|
500
494
|
t.type != "main" && t.title.language&.include?(l)
|
501
495
|
end
|
496
|
+
next if ttl.empty?
|
497
|
+
|
502
498
|
tm_en = ttl.map { |t| t.title.content }.join " – "
|
503
499
|
me.title.detect do |t|
|
504
500
|
t.type == "main" && t.title.language&.include?(l)
|
@@ -657,268 +653,5 @@ module RelatonBib
|
|
657
653
|
xml["schema-version"] = schema unless opts[:embedded]
|
658
654
|
xml
|
659
655
|
end
|
660
|
-
|
661
|
-
#
|
662
|
-
# Render BibXML (RFC, BCP)
|
663
|
-
#
|
664
|
-
# @param [Nokogiri::XML::Builder] builder
|
665
|
-
# @param [Boolean] include_bibdata
|
666
|
-
#
|
667
|
-
def render_bibxml(builder, include_keywords) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
668
|
-
target = link.detect { |l| l.type.casecmp("src").zero? } ||
|
669
|
-
link.detect { |l| l.type.casecmp("doi").zero? }
|
670
|
-
bxml = if docnumber&.match(/^BCP/) || (docidentifier.detect(&:primary)&.id ||
|
671
|
-
docidentifier[0].id).include?("BCP")
|
672
|
-
render_bibxml_refgroup(builder, include_keywords)
|
673
|
-
else
|
674
|
-
render_bibxml_ref(builder, include_keywords)
|
675
|
-
end
|
676
|
-
bxml[:target] = target.content.to_s if target
|
677
|
-
end
|
678
|
-
|
679
|
-
#
|
680
|
-
# Render BibXML (BCP)
|
681
|
-
#
|
682
|
-
# @param [Nokogiri::XML::Builder] builder
|
683
|
-
# @param [Boolean] include_keywords
|
684
|
-
#
|
685
|
-
def render_bibxml_refgroup(builder, include_keywords)
|
686
|
-
builder.referencegroup(**ref_attrs) do |b|
|
687
|
-
relation.each do |r|
|
688
|
-
r.bibitem.to_bibxml(b, include_keywords: include_keywords) if r.type == "includes"
|
689
|
-
end
|
690
|
-
end
|
691
|
-
end
|
692
|
-
|
693
|
-
#
|
694
|
-
# Render BibXML (RFC)
|
695
|
-
#
|
696
|
-
# @param [Nokogiri::XML::Builder] builder
|
697
|
-
# @param [Boolean] include_keywords
|
698
|
-
#
|
699
|
-
def render_bibxml_ref(builder, include_keywords) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
700
|
-
builder.reference(**ref_attrs) do |xml|
|
701
|
-
if title.any? || contributor.any? || date.any? || abstract.any? ||
|
702
|
-
editorialgroup&.technical_committee&.any? ||
|
703
|
-
(include_keywords && keyword.any?)
|
704
|
-
xml.front do
|
705
|
-
xml.title title[0].title.content if title.any?
|
706
|
-
render_authors xml
|
707
|
-
render_date xml
|
708
|
-
render_workgroup xml
|
709
|
-
render_keyword xml if include_keywords
|
710
|
-
render_abstract xml
|
711
|
-
end
|
712
|
-
end
|
713
|
-
render_seriesinfo xml
|
714
|
-
render_format xml
|
715
|
-
end
|
716
|
-
end
|
717
|
-
|
718
|
-
def render_format(builder)
|
719
|
-
link.select { |l| l.type == "TXT" }.each do |l|
|
720
|
-
builder.format type: l.type, target: l.content
|
721
|
-
end
|
722
|
-
end
|
723
|
-
|
724
|
-
#
|
725
|
-
# Create reference attributes
|
726
|
-
#
|
727
|
-
# @return [Hash<Symbol=>String>] attributes
|
728
|
-
#
|
729
|
-
def ref_attrs # rubocop:disable Metrics/AbcSize
|
730
|
-
discopes = %w[anchor docName number]
|
731
|
-
attrs = docidentifier.each_with_object({}) do |di, h|
|
732
|
-
next unless discopes.include?(di.scope)
|
733
|
-
|
734
|
-
h[di.scope.to_sym] = di.id
|
735
|
-
end
|
736
|
-
return attrs if attrs.any?
|
737
|
-
|
738
|
-
docidentifier.first&.tap do |di|
|
739
|
-
anchor = di.type == "IANA" ? di.id.split[1..-1].join(" ").upcase : di.id
|
740
|
-
return { anchor: anchor.gsub(" ", ".") }
|
741
|
-
end
|
742
|
-
end
|
743
|
-
|
744
|
-
#
|
745
|
-
# Render keyword
|
746
|
-
#
|
747
|
-
# @param [Nokogiri::XML::Builder] builder xml builder
|
748
|
-
#
|
749
|
-
def render_keyword(builder)
|
750
|
-
keyword.each { |kw| builder.keyword kw.content }
|
751
|
-
end
|
752
|
-
|
753
|
-
#
|
754
|
-
# Render workgroup
|
755
|
-
#
|
756
|
-
# @param [Nokogiri::XML::Builder] builder xml builder
|
757
|
-
#
|
758
|
-
def render_workgroup(builder)
|
759
|
-
editorialgroup&.technical_committee&.each do |tc|
|
760
|
-
builder.workgroup tc.workgroup.name
|
761
|
-
end
|
762
|
-
end
|
763
|
-
|
764
|
-
#
|
765
|
-
# Render abstract
|
766
|
-
#
|
767
|
-
# @param [Nokogiri::XML::Builder] builder xml builder
|
768
|
-
#
|
769
|
-
def render_abstract(builder)
|
770
|
-
return unless abstract.any?
|
771
|
-
|
772
|
-
builder.abstract { |xml| xml << abstract[0].content.gsub(/(<\/?)p(>)/, '\1t\2') }
|
773
|
-
end
|
774
|
-
|
775
|
-
#
|
776
|
-
# Render date
|
777
|
-
#
|
778
|
-
# @param [Nokogiri::XML::Builder] builder xml builder
|
779
|
-
#
|
780
|
-
def render_date(builder) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
781
|
-
dt = date.detect { |d| d.type == "published" }
|
782
|
-
return unless dt
|
783
|
-
|
784
|
-
elm = builder.date
|
785
|
-
y = dt.on(:year) || dt.from(:year) || dt.to(:year)
|
786
|
-
elm[:year] = y if y
|
787
|
-
m = dt.on(:month) || dt.from(:month) || dt.to(:month)
|
788
|
-
elm[:month] = Date::MONTHNAMES[m] if m
|
789
|
-
# rfcs = %w[RFC BCP FYI STD]
|
790
|
-
# unless rfcs.include?(doctype) && docidentifier.detect { |di| rfcs.include? di.type }
|
791
|
-
d = dt.on(:day) || dt.from(:day) || dt.to(:day)
|
792
|
-
elm[:day] = d if d
|
793
|
-
# end
|
794
|
-
end
|
795
|
-
|
796
|
-
#
|
797
|
-
# Render seriesinfo
|
798
|
-
#
|
799
|
-
# @param [Nokogiri::XML::Builder] builder xml builder
|
800
|
-
#
|
801
|
-
def render_seriesinfo(builder) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
802
|
-
docidentifier.each do |di|
|
803
|
-
if BibXMLParser::SERIESINFONAMES.include? di.type
|
804
|
-
builder.seriesInfo(name: di.type, value: di.id)
|
805
|
-
end
|
806
|
-
end
|
807
|
-
# di_types = docidentifier.map(&:type)
|
808
|
-
series.select do |s|
|
809
|
-
s.title && # !di_types.include?(s.title.title.to_s) &&
|
810
|
-
!BibXMLParser::SERIESINFONAMES.include?(s.title.title.to_s)
|
811
|
-
end.uniq { |s| s.title.title.to_s }.each do |s|
|
812
|
-
si = builder.seriesInfo(name: s.title.title.to_s)
|
813
|
-
si[:value] = s.number if s.number
|
814
|
-
end
|
815
|
-
end
|
816
|
-
|
817
|
-
#
|
818
|
-
# Render authors
|
819
|
-
#
|
820
|
-
# @param [Nokogiri::XML::Builder] builder xml builder
|
821
|
-
#
|
822
|
-
def render_authors(builder) # rubocop:disable Metrics/AbcSize
|
823
|
-
contributor.each do |c|
|
824
|
-
builder.author do |xml|
|
825
|
-
xml.parent[:role] = "editor" if c.role.detect { |r| r.type == "editor" }
|
826
|
-
if c.entity.is_a?(Person) then render_person xml, c.entity
|
827
|
-
else render_organization xml, c.entity, c.role
|
828
|
-
end
|
829
|
-
render_address xml, c
|
830
|
-
end
|
831
|
-
end
|
832
|
-
end
|
833
|
-
|
834
|
-
#
|
835
|
-
# Render address
|
836
|
-
#
|
837
|
-
# @param [Nokogiri::XML::Builder] builder xml builder
|
838
|
-
# @param [RelatonBib::ContributionInfo] contrib contributor
|
839
|
-
#
|
840
|
-
def render_address(builder, contrib) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
841
|
-
# addr = contrib.entity.contact.reject do |cn|
|
842
|
-
# cn.is_a?(Address) && cn.postcode.nil?
|
843
|
-
# end
|
844
|
-
if contrib.entity.contact.any?
|
845
|
-
builder.address do |xml|
|
846
|
-
address = contrib.entity.contact.detect { |cn| cn.is_a? Address }
|
847
|
-
if address
|
848
|
-
xml.postal do
|
849
|
-
xml.city address.city if address.city
|
850
|
-
xml.code address.postcode if address.postcode
|
851
|
-
xml.country address.country if address.country
|
852
|
-
xml.region address.state if address.state
|
853
|
-
xml.street address.street[0] if address.street.any?
|
854
|
-
end
|
855
|
-
end
|
856
|
-
render_contact xml, contrib.entity.contact
|
857
|
-
end
|
858
|
-
end
|
859
|
-
end
|
860
|
-
|
861
|
-
#
|
862
|
-
# Render contact
|
863
|
-
#
|
864
|
-
# @param [Nokogiri::XML::Builder] builder xml builder
|
865
|
-
# @param [Array<RelatonBib::Address, RelatonBib::Contact>] addr contact
|
866
|
-
#
|
867
|
-
def render_contact(builder, addr)
|
868
|
-
%w[phone email uri].each do |type|
|
869
|
-
cont = addr.detect { |cn| cn.is_a?(Contact) && cn.type == type }
|
870
|
-
builder.send type, cont.value if cont
|
871
|
-
end
|
872
|
-
end
|
873
|
-
|
874
|
-
#
|
875
|
-
# Render person
|
876
|
-
#
|
877
|
-
# @param [Nokogiri::XML::Builder] builder xml builder
|
878
|
-
# @param [RelatonBib::Person] person person
|
879
|
-
#
|
880
|
-
def render_person(builder, person) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
881
|
-
render_organization builder, person.affiliation.first&.organization
|
882
|
-
if person.name.completename
|
883
|
-
builder.parent[:fullname] = person.name.completename.content
|
884
|
-
elsif person.name.forename.any?
|
885
|
-
builder.parent[:fullname] = person.name.forename.map do |n|
|
886
|
-
n.content || n.initial
|
887
|
-
end.join " "
|
888
|
-
end
|
889
|
-
if person.name.initials
|
890
|
-
builder.parent[:initials] = person.name.initials.content
|
891
|
-
elsif person.name.forename.any?
|
892
|
-
builder.parent[:initials] = person.name.forename.map do |f|
|
893
|
-
"#{f.initial || f.content[0]}."
|
894
|
-
end.join
|
895
|
-
end
|
896
|
-
if person.name.surname
|
897
|
-
if !person.name.completename && person.name.forename.any? && person.name.surname
|
898
|
-
builder.parent[:fullname] += " #{person.name.surname}"
|
899
|
-
end
|
900
|
-
builder.parent[:surname] = person.name.surname.content
|
901
|
-
end
|
902
|
-
end
|
903
|
-
|
904
|
-
#
|
905
|
-
# Render organization
|
906
|
-
#
|
907
|
-
# @param [Nokogiri::XML::Builder] builder xml builder
|
908
|
-
# @param [RelatonBib::Organization] org organization
|
909
|
-
#
|
910
|
-
def render_organization(builder, org, _role = []) # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/AbcSize
|
911
|
-
abbrev = org&.abbreviation&.content
|
912
|
-
orgname = org&.name&.first&.content
|
913
|
-
orgname = if BibXMLParser::ORGNAMES.key?(abbrev) then abbrev
|
914
|
-
else BibXMLParser::ORGNAMES.key(orgname) || orgname || abbrev
|
915
|
-
end
|
916
|
-
# if role.detect { |r| r.description.detect { |d| d.content == "BibXML author" } }
|
917
|
-
# builder.parent[:fullname] = orgname
|
918
|
-
# else
|
919
|
-
org = builder.organization orgname
|
920
|
-
org[:abbrev] = abbrev if abbrev
|
921
|
-
# end
|
922
|
-
end
|
923
656
|
end
|
924
657
|
end
|
data/lib/relaton_bib/forename.rb
CHANGED
@@ -122,7 +122,7 @@ module RelatonBib
|
|
122
122
|
str.gsub(/(?<=<)\w+:(?=\w+>)/, "").gsub(/(?<=<\/)\w+:(?=\w+>)/, "")
|
123
123
|
.gsub(/<i>/, "<em>").gsub(/<\/i>/, "</em>")
|
124
124
|
.gsub(/<b>/, "<strong>").gsub(/<\/b>/, "</strong>")
|
125
|
-
.gsub(/<(?!\/?(em|strong|stem|sup|sub|tt|br\s?\/|p))[^\s!]\/?.*?>/, "
|
125
|
+
.gsub(/<(?!\/?(em|strong|stem|sup|sub|tt|br\s?\/|p))[^\s!]\/?.*?>/, "")
|
126
126
|
.gsub(/\s+([.,:;!?<])/, "\\1").strip
|
127
127
|
end
|
128
128
|
end
|
@@ -282,7 +282,7 @@ module RelatonBib
|
|
282
282
|
return [] unless person[:affiliation]
|
283
283
|
|
284
284
|
RelatonBib.array(person[:affiliation]).map do |a|
|
285
|
-
a[:description] = RelatonBib.array(a[:description])
|
285
|
+
a[:description] = RelatonBib.array(a[:description]).map do |d|
|
286
286
|
cnt = if d.is_a?(Hash)
|
287
287
|
{ content: d[:content], language: d[:language],
|
288
288
|
script: d[:script], format: d[:format] }
|
@@ -323,7 +323,9 @@ module RelatonBib
|
|
323
323
|
return unless ret[:copyright]
|
324
324
|
|
325
325
|
ret[:copyright] = RelatonBib.array(ret[:copyright]).map do |c|
|
326
|
-
c[:owner] = RelatonBib.array(c[:owner])
|
326
|
+
c[:owner] = RelatonBib.array(c[:owner]).map do |o|
|
327
|
+
org_hash_to_bib(o)
|
328
|
+
end
|
327
329
|
c
|
328
330
|
end
|
329
331
|
end
|
data/lib/relaton_bib/hit.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "weakref"
|
2
|
+
|
1
3
|
module RelatonBib
|
2
4
|
class Hit
|
3
5
|
# @return [RelatonBib::HitCollection]
|
@@ -10,7 +12,7 @@ module RelatonBib
|
|
10
12
|
# @param hit_collection [RelatonBib::HitCollection]
|
11
13
|
def initialize(hit, hit_collection = nil)
|
12
14
|
@hit = hit
|
13
|
-
@hit_collection = hit_collection
|
15
|
+
@hit_collection = WeakRef.new hit_collection if hit_collection
|
14
16
|
end
|
15
17
|
|
16
18
|
# @return [String]
|
data/lib/relaton_bib/medium.rb
CHANGED
@@ -11,7 +11,7 @@ module RelatonBib
|
|
11
11
|
# @param form [String, nil] form of the medium
|
12
12
|
# @param carrier [String, nil] carrier of the medium
|
13
13
|
# @param size [String, nil] size of the medium
|
14
|
-
# @param scale [String, nil]
|
14
|
+
# @param scale [String, nil]
|
15
15
|
#
|
16
16
|
def initialize(**args)
|
17
17
|
@content = args[:content]
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Monkey patch to fix the issue with month quotes in BibTeX
|
2
2
|
module BibTeX
|
3
3
|
class Value
|
4
|
-
def to_s(options = {})
|
4
|
+
def to_s(options = {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
5
5
|
if options.key?(:filter)
|
6
6
|
opts = options.reject { |k,| k == :filter || (k == :quotes && (!atomic? || symbol?)) }
|
7
7
|
return convert(options[:filter]).to_s(opts)
|
@@ -0,0 +1,290 @@
|
|
1
|
+
module RelatonBib
|
2
|
+
module Renderer
|
3
|
+
class BibXML
|
4
|
+
def initialize(bib)
|
5
|
+
@bib = bib
|
6
|
+
end
|
7
|
+
|
8
|
+
#
|
9
|
+
# Render BibXML (RFC)
|
10
|
+
#
|
11
|
+
# @param [Nokogiri::XML::Builder, nil] builder
|
12
|
+
# @param [Boolean] include_keywords (false)
|
13
|
+
#
|
14
|
+
# @return [String, Nokogiri::XML::Builder::NodeBuilder] XML
|
15
|
+
#
|
16
|
+
def render(builder: nil, include_keywords: true)
|
17
|
+
if builder
|
18
|
+
render_bibxml builder, include_keywords
|
19
|
+
else
|
20
|
+
Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
|
21
|
+
render_bibxml xml, include_keywords
|
22
|
+
end.doc.root.to_xml
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Render BibXML (RFC, BCP)
|
28
|
+
#
|
29
|
+
# @param [Nokogiri::XML::Builder] builder
|
30
|
+
# @param [Boolean] include_bibdata
|
31
|
+
#
|
32
|
+
def render_bibxml(builder, include_keywords) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
33
|
+
target = @bib.link.detect { |l| l.type.casecmp("src").zero? } ||
|
34
|
+
@bib.link.detect { |l| l.type.casecmp("doi").zero? }
|
35
|
+
bxml = if @bib.docnumber&.match(/^BCP/) || (@bib.docidentifier.detect(&:primary)&.id ||
|
36
|
+
@bib.docidentifier[0].id).include?("BCP")
|
37
|
+
render_bibxml_refgroup(builder, include_keywords)
|
38
|
+
else
|
39
|
+
render_bibxml_ref(builder, include_keywords)
|
40
|
+
end
|
41
|
+
bxml[:target] = target.content.to_s if target
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Render BibXML (BCP)
|
46
|
+
#
|
47
|
+
# @param [Nokogiri::XML::Builder] builder
|
48
|
+
# @param [Boolean] include_keywords
|
49
|
+
#
|
50
|
+
def render_bibxml_refgroup(builder, include_keywords)
|
51
|
+
builder.referencegroup(**ref_attrs) do |b|
|
52
|
+
@bib.relation.each do |r|
|
53
|
+
r.bibitem.to_bibxml(b, include_keywords: include_keywords) if r.type == "includes"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Render BibXML (RFC)
|
60
|
+
#
|
61
|
+
# @param [Nokogiri::XML::Builder] builder
|
62
|
+
# @param [Boolean] include_keywords
|
63
|
+
#
|
64
|
+
def render_bibxml_ref(builder, include_keywords) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
65
|
+
builder.reference(**ref_attrs) do |xml|
|
66
|
+
if @bib.title.any? || @bib.contributor.any? || @bib.date.any? || @bib.abstract.any? ||
|
67
|
+
@bib.editorialgroup&.technical_committee&.any? ||
|
68
|
+
(include_keywords && @bib.keyword.any?)
|
69
|
+
xml.front do
|
70
|
+
xml.title @bib.title[0].title.content if @bib.title.any?
|
71
|
+
render_authors xml
|
72
|
+
render_date xml
|
73
|
+
render_workgroup xml
|
74
|
+
render_keyword xml if include_keywords
|
75
|
+
render_abstract xml
|
76
|
+
end
|
77
|
+
end
|
78
|
+
render_seriesinfo xml
|
79
|
+
render_format xml
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# Create reference attributes
|
85
|
+
#
|
86
|
+
# @return [Hash<Symbol=>String>] attributes
|
87
|
+
#
|
88
|
+
def ref_attrs # rubocop:disable Metrics/AbcSize
|
89
|
+
discopes = %w[anchor docName number]
|
90
|
+
attrs = @bib.docidentifier.each_with_object({}) do |di, h|
|
91
|
+
next unless discopes.include?(di.scope)
|
92
|
+
|
93
|
+
h[di.scope.to_sym] = di.id
|
94
|
+
end
|
95
|
+
return attrs if attrs.any?
|
96
|
+
|
97
|
+
@bib.docidentifier.first&.tap do |di|
|
98
|
+
anchor = di.type == "IANA" ? di.id.split[1..].join(" ").upcase : di.id
|
99
|
+
return { anchor: anchor.gsub(" ", ".") }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# Render authors
|
105
|
+
#
|
106
|
+
# @param [Nokogiri::XML::Builder] builder xml builder
|
107
|
+
#
|
108
|
+
def render_authors(builder) # rubocop:disable Metrics/AbcSize
|
109
|
+
@bib.contributor.each do |c|
|
110
|
+
builder.author do |xml|
|
111
|
+
xml.parent[:role] = "editor" if c.role.detect { |r| r.type == "editor" }
|
112
|
+
if c.entity.is_a?(Person) then render_person xml, c.entity
|
113
|
+
else render_organization xml, c.entity, c.role
|
114
|
+
end
|
115
|
+
render_address xml, c
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
#
|
121
|
+
# Render address
|
122
|
+
#
|
123
|
+
# @param [Nokogiri::XML::Builder] builder xml builder
|
124
|
+
# @param [RelatonBib::ContributionInfo] contrib contributor
|
125
|
+
#
|
126
|
+
def render_address(builder, contrib) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
127
|
+
# addr = contrib.entity.contact.reject do |cn|
|
128
|
+
# cn.is_a?(Address) && cn.postcode.nil?
|
129
|
+
# end
|
130
|
+
if contrib.entity.contact.any?
|
131
|
+
builder.address do |xml|
|
132
|
+
address = contrib.entity.contact.detect { |cn| cn.is_a? Address }
|
133
|
+
if address
|
134
|
+
xml.postal do
|
135
|
+
xml.city address.city if address.city
|
136
|
+
xml.code address.postcode if address.postcode
|
137
|
+
xml.country address.country if address.country
|
138
|
+
xml.region address.state if address.state
|
139
|
+
xml.street address.street[0] if address.street.any?
|
140
|
+
end
|
141
|
+
end
|
142
|
+
render_contact xml, contrib.entity.contact
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
#
|
148
|
+
# Render contact
|
149
|
+
#
|
150
|
+
# @param [Nokogiri::XML::Builder] builder xml builder
|
151
|
+
# @param [Array<RelatonBib::Address, RelatonBib::Contact>] addr contact
|
152
|
+
#
|
153
|
+
def render_contact(builder, addr)
|
154
|
+
%w[phone email uri].each do |type|
|
155
|
+
cont = addr.detect { |cn| cn.is_a?(Contact) && cn.type == type }
|
156
|
+
builder.send type, cont.value if cont
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
#
|
161
|
+
# Render person
|
162
|
+
#
|
163
|
+
# @param [Nokogiri::XML::Builder] builder xml builder
|
164
|
+
# @param [RelatonBib::Person] person person
|
165
|
+
#
|
166
|
+
def render_person(builder, person) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
167
|
+
render_organization builder, person.affiliation.first&.organization
|
168
|
+
if person.name.completename
|
169
|
+
builder.parent[:fullname] = person.name.completename.content
|
170
|
+
elsif person.name.forename.any?
|
171
|
+
builder.parent[:fullname] = person.name.forename.map do |n|
|
172
|
+
n.content || n.initial
|
173
|
+
end.join " "
|
174
|
+
end
|
175
|
+
if person.name.initials
|
176
|
+
builder.parent[:initials] = person.name.initials.content
|
177
|
+
elsif person.name.forename.any?
|
178
|
+
builder.parent[:initials] = person.name.forename.map do |f|
|
179
|
+
"#{f.initial || f.content[0]}."
|
180
|
+
end.join
|
181
|
+
end
|
182
|
+
if person.name.surname
|
183
|
+
if !person.name.completename && person.name.forename.any? && person.name.surname
|
184
|
+
builder.parent[:fullname] += " #{person.name.surname}"
|
185
|
+
end
|
186
|
+
builder.parent[:surname] = person.name.surname.content
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
#
|
191
|
+
# Render organization
|
192
|
+
#
|
193
|
+
# @param [Nokogiri::XML::Builder] builder xml builder
|
194
|
+
# @param [RelatonBib::Organization] org organization
|
195
|
+
#
|
196
|
+
def render_organization(builder, org, _role = []) # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/AbcSize
|
197
|
+
abbrev = org&.abbreviation&.content
|
198
|
+
orgname = org&.name&.first&.content
|
199
|
+
orgname = if BibXMLParser::ORGNAMES.key?(abbrev) then abbrev
|
200
|
+
else BibXMLParser::ORGNAMES.key(orgname) || orgname || abbrev
|
201
|
+
end
|
202
|
+
# if role.detect { |r| r.description.detect { |d| d.content == "BibXML author" } }
|
203
|
+
# builder.parent[:fullname] = orgname
|
204
|
+
# else
|
205
|
+
org = builder.organization orgname
|
206
|
+
org[:abbrev] = abbrev if abbrev
|
207
|
+
# end
|
208
|
+
end
|
209
|
+
|
210
|
+
#
|
211
|
+
# Render date
|
212
|
+
#
|
213
|
+
# @param [Nokogiri::XML::Builder] builder xml builder
|
214
|
+
#
|
215
|
+
def render_date(builder) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
216
|
+
dt = @bib.date.detect { |d| d.type == "published" }
|
217
|
+
return unless dt
|
218
|
+
|
219
|
+
elm = builder.date
|
220
|
+
y = dt.on(:year) || dt.from(:year) || dt.to(:year)
|
221
|
+
elm[:year] = y if y
|
222
|
+
m = dt.on(:month) || dt.from(:month) || dt.to(:month)
|
223
|
+
elm[:month] = Date::MONTHNAMES[m] if m
|
224
|
+
# rfcs = %w[RFC BCP FYI STD]
|
225
|
+
# unless rfcs.include?(doctype) && docidentifier.detect { |di| rfcs.include? di.type }
|
226
|
+
d = dt.on(:day) || dt.from(:day) || dt.to(:day)
|
227
|
+
elm[:day] = d if d
|
228
|
+
# end
|
229
|
+
end
|
230
|
+
|
231
|
+
#
|
232
|
+
# Render workgroup
|
233
|
+
#
|
234
|
+
# @param [Nokogiri::XML::Builder] builder xml builder
|
235
|
+
#
|
236
|
+
def render_workgroup(builder)
|
237
|
+
@bib.editorialgroup&.technical_committee&.each do |tc|
|
238
|
+
builder.workgroup tc.workgroup.name
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
#
|
243
|
+
# Render keyword
|
244
|
+
#
|
245
|
+
# @param [Nokogiri::XML::Builder] builder xml builder
|
246
|
+
#
|
247
|
+
def render_keyword(builder)
|
248
|
+
@bib.keyword.each { |kw| builder.keyword kw.content }
|
249
|
+
end
|
250
|
+
|
251
|
+
#
|
252
|
+
# Render abstract
|
253
|
+
#
|
254
|
+
# @param [Nokogiri::XML::Builder] builder xml builder
|
255
|
+
#
|
256
|
+
def render_abstract(builder)
|
257
|
+
return unless @bib.abstract.any?
|
258
|
+
|
259
|
+
builder.abstract { |xml| xml << @bib.abstract[0].content.gsub(/(<\/?)p(>)/, '\1t\2') }
|
260
|
+
end
|
261
|
+
|
262
|
+
#
|
263
|
+
# Render seriesinfo
|
264
|
+
#
|
265
|
+
# @param [Nokogiri::XML::Builder] builder xml builder
|
266
|
+
#
|
267
|
+
def render_seriesinfo(builder) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
268
|
+
@bib.docidentifier.each do |di|
|
269
|
+
if BibXMLParser::SERIESINFONAMES.include?(di.type) && di.scope != "trademark"
|
270
|
+
builder.seriesInfo(name: di.type, value: di.id)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
# di_types = docidentifier.map(&:type)
|
274
|
+
@bib.series.select do |s|
|
275
|
+
s.title && # !di_types.include?(s.title.title.to_s) &&
|
276
|
+
!BibXMLParser::SERIESINFONAMES.include?(s.title.title.to_s)
|
277
|
+
end.uniq { |s| s.title.title.to_s }.each do |s|
|
278
|
+
si = builder.seriesInfo(name: s.title.title.to_s)
|
279
|
+
si[:value] = s.number if s.number
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
def render_format(builder)
|
284
|
+
@bib.link.select { |l| l.type == "TXT" }.each do |l|
|
285
|
+
builder.format type: l.type, target: l.content
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
data/lib/relaton_bib/version.rb
CHANGED
data/lib/relaton_bib.rb
CHANGED
@@ -12,6 +12,7 @@ require "relaton_bib/hit_collection"
|
|
12
12
|
require "relaton_bib/hit"
|
13
13
|
require "relaton_bib/bibxml_parser"
|
14
14
|
require "relaton_bib/renderer/bibtex_builder"
|
15
|
+
require "relaton_bib/renderer/bibxml"
|
15
16
|
|
16
17
|
module RelatonBib
|
17
18
|
class Error < StandardError; end
|
@@ -67,15 +68,17 @@ module RelatonBib
|
|
67
68
|
# Parse yaml content
|
68
69
|
#
|
69
70
|
# @param [String] yaml content
|
71
|
+
# @param [Array] classes classes to be allowed
|
72
|
+
# @param [Boolean] symbolize_names symbolize names if true (default: false)
|
70
73
|
#
|
71
74
|
# @return [Hash] data
|
72
75
|
#
|
73
|
-
def parse_yaml(yaml, classes = [])
|
76
|
+
def parse_yaml(yaml, classes = [], symbolize_names: false)
|
74
77
|
# Newer versions of Psych uses the `permitted_classes:` parameter
|
75
78
|
if YAML.method(:safe_load).parameters.map(&:last).include? :permitted_classes
|
76
|
-
YAML.safe_load(yaml, permitted_classes: classes)
|
79
|
+
YAML.safe_load(yaml, permitted_classes: classes, symbolize_names: symbolize_names)
|
77
80
|
else
|
78
|
-
YAML.safe_load(yaml, classes)
|
81
|
+
YAML.safe_load(yaml, classes, symbolize_names: symbolize_names)
|
79
82
|
end
|
80
83
|
end
|
81
84
|
end
|
data/relaton-bib.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.bindir = "exe"
|
22
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
23
|
spec.require_paths = ["lib"]
|
24
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 2.
|
24
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
|
25
25
|
|
26
26
|
spec.add_development_dependency "byebug"
|
27
27
|
spec.add_development_dependency "equivalent-xml", "~> 0.6"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: relaton-bib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.14.
|
4
|
+
version: 1.14.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: byebug
|
@@ -267,6 +267,7 @@ files:
|
|
267
267
|
- lib/relaton_bib/person.rb
|
268
268
|
- lib/relaton_bib/place.rb
|
269
269
|
- lib/relaton_bib/renderer/bibtex_builder.rb
|
270
|
+
- lib/relaton_bib/renderer/bibxml.rb
|
270
271
|
- lib/relaton_bib/series.rb
|
271
272
|
- lib/relaton_bib/structured_identifier.rb
|
272
273
|
- lib/relaton_bib/technical_committee.rb
|
@@ -290,7 +291,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
290
291
|
requirements:
|
291
292
|
- - ">="
|
292
293
|
- !ruby/object:Gem::Version
|
293
|
-
version: 2.
|
294
|
+
version: 2.7.0
|
294
295
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
295
296
|
requirements:
|
296
297
|
- - ">="
|