relaton-bib 1.14.5 → 1.14.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
- - ">="
|