relaton-bib 1.2.0 → 1.3.1

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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ubuntu.yml +1 -0
  3. data/.rubocop.yml +2 -2
  4. data/README.adoc +16 -0
  5. data/lib/relaton_bib.rb +15 -15
  6. data/lib/relaton_bib/bib_item_locality.rb +13 -1
  7. data/lib/relaton_bib/biblio_note.rb +11 -0
  8. data/lib/relaton_bib/biblio_version.rb +12 -0
  9. data/lib/relaton_bib/bibliographic_date.rb +13 -0
  10. data/lib/relaton_bib/bibliographic_item.rb +80 -24
  11. data/lib/relaton_bib/classification.rb +11 -0
  12. data/lib/relaton_bib/contribution_info.rb +27 -1
  13. data/lib/relaton_bib/contributor.rb +55 -1
  14. data/lib/relaton_bib/copyright_association.rb +14 -1
  15. data/lib/relaton_bib/document_identifier.rb +20 -4
  16. data/lib/relaton_bib/document_relation.rb +15 -5
  17. data/lib/relaton_bib/document_relation_collection.rb +12 -0
  18. data/lib/relaton_bib/document_status.rb +10 -0
  19. data/lib/relaton_bib/editorial_group.rb +9 -0
  20. data/lib/relaton_bib/formatted_ref.rb +7 -0
  21. data/lib/relaton_bib/formatted_string.rb +11 -0
  22. data/lib/relaton_bib/hash_converter.rb +55 -36
  23. data/lib/relaton_bib/ics.rb +11 -0
  24. data/lib/relaton_bib/localized_string.rb +23 -6
  25. data/lib/relaton_bib/medium.rb +11 -0
  26. data/lib/relaton_bib/organization.rb +27 -7
  27. data/lib/relaton_bib/person.rb +54 -7
  28. data/lib/relaton_bib/place.rb +13 -1
  29. data/lib/relaton_bib/series.rb +25 -4
  30. data/lib/relaton_bib/structured_identifier.rb +30 -0
  31. data/lib/relaton_bib/technical_committee.rb +11 -0
  32. data/lib/relaton_bib/typed_title_string.rb +13 -7
  33. data/lib/relaton_bib/typed_uri.rb +11 -0
  34. data/lib/relaton_bib/validity.rb +11 -0
  35. data/lib/relaton_bib/version.rb +1 -1
  36. data/lib/relaton_bib/workgroup.rb +10 -0
  37. data/lib/relaton_bib/xml_parser.rb +54 -39
  38. metadata +5 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d7395a60aab1daa2e260e12170c082a9131559420e6f9dc617e2d26ac199817
4
- data.tar.gz: 1c1a1d0308161cddfc67af2a1725cebd448b5464bf625e45d04e2139e877e442
3
+ metadata.gz: cfbf62a35f1d2fc87694f7e749f4a511dd6ec1962316857059e977ffe5e0ea88
4
+ data.tar.gz: 627c561a83b8e2cf1dbb14351383feb91ba6803dee8821a4e7d73ce1c3b96855
5
5
  SHA512:
6
- metadata.gz: d31d78f1eb0091bbfab575014d3255cb52dec3019f3b64178a9c7206999073c6e848ab143e1d005b4247be79457bf70914c0edff023aa132d9d67a1d2f9192e8
7
- data.tar.gz: 4640ecabf678c627ae47e7816a67e3ce5da01d00cba2e78672284b7ff2c366b8f9fcd8cb2aaedb5468f93af10f566a284df4a8c057530601afd55e80ca16b883
6
+ metadata.gz: 41107e963fa76a4dad2ebdff5d1fefd5d6c48ac61692027359489643c4b6e3f2185f0bc3ecbaa77462cd4b7c033cbe48e008255ae9ff072b403ada4146374870
7
+ data.tar.gz: 0d2a5739b3fe5f18aa9b17e7dbb87e00bc6a012a0e6f13831f9d06871992dbd7d9aa0f859621039fbbac6cf02a45eae859fa686c67ade23817431241110073d4
@@ -35,4 +35,5 @@ jobs:
35
35
  bundle install --jobs 4 --retry 3
36
36
  - name: Run specs
37
37
  run: |
38
+ unset JAVA_TOOL_OPTIONS
38
39
  bundle exec rake
@@ -5,6 +5,6 @@
5
5
  inherit_from:
6
6
  - https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
7
7
  AllCops:
8
- TargetRubyVersion: 2.3
8
+ TargetRubyVersion: 2.4
9
9
  Rails:
10
- Enabled: true
10
+ Enabled: false
@@ -380,6 +380,22 @@ item.to_bibtex
380
380
  ...
381
381
  ----
382
382
 
383
+ === Exporting bibliographic item to AsciiBib
384
+
385
+ [source,ruby]
386
+ ----
387
+ item.to_asciibib
388
+ [%bibitem]
389
+ == {blank}
390
+ id:: ISOTC211
391
+ fetched:: 2020-08-19
392
+ title::
393
+ title.type:: title-main
394
+ title.conten:: Geographic information
395
+ title.format:: text/plain
396
+ ...
397
+ ----
398
+
383
399
  == Development
384
400
 
385
401
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -10,31 +10,31 @@ module RelatonBib
10
10
  class RequestError < StandardError; end
11
11
 
12
12
  class << self
13
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
14
-
15
- # @param date [String]
13
+ # @param date [String, Integer, Date]
16
14
  # @return [Date, NilClass]
17
- def parse_date(sdate)
18
- if sdate.is_a?(Date) then sdate
19
- elsif /(?<date>\w+\s\d{4})/ =~ sdate # February 2012
20
- Date.strptime(date, "%B %Y")
21
- elsif /(?<date>\w+\s\d{1,2},\s\d{4})/ =~ sdate # February 11, 2012
22
- Date.strptime(date, "%B %d, %Y")
23
- elsif /(?<date>\d{4}-\d{2}-\d{2})/ =~ sdate # 2012-02-11
24
- Date.parse(date)
25
- elsif /(?<date>\d{4}-\d{2})/ =~ sdate # 2012-02
15
+ def parse_date(date) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
16
+ return date if date.is_a?(Date)
17
+
18
+ sdate = date.to_s
19
+ case sdate
20
+ when /(?<date>\w+\s\d{4})/ # February 2012
21
+ Date.strptime($~[:date], "%B %Y")
22
+ when /(?<date>\w+\s\d{1,2},\s\d{4})/ # February 11, 2012
23
+ Date.strptime($~[:date], "%B %d, %Y")
24
+ when /(?<date>\d{4}-\d{2}-\d{2})/ # 2012-02-11
25
+ Date.parse($~[:date])
26
+ when /(?<date>\d{4}-\d{2})/ # 2012-02
26
27
  Date.strptime date, "%Y-%m"
27
- elsif /(?<date>\d{4})/ =~ sdate then Date.strptime date, "%Y" # 2012
28
+ when /(?<date>\d{4})/ then Date.strptime $~[:date], "%Y" # 2012
28
29
  end
29
30
  end
30
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
31
31
  end
32
32
 
33
33
  private
34
34
 
35
35
  # @param array [Array]
36
36
  # @return [Array<String>, String]
37
- def single_element_array(array)
37
+ def single_element_array(array) # rubocop:disable Metrics/CyclomaticComplexity
38
38
  if array.size > 1
39
39
  array.map { |e| e.is_a?(String) ? e : e.to_hash }
40
40
  else
@@ -17,7 +17,7 @@ module RelatonBib
17
17
  type_ptrn = %r{section|clause|part|paragraph|chapter|page|whole|table|
18
18
  annex|figure|note|list|example|volume|issue|time|
19
19
  locality:[a-zA-Z0-9_]+}x
20
- unless type =~ type_ptrn
20
+ unless type.match? type_ptrn
21
21
  warn "[relaton-bib] WARNING: invalid locality type: #{type}"
22
22
  end
23
23
 
@@ -39,6 +39,18 @@ module RelatonBib
39
39
  hash["reference_to"] = reference_to if reference_to
40
40
  hash
41
41
  end
42
+
43
+ # @param prefix [String]
44
+ # @param count [Integeg] number of localities
45
+ # @return [String]
46
+ def to_asciibib(prefix = "", count = 1)
47
+ pref = prefix.empty? ? prefix : prefix + "."
48
+ out = count > 1 ? "#{prefix}::\n" : ""
49
+ out += "#{pref}type:: #{type}\n"
50
+ out += "#{pref}reference_from:: #{reference_from}\n"
51
+ out += "#{pref}reference_to:: #{reference_to}\n" if reference_to
52
+ out
53
+ end
42
54
  end
43
55
 
44
56
  class Locality < BibItemLocality
@@ -29,5 +29,16 @@ module RelatonBib
29
29
  hash["type"] = type
30
30
  hash
31
31
  end
32
+
33
+ # @param prefix [String]
34
+ # @param count [Integer] number of notes
35
+ # @return [String]
36
+ def to_asciibib(prefix = "", count = 1)
37
+ pref = prefix.empty? ? prefix : prefix + "."
38
+ out = count > 1 ? "#{pref}biblionote::\n" : ""
39
+ out + "#{pref}biblionote.type:: #{type}\n" if type
40
+ out += super "#{pref}biblionote"
41
+ out
42
+ end
32
43
  end
33
44
  end
@@ -32,6 +32,18 @@ module RelatonBib
32
32
  hash["draft"] = single_element_array(draft) if draft&.any?
33
33
  hash
34
34
  end
35
+
36
+ # @param prefix [String]
37
+ # @return [String]
38
+ def to_asciibib(prefix = "")
39
+ pref = prefix.empty? ? prefix : prefix + "."
40
+ out = ""
41
+ if revision_date
42
+ out += "#{pref}version.revision_date:: #{revision_date}\n"
43
+ end
44
+ draft&.each { |d| out += "#{pref}version.draft:: #{d}\n" }
45
+ out
46
+ end
35
47
  end
36
48
  end
37
49
  end
@@ -60,6 +60,19 @@ module RelatonBib
60
60
  hash
61
61
  end
62
62
 
63
+ # @param prefix [String]
64
+ # @param count [Integer] number of dates
65
+ # @return [String]
66
+ def to_asciibib(prefix = "", count = 1)
67
+ pref = prefix.empty? ? prefix : prefix + "."
68
+ out = count > 1 ? "#{pref}date::\n" : ""
69
+ out += "#{pref}date.type:: #{type}\n"
70
+ out += "#{pref}date.on:: #{on}\n" if on
71
+ out += "#{pref}date.from:: #{from}\n" if from
72
+ out += "#{pref}date.to:: #{to}\n" if to
73
+ out
74
+ end
75
+
63
76
  private
64
77
 
65
78
  # Formats date
@@ -237,13 +237,18 @@ module RelatonBib
237
237
  end
238
238
  @series = args.fetch :series, []
239
239
  @medium = args[:medium]
240
- @place = args.fetch(:place, []).map { |pl| pl.is_a?(String) ? Place.new(name: pl) : pl }
240
+ @place = args.fetch(:place, []).map do |pl|
241
+ pl.is_a?(String) ? Place.new(name: pl) : pl
242
+ end
241
243
  @extent = args[:extent] || []
242
244
  @accesslocation = args.fetch :accesslocation, []
243
245
  @classification = args.fetch :classification, []
244
246
  @validity = args[:validity]
245
- @fetched = args.fetch :fetched, nil # , Date.today # we should pass the fetched arg from scrappers
246
- @keyword = (args[:keyword] || []).map { |kw| LocalizedString.new(kw) }
247
+ # we should pass the fetched arg from scrappers
248
+ @fetched = args.fetch :fetched, nil
249
+ @keyword = (args[:keyword] || []).map do |kw|
250
+ LocalizedString.new(kw)
251
+ end
247
252
  @license = args.fetch :license, []
248
253
  @doctype = args[:doctype]
249
254
  @editorialgroup = args[:editorialgroup]
@@ -278,7 +283,7 @@ module RelatonBib
278
283
  end
279
284
 
280
285
  # @return [String]
281
- def shortref(identifier, **opts)
286
+ def shortref(identifier, **opts) # rubocop:disable Metrics/CyclomaticComplexity
282
287
  pubdate = date.select { |d| d.type == "published" }
283
288
  year = if opts[:no_year] || pubdate.empty? then ""
284
289
  else ":" + pubdate&.first&.on&.year.to_s
@@ -300,10 +305,8 @@ module RelatonBib
300
305
  end
301
306
  end
302
307
 
303
- # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
304
-
305
308
  # @return [Hash]
306
- def to_hash
309
+ def to_hash # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
307
310
  hash = {}
308
311
  hash["id"] = id if id
309
312
  hash["title"] = single_element_array(title) if title&.any?
@@ -312,7 +315,9 @@ module RelatonBib
312
315
  hash["docid"] = single_element_array(docidentifier) if docidentifier&.any?
313
316
  hash["docnumber"] = docnumber if docnumber
314
317
  hash["date"] = single_element_array(date) if date&.any?
315
- hash["contributor"] = single_element_array(contributor) if contributor&.any?
318
+ if contributor&.any?
319
+ hash["contributor"] = single_element_array(contributor)
320
+ end
316
321
  hash["edition"] = edition if edition
317
322
  hash["version"] = version.to_hash if version
318
323
  hash["revdate"] = revdate if revdate
@@ -328,8 +333,12 @@ module RelatonBib
328
333
  hash["medium"] = medium.to_hash if medium
329
334
  hash["place"] = single_element_array(place) if place&.any?
330
335
  hash["extent"] = single_element_array(extent) if extent&.any?
331
- hash["accesslocation"] = single_element_array(accesslocation) if accesslocation&.any?
332
- hash["classification"] = single_element_array(classification) if classification&.any?
336
+ if accesslocation&.any?
337
+ hash["accesslocation"] = single_element_array(accesslocation)
338
+ end
339
+ if classification&.any?
340
+ hash["classification"] = single_element_array(classification)
341
+ end
333
342
  hash["validity"] = validity.to_hash if validity
334
343
  hash["fetched"] = fetched.to_s if fetched
335
344
  hash["keyword"] = single_element_array(keyword) if keyword&.any?
@@ -342,11 +351,10 @@ module RelatonBib
342
351
  end
343
352
  hash
344
353
  end
345
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
346
354
 
347
355
  # @param bibtex [BibTeX::Bibliography, NilClass]
348
356
  # @return [String]
349
- def to_bibtex(bibtex = nil)
357
+ def to_bibtex(bibtex = nil) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
350
358
  item = BibTeX::Entry.new
351
359
  item.type = bibtex_type
352
360
  item.key = id
@@ -369,7 +377,6 @@ module RelatonBib
369
377
  bibtex << item
370
378
  bibtex.to_s
371
379
  end
372
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
373
380
 
374
381
  # @param lang [String] language code Iso639
375
382
  # @return [Array<RelatonIsoBib::TypedTitleString>]
@@ -391,7 +398,7 @@ module RelatonBib
391
398
 
392
399
  def deep_clone
393
400
  dump = Marshal.dump self
394
- Marshal.load dump
401
+ Marshal.load dump # rubocop:disable Security/MarshalLoad
395
402
  end
396
403
 
397
404
  def disable_id_attribute
@@ -399,17 +406,19 @@ module RelatonBib
399
406
  end
400
407
 
401
408
  # remove title part components and abstract
402
- def to_all_parts
409
+ def to_all_parts # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
403
410
  me = deep_clone
404
411
  me.disable_id_attribute
405
- me.relation << RelatonBib::DocumentRelation.new(
406
- type: "instance", bibitem: self,
407
- )
412
+ me.relation << DocumentRelation.new(type: "instance", bibitem: self)
408
413
  me.language.each do |l|
409
414
  me.title.delete_if { |t| t.type == "title-part" }
410
- ttl = me.title.select { |t| t.type != "main" && t.title.language&.include?(l) }
415
+ ttl = me.title.select do |t|
416
+ t.type != "main" && t.title.language&.include?(l)
417
+ end
411
418
  tm_en = ttl.map { |t| t.title.content }.join " – "
412
- me.title.detect { |t| t.type == "main" && t.title.language&.include?(l) }&.title&.content = tm_en
419
+ me.title.detect do |t|
420
+ t.type == "main" && t.title.language&.include?(l)
421
+ end&.title&.content = tm_en
413
422
  end
414
423
  me.abstract = []
415
424
  me.docidentifier.each(&:remove_part)
@@ -440,7 +449,7 @@ module RelatonBib
440
449
 
441
450
  # If revision_date exists then returns it else returns published date or nil
442
451
  # @return [String, NilClass]
443
- def revdate
452
+ def revdate # rubocop:disable Metrics/CyclomaticComplexity
444
453
  @revdate ||= if version&.revision_date
445
454
  version.revision_date
446
455
  else
@@ -448,6 +457,53 @@ module RelatonBib
448
457
  end
449
458
  end
450
459
 
460
+ # @param prefix [String]
461
+ # @return [String]
462
+ def to_asciibib(prefix = "") # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
463
+ pref = prefix.empty? ? prefix : prefix + "."
464
+ out = prefix.empty? ? "[%bibitem]\n== {blank}\n" : ""
465
+ out += "#{pref}id:: #{id}\n" if id
466
+ out += "#{pref}fetched:: #{fetched}\n" if fetched
467
+ title.each { |t| out += t.to_asciibib(prefix, title.size) }
468
+ out += "#{pref}type:: #{type}\n" if type
469
+ docidentifier.each do |di|
470
+ out += di.to_asciibib prefix, docidentifier.size
471
+ end
472
+ out += "#{pref}docnumber:: #{docnumber}\n" if docnumber
473
+ out += "#{pref}edition:: #{edition}\n" if edition
474
+ language.each { |l| out += "#{pref}language:: #{l}\n" }
475
+ script.each { |s| out += "#{pref}script:: #{s}\n" }
476
+ out += version.to_asciibib prefix if version
477
+ biblionote&.each { |b| out += b.to_asciibib prefix, biblionote.size }
478
+ out += status.to_asciibib prefix if status
479
+ date.each { |d| out += d.to_asciibib prefix, date.size }
480
+ abstract.each do |a|
481
+ out += a.to_asciibib "#{pref}abstract", abstract.size
482
+ end
483
+ copyright.each { |c| out += c.to_asciibib prefix, copyright.size }
484
+ link.each { |l| out += l.to_asciibib prefix, link.size }
485
+ out += medium.to_asciibib prefix if medium
486
+ place.each { |pl| out += pl.to_asciibib prefix, place.size }
487
+ extent.each { |ex| out += ex.to_asciibib "#{pref}extent", extent.size }
488
+ accesslocation.each { |al| out += "#{pref}accesslocation:: #{al}\n" }
489
+ classification.each do |cl|
490
+ out += cl.to_asciibib prefix, classification.size
491
+ end
492
+ out += validity.to_asciibib prefix if validity
493
+ contributor.each do |c|
494
+ out += c.to_asciibib "contributor.*", contributor.size
495
+ end
496
+ out += relation.to_asciibib prefix if relation
497
+ series.each { |s| out += s.to_asciibib prefix, series.size }
498
+ out += "#{pref}doctype:: #{doctype}\n" if doctype
499
+ out += "#{pref}formattedref:: #{formattedref}\n" if formattedref
500
+ keyword.each { |kw| out += kw.to_asciibib "#{pref}keyword", keyword.size }
501
+ out += editorialgroup.to_asciibib prefix if editorialgroup
502
+ ics.each { |i| out += i.to_asciibib prefix, ics.size }
503
+ out += structuredidentifier.to_asciibib prefix if structuredidentifier
504
+ out
505
+ end
506
+
451
507
  private
452
508
 
453
509
  # @return [String]
@@ -470,7 +526,7 @@ module RelatonBib
470
526
  # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
471
527
 
472
528
  # @param [BibTeX::Entry]
473
- def bibtex_author(item)
529
+ def bibtex_author(item) # rubocop:disable Metrics/CyclomaticComplexity
474
530
  authors = contributor.select do |c|
475
531
  c.entity.is_a?(Person) && c.role.map(&:type).include?("author")
476
532
  end.map &:entity
@@ -487,7 +543,7 @@ module RelatonBib
487
543
  end
488
544
 
489
545
  # @param [BibTeX::Entry]
490
- def bibtex_contributor(item)
546
+ def bibtex_contributor(item) # rubocop:disable Metrics/CyclomaticComplexity
491
547
  contributor.each do |c|
492
548
  rls = c.role.map(&:type)
493
549
  if rls.include?("publisher") then item.publisher = c.entity.name
@@ -504,7 +560,7 @@ module RelatonBib
504
560
  # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
505
561
 
506
562
  # @param [BibTeX::Entry]
507
- def bibtex_note(item)
563
+ def bibtex_note(item) # rubocop:disable Metrics/CyclomaticComplexity
508
564
  biblionote.each do |n|
509
565
  case n.type
510
566
  when "annote" then item.annote = n.content
@@ -25,5 +25,16 @@ module RelatonBib
25
25
  hash["type"] = type if type
26
26
  hash
27
27
  end
28
+
29
+ # @param prefix [String]
30
+ # @param count [Integer] number of classifications
31
+ # @return [String]
32
+ def to_asciibib(prefix = "", count = 1)
33
+ pref = prefix.empty? ? "classification" : prefix + ".classification"
34
+ out = count > 1 ? "#{pref}::\n" : ""
35
+ out += "#{pref}.type:: #{type}\n" if type
36
+ out += "#{pref}.value:: #{value}\n"
37
+ out
38
+ end
28
39
  end
29
40
  end
@@ -26,7 +26,9 @@ module RelatonBib
26
26
  end
27
27
 
28
28
  @type = args[:type]
29
- @description = args.fetch(:description, []).map { |d| FormattedString.new content: d, format: nil }
29
+ @description = args.fetch(:description, []).map do |d|
30
+ FormattedString.new content: d, format: nil
31
+ end
30
32
  end
31
33
 
32
34
  # @param builder [Nokogiri::XML::Builder]
@@ -48,6 +50,19 @@ module RelatonBib
48
50
  type
49
51
  end
50
52
  end
53
+
54
+ # @param prefix [String]
55
+ # @param count [Integer] number of contributors
56
+ # 2return [String]
57
+ def to_asciibib(prefix = "", count = 1)
58
+ pref = prefix.empty? ? prefix : prefix + "."
59
+ out = count > 1 ? "#{prefix}::\n" : ""
60
+ description.each do |d|
61
+ out += d.to_asciibib "#{pref}role.description", description.size
62
+ end
63
+ out += "#{pref}role.type:: #{type}\n" if type
64
+ out
65
+ end
51
66
  end
52
67
 
53
68
  # Contribution info.
@@ -79,5 +94,16 @@ module RelatonBib
79
94
  hash["role"] = single_element_array(role) if role&.any?
80
95
  hash
81
96
  end
97
+
98
+ # @param prefix [String]
99
+ # @param count [Integer] number of contributors
100
+ # @return [String]
101
+ def to_asciibib(prefix = "", count = 1)
102
+ pref = prefix.split(".").first
103
+ out = count > 1 ? "#{pref}::\n" : ""
104
+ out += entity.to_asciibib prefix
105
+ role.each { |r| out += r.to_asciibib pref, role.size }
106
+ out
107
+ end
82
108
  end
83
109
  end