metanorma-standoc 1.6.0 → 1.6.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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/lib/asciidoctor/standoc/cleanup_footnotes.rb +11 -0
  3. data/lib/asciidoctor/standoc/cleanup_ref.rb +1 -1
  4. data/lib/asciidoctor/standoc/converter.rb +2 -2
  5. data/lib/asciidoctor/standoc/front.rb +3 -3
  6. data/lib/asciidoctor/standoc/front_contributor.rb +34 -10
  7. data/lib/asciidoctor/standoc/isodoc.rng +0 -1
  8. data/lib/asciidoctor/standoc/macros.rb +1 -2
  9. data/lib/asciidoctor/standoc/ref.rb +9 -15
  10. data/lib/asciidoctor/standoc/ref_sect.rb +12 -5
  11. data/lib/asciidoctor/standoc/section.rb +5 -9
  12. data/lib/liquid/custom_blocks/with_json_nested_context.rb +18 -0
  13. data/lib/liquid/custom_blocks/with_yaml_nested_context.rb +19 -0
  14. data/lib/metanorma/standoc/version.rb +1 -1
  15. data/metanorma-standoc.gemspec +2 -1
  16. data/spec/asciidoctor-standoc/base_spec.rb +123 -8
  17. data/spec/asciidoctor-standoc/cleanup_spec.rb +37 -0
  18. data/spec/asciidoctor-standoc/isobib_cache_spec.rb +6 -22
  19. data/spec/asciidoctor-standoc/macros_json2text_spec.rb +1 -1
  20. data/spec/asciidoctor-standoc/macros_yaml2text_spec.rb +1 -1
  21. data/spec/asciidoctor-standoc/refs_dl_spec.rb +2 -2
  22. data/spec/asciidoctor-standoc/refs_spec.rb +248 -46
  23. data/spec/support/shared_examples/structured_data_2_text_preprocessor.rb +156 -4
  24. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +155 -155
  25. data/spec/vcr_cassettes/isobib_get_123.yml +10 -56
  26. data/spec/vcr_cassettes/isobib_get_123_1.yml +92 -92
  27. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +361 -0
  28. data/spec/vcr_cassettes/isobib_get_123_2001.yml +45 -45
  29. data/spec/vcr_cassettes/isobib_get_124.yml +45 -45
  30. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +8 -8
  31. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +36 -36
  32. metadata +21 -7
  33. data/lib/asciidoctor/standoc/base_structured_text_preprocessor.rb +0 -123
  34. data/lib/asciidoctor/standoc/json2_text_preprocessor.rb +0 -44
  35. data/lib/asciidoctor/standoc/yaml2_text_preprocessor.rb +0 -46
@@ -1,123 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "liquid/custom_blocks/key_iterator"
4
- require "liquid/custom_filters/values"
5
-
6
- Liquid::Template.register_tag("keyiterator", Liquid::CustomBlocks::KeyIterator)
7
- Liquid::Template.register_filter(Liquid::CustomFilters)
8
-
9
- module Asciidoctor
10
- module Standoc
11
- # Base class for processing structured data blocks(yaml, json)
12
- class BaseStructuredTextPreprocessor < Asciidoctor::Extensions::Preprocessor
13
- BLOCK_START_REGEXP = /\{(.+?)\.\*,(.+),(.+)\}/
14
- BLOCK_END_REGEXP = /\A\{[A-Z]+\}\z/
15
-
16
- def process(document, reader)
17
- input_lines = reader.readlines.to_enum
18
- Reader.new(processed_lines(document, input_lines))
19
- end
20
-
21
- protected
22
-
23
- def content_from_file(_document, _file_path)
24
- raise ArgumentError, "Implement `content_from_file` in your class"
25
- end
26
-
27
- private
28
-
29
- def processed_lines(document, input_lines)
30
- result = []
31
- loop do
32
- result.push(*process_text_blocks(document, input_lines))
33
- end
34
- result
35
- end
36
-
37
- def relative_file_path(document, file_path)
38
- docfile_directory = File.dirname(document.attributes["docfile"] || ".")
39
- document
40
- .path_resolver
41
- .system_path(file_path, docfile_directory)
42
- end
43
-
44
- def process_text_blocks(document, input_lines)
45
- line = input_lines.next
46
- block_match = line.match(/^\[#{config[:block_name]},(.+?),(.+?)\]/)
47
- return [line] if block_match.nil?
48
-
49
- mark = input_lines.next
50
- current_block = []
51
- while (block_line = input_lines.next) != mark
52
- current_block.push(block_line)
53
- end
54
- read_content_and_parse_template(document,
55
- current_block,
56
- block_match)
57
- end
58
-
59
- def read_content_and_parse_template(document, current_block, block_match)
60
- transformed_liquid_lines = current_block
61
- .map(&method(:transform_line_liquid))
62
- context_items = content_from_file(document, block_match[1])
63
- parse_context_block(document: document,
64
- context_lines: transformed_liquid_lines,
65
- context_items: context_items,
66
- context_name: block_match[2])
67
- rescue StandardError => exception
68
- document.logger
69
- .warn("Failed to parse #{config[:block_name]} \
70
- block: #{exception.message}")
71
- []
72
- end
73
-
74
- def transform_line_liquid(line)
75
- if line.match?(BLOCK_START_REGEXP)
76
- line.gsub!(BLOCK_START_REGEXP,
77
- '{% keyiterator \1, \2 %}')
78
- end
79
-
80
- if line.strip.match?(BLOCK_END_REGEXP)
81
- line.gsub!(BLOCK_END_REGEXP, "{% endkeyiterator %}")
82
- end
83
- line
84
- .gsub(/(?<!{){(?!%)([^{}]+)(?<!%)}(?!})/, '{{\1}}')
85
- .gsub(/[a-z\.]+\#/, "index")
86
- .gsub(/{{(.+)\s+\+\s+(\d+)\s*?}}/, '{{ \1 | plus: \2 }}')
87
- .gsub(/{{(.+)\s+\-\s+(\d+)\s*?}}/, '{{ \1 | minus: \2 }}')
88
- .gsub(/{{(.+).values(.*?)}}/,
89
- '{% assign custom_value = \1 | values %}{{custom_value\2}}')
90
- end
91
-
92
- def parse_context_block(context_lines:,
93
- context_items:,
94
- context_name:,
95
- document:)
96
- render_result, errors = render_liquid_string(
97
- template_string: context_lines.join("\n"),
98
- context_items: context_items,
99
- context_name: context_name
100
- )
101
- notify_render_errors(document, errors)
102
- render_result.split("\n")
103
- end
104
-
105
- def render_liquid_string(template_string:, context_items:, context_name:)
106
- liquid_template = Liquid::Template.parse(template_string)
107
- rendered_string = liquid_template
108
- .render(context_name => context_items,
109
- strict_variables: true,
110
- error_mode: :warn)
111
- [rendered_string, liquid_template.errors]
112
- end
113
-
114
- def notify_render_errors(document, errors)
115
- errors.each do |error_obj|
116
- document
117
- .logger
118
- .warn("Liquid render error: #{error_obj.message}")
119
- end
120
- end
121
- end
122
- end
123
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "asciidoctor/standoc/base_structured_text_preprocessor"
4
-
5
- module Asciidoctor
6
- module Standoc
7
- class Json2TextPreprocessor < BaseStructuredTextPreprocessor
8
- # search document for block `yaml2text`
9
- # after that take template from block and read file into this template
10
- # example:
11
- # [yaml2text,foobar.yaml]
12
- # ----
13
- # === {item.name}
14
- # {item.desc}
15
- #
16
- # {item.symbol}:: {item.symbol_def}
17
- # ----
18
- #
19
- # with content of `foobar.yaml` file equal to:
20
- # - name: spaghetti
21
- # desc: wheat noodles of 9mm diameter
22
- # symbol: SPAG
23
- # symbol_def: the situation is message like spaghetti at a kid's
24
- #
25
- # will produce:
26
- # === spaghetti
27
- # wheat noodles of 9mm diameter
28
- #
29
- # SPAG:: the situation is message like spaghetti at a kid's meal
30
-
31
- def initialize(config = {})
32
- super
33
- @config[:block_name] = "json2text"
34
- end
35
-
36
- protected
37
-
38
- def content_from_file(document, file_path)
39
- JSON.parse(File.read(relative_file_path(document, file_path),
40
- encoding: "UTF-8"))
41
- end
42
- end
43
- end
44
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "asciidoctor/standoc/base_structured_text_preprocessor"
4
-
5
- module Asciidoctor
6
- module Standoc
7
- class Yaml2TextPreprocessor < BaseStructuredTextPreprocessor
8
- # search document for block `yaml2text`
9
- # after that take template from block and read file into this template
10
- # example:
11
- # [yaml2text,foobar.yaml]
12
- # ----
13
- # === {item.name}
14
- # {item.desc}
15
- #
16
- # {item.symbol}:: {item.symbol_def}
17
- # ----
18
- #
19
- # with content of `foobar.yaml` file equal to:
20
- # - name: spaghetti
21
- # desc: wheat noodles of 9mm diameter
22
- # symbol: SPAG
23
- # symbol_def: the situation is message like spaghetti at a kid's
24
- #
25
- # will produce:
26
- # === spaghetti
27
- # wheat noodles of 9mm diameter
28
- #
29
- # SPAG:: the situation is message like spaghetti at a kid's meal
30
-
31
- def initialize(config = {})
32
- super
33
- @config[:block_name] = "yaml2text"
34
- end
35
-
36
- protected
37
-
38
- def content_from_file(document, file_path)
39
- YAML.safe_load(
40
- File.read(relative_file_path(document, file_path),
41
- encoding: "UTF-8"),
42
- [Date, Time])
43
- end
44
- end
45
- end
46
- end