isodoc 1.0.27 → 1.1.2
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/.github/workflows/macos.yml +4 -8
- data/.github/workflows/ubuntu.yml +18 -16
- data/.github/workflows/windows.yml +4 -8
- data/Rakefile +3 -1
- data/isodoc.gemspec +2 -2
- data/lib/isodoc.rb +2 -0
- data/lib/isodoc/base_style/metanorma_word.scss +0 -1
- data/lib/isodoc/base_style/reset.scss +3 -3
- data/lib/isodoc/common.rb +0 -4
- data/lib/isodoc/convert.rb +121 -58
- data/lib/isodoc/function/blocks.rb +42 -53
- data/lib/isodoc/function/blocks_example_note.rb +108 -0
- data/lib/isodoc/function/cleanup.rb +8 -4
- data/lib/isodoc/function/i18n.rb +1 -0
- data/lib/isodoc/function/inline.rb +70 -90
- data/lib/isodoc/function/inline_simple.rb +72 -0
- data/lib/isodoc/function/lists.rb +12 -6
- data/lib/isodoc/function/references.rb +33 -38
- data/lib/isodoc/function/reqt.rb +14 -5
- data/lib/isodoc/function/section.rb +8 -11
- data/lib/isodoc/function/table.rb +4 -4
- data/lib/isodoc/function/terms.rb +3 -3
- data/lib/isodoc/function/to_word_html.rb +21 -13
- data/lib/isodoc/function/utils.rb +57 -50
- data/lib/isodoc/gem_tasks.rb +104 -0
- data/lib/isodoc/headlesshtml_convert.rb +7 -6
- data/lib/isodoc/html_convert.rb +2 -1
- data/lib/isodoc/html_function/footnotes.rb +1 -1
- data/lib/isodoc/html_function/html.rb +13 -1
- data/lib/isodoc/html_function/postprocess.rb +4 -4
- data/lib/isodoc/metadata.rb +74 -62
- data/lib/isodoc/pdf_convert.rb +8 -6
- data/lib/isodoc/presentation_xml_convert.rb +29 -0
- data/lib/isodoc/sassc_importer.rb +11 -0
- data/lib/isodoc/version.rb +1 -1
- data/lib/isodoc/word_convert.rb +2 -1
- data/lib/isodoc/word_function/body.rb +14 -48
- data/lib/isodoc/word_function/footnotes.rb +1 -1
- data/lib/isodoc/word_function/inline.rb +75 -0
- data/lib/isodoc/word_function/postprocess.rb +1 -0
- data/lib/isodoc/word_function/table.rb +3 -3
- data/lib/isodoc/xref.rb +59 -0
- data/lib/isodoc/{function → xref}/xref_anchor.rb +10 -21
- data/lib/isodoc/xref/xref_counter.rb +74 -0
- data/lib/isodoc/{function → xref}/xref_gen.rb +9 -22
- data/lib/isodoc/{function → xref}/xref_gen_seq.rb +41 -32
- data/lib/isodoc/{function → xref}/xref_sect_gen.rb +33 -23
- data/lib/isodoc/xslfo_convert.rb +16 -4
- data/spec/assets/{html.css → html.scss} +0 -0
- data/spec/assets/i18n.yaml +4 -1
- data/spec/assets/odf.emf +0 -0
- data/spec/assets/odf.svg +4 -0
- data/spec/assets/odf1.svg +4 -0
- data/spec/isodoc/blocks_spec.rb +219 -47
- data/spec/isodoc/cleanup_spec.rb +135 -6
- data/spec/isodoc/footnotes_spec.rb +22 -7
- data/spec/isodoc/inline_spec.rb +262 -2
- data/spec/isodoc/lists_spec.rb +8 -8
- data/spec/isodoc/metadata_spec.rb +110 -3
- data/spec/isodoc/postproc_spec.rb +1321 -1351
- data/spec/isodoc/presentation_xml_spec.rb +20 -0
- data/spec/isodoc/ref_spec.rb +119 -50
- data/spec/isodoc/section_spec.rb +84 -18
- data/spec/isodoc/table_spec.rb +6 -6
- data/spec/isodoc/terms_spec.rb +7 -7
- data/spec/isodoc/xref_spec.rb +165 -45
- metadata +36 -27
- data/lib/isodoc/function/blocks_example.rb +0 -53
- data/lib/isodoc/function/xref_counter.rb +0 -50
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module IsoDoc::Function
|
2
4
|
module Utils
|
3
5
|
def date_range(date)
|
@@ -9,50 +11,50 @@ module IsoDoc::Function
|
|
9
11
|
end
|
10
12
|
|
11
13
|
def insert_tab(out, n)
|
12
|
-
[1..n].each { out <<
|
14
|
+
[1..n].each { out << ' ' }
|
13
15
|
end
|
14
16
|
|
15
17
|
# add namespaces for Word fragments
|
16
|
-
NOKOHEAD = <<~HERE
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
NOKOHEAD = <<~HERE
|
19
|
+
<!DOCTYPE html SYSTEM
|
20
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
21
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
22
|
+
<head> <title></title> <meta charset="UTF-8" /> </head>
|
23
|
+
<body> </body> </html>
|
22
24
|
HERE
|
23
25
|
|
24
26
|
# block for processing XML document fragments as XHTML,
|
25
27
|
# to allow for HTMLentities
|
26
28
|
def noko(&block)
|
27
29
|
doc = ::Nokogiri::XML.parse(NOKOHEAD)
|
28
|
-
fragment = doc.fragment(
|
30
|
+
fragment = doc.fragment('')
|
29
31
|
::Nokogiri::XML::Builder.with fragment, &block
|
30
|
-
fragment.to_xml(encoding:
|
31
|
-
l.gsub(/\s*\n/,
|
32
|
+
fragment.to_xml(encoding: 'US-ASCII').lines.map do |l|
|
33
|
+
l.gsub(/\s*\n/, '')
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
35
37
|
def attr_code(attributes)
|
36
38
|
attributes = attributes.reject { |_, val| val.nil? }.map
|
37
39
|
attributes.map do |k, v|
|
38
|
-
[k,
|
40
|
+
[k, v.is_a?(String) ? HTMLEntities.new.decode(v) : v]
|
39
41
|
end.to_h
|
40
42
|
end
|
41
43
|
|
42
44
|
DOCTYPE_HDR = '<!DOCTYPE html SYSTEM '\
|
43
|
-
'"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
|
45
|
+
'"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
|
44
46
|
|
45
47
|
def to_xhtml(xml)
|
46
|
-
xml.gsub!(/<\?xml[^>]*>/,
|
47
|
-
/<!DOCTYPE /.match
|
48
|
+
xml.gsub!(/<\?xml[^>]*>/, '')
|
49
|
+
/<!DOCTYPE /.match(xml) || (xml = DOCTYPE_HDR + xml)
|
48
50
|
xml = xml.split(/(\&[^ \r\n\t#;]+;)/).map do |t|
|
49
|
-
/^(\&[^ \t\r\n#;]+;)/.match(t) ?
|
51
|
+
/^(\&[^ \t\r\n#;]+;)/.match?(t) ?
|
50
52
|
HTMLEntities.new.encode(HTMLEntities.new.decode(t), :hexadecimal) : t
|
51
|
-
end.join(
|
53
|
+
end.join('')
|
52
54
|
begin
|
53
|
-
Nokogiri::XML.parse(xml
|
55
|
+
Nokogiri::XML.parse(xml, &:strict)
|
54
56
|
rescue Nokogiri::XML::SyntaxError => e
|
55
|
-
File.open("#{@filename}.#{@format}.err",
|
57
|
+
File.open("#{@filename}.#{@format}.err", 'w:UTF-8') { |f| f.write xml }
|
56
58
|
abort "Malformed Output XML for #{@format}: #{e} (see #{@filename}.#{@format}.err)"
|
57
59
|
end
|
58
60
|
end
|
@@ -64,7 +66,7 @@ module IsoDoc::Function
|
|
64
66
|
end
|
65
67
|
|
66
68
|
def from_xhtml(xml)
|
67
|
-
xml.to_xml.sub(%r{ xmlns="http://www.w3.org/1999/xhtml"},
|
69
|
+
xml.to_xml.sub(%r{ xmlns="http://www.w3.org/1999/xhtml"}, '')
|
68
70
|
end
|
69
71
|
|
70
72
|
CLAUSE_ANCESTOR =
|
@@ -72,7 +74,7 @@ module IsoDoc::Function
|
|
72
74
|
"local-name() = 'acknowledgements' or local-name() = 'term' or "\
|
73
75
|
"local-name() = 'appendix' or local-name() = 'foreword' or "\
|
74
76
|
"local-name() = 'introduction' or local-name() = 'terms' or "\
|
75
|
-
"local-name() = 'clause' or local-name() = 'references']/@id"
|
77
|
+
"local-name() = 'clause' or local-name() = 'references']/@id"
|
76
78
|
|
77
79
|
def get_clause_id(node)
|
78
80
|
clause = node.xpath(CLAUSE_ANCESTOR)
|
@@ -86,7 +88,7 @@ module IsoDoc::Function
|
|
86
88
|
"local-name() = 'acknowledgements' or local-name() = 'term' or "\
|
87
89
|
"local-name() = 'clause' or local-name() = 'references' or "\
|
88
90
|
"local-name() = 'figure' or local-name() = 'formula' or "\
|
89
|
-
"local-name() = 'table' or local-name() = 'example']/@id"
|
91
|
+
"local-name() = 'table' or local-name() = 'example']/@id"
|
90
92
|
|
91
93
|
def get_note_container_id(node)
|
92
94
|
container = node.xpath(NOTE_CONTAINER_ANCESTOR)
|
@@ -94,7 +96,7 @@ module IsoDoc::Function
|
|
94
96
|
end
|
95
97
|
|
96
98
|
def sentence_join(array)
|
97
|
-
return
|
99
|
+
return '' if array.nil? || array.empty?
|
98
100
|
if array.length == 1 then array[0]
|
99
101
|
else
|
100
102
|
IsoDoc::Function::I18n::l10n("#{array[0..-2].join(', ')} "\
|
@@ -105,25 +107,25 @@ module IsoDoc::Function
|
|
105
107
|
|
106
108
|
# avoid `; avoid {{ (Liquid Templates); avoid [[ (Javascript)
|
107
109
|
def extract_delims(text)
|
108
|
-
@openmathdelim =
|
109
|
-
@closemathdelim =
|
110
|
+
@openmathdelim = '(#('
|
111
|
+
@closemathdelim = ')#)'
|
110
112
|
while text.include?(@openmathdelim) || text.include?(@closemathdelim)
|
111
|
-
@openmathdelim +=
|
112
|
-
@closemathdelim +=
|
113
|
+
@openmathdelim += '('
|
114
|
+
@closemathdelim += ')'
|
113
115
|
end
|
114
116
|
[@openmathdelim, @closemathdelim]
|
115
117
|
end
|
116
118
|
|
117
119
|
def header_strip(h)
|
118
|
-
h = h.to_s.gsub(%r{<br\s*/>},
|
119
|
-
|
120
|
+
h = h.to_s.gsub(%r{<br\s*/>}, ' ').gsub(/<\/?h[123456][^>]*>/, '')
|
121
|
+
.gsub(/<\/?b[^>]*>/, '')
|
120
122
|
h1 = to_xhtml_fragment(h.dup)
|
121
123
|
h1.traverse do |x|
|
122
|
-
x.replace(
|
123
|
-
x.remove if x.name ==
|
124
|
-
x.remove if x.name ==
|
125
|
-
x.remove if x.name ==
|
126
|
-
x.replace(x.children) if x.name ==
|
124
|
+
x.replace(' ') if x.name == 'span' && /mso-tab-count/.match(x['style'])
|
125
|
+
x.remove if x.name == 'span' && x['class'] == 'MsoCommentReference'
|
126
|
+
x.remove if x.name == 'a' && x['class'] == 'FootnoteRef'
|
127
|
+
x.remove if x.name == 'span' && /mso-bookmark/.match(x['style'])
|
128
|
+
x.replace(x.children) if x.name == 'a'
|
127
129
|
end
|
128
130
|
from_xhtml(h1)
|
129
131
|
end
|
@@ -135,9 +137,9 @@ module IsoDoc::Function
|
|
135
137
|
def liquid(doc)
|
136
138
|
# unescape HTML escapes in doc
|
137
139
|
doc = doc.split(%r<(\{%|%\})>).each_slice(4).map do |a|
|
138
|
-
a[2] = a[2].gsub(/\</,
|
139
|
-
a.join(
|
140
|
-
end.join(
|
140
|
+
a[2] = a[2].gsub(/\</, '<').gsub(/\>/, '>') if a.size > 2
|
141
|
+
a.join('')
|
142
|
+
end.join('')
|
141
143
|
Liquid::Template.parse(doc)
|
142
144
|
end
|
143
145
|
|
@@ -147,36 +149,41 @@ module IsoDoc::Function
|
|
147
149
|
end
|
148
150
|
|
149
151
|
def populate_template(docxml, _format = nil)
|
150
|
-
meta = @meta
|
152
|
+
meta = @meta
|
153
|
+
.get
|
154
|
+
.merge(@labels || {})
|
155
|
+
.merge(@meta.labels || {})
|
156
|
+
.merge(@meta.fonts_options || {})
|
151
157
|
template = liquid(docxml)
|
152
|
-
template.render(meta.map { |k, v| [k.to_s, empty2nil(v)] }.to_h)
|
153
|
-
|
158
|
+
template.render(meta.map { |k, v| [k.to_s, empty2nil(v)] }.to_h)
|
159
|
+
.gsub('<', '<').gsub('>', '>').gsub('&', '&')
|
154
160
|
end
|
155
161
|
|
156
|
-
def save_dataimage(uri,
|
162
|
+
def save_dataimage(uri, _relative_dir = true)
|
157
163
|
%r{^data:image/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ uri
|
158
|
-
imgtype
|
159
|
-
|
164
|
+
imgtype.sub!(/\+[a-z0-9]+$/, '') # svg+xml
|
165
|
+
imgtype = 'png' unless /^[a-z0-9]+$/.match imgtype
|
166
|
+
Tempfile.open(['image', ".#{imgtype}"]) do |f|
|
160
167
|
f.binmode
|
161
168
|
f.write(Base64.strict_decode64(imgdata))
|
162
|
-
@tempfile_cache << f #persist to the end
|
169
|
+
@tempfile_cache << f # persist to the end
|
163
170
|
f.path
|
164
171
|
end
|
165
172
|
end
|
166
173
|
|
167
174
|
def image_localfile(i)
|
168
|
-
if /^data:image/.match i[
|
169
|
-
save_dataimage(i[
|
170
|
-
elsif %r{^([A-Z]:)?/}.match i[
|
171
|
-
i[
|
175
|
+
if /^data:image/.match? i['src']
|
176
|
+
save_dataimage(i['src'], false)
|
177
|
+
elsif %r{^([A-Z]:)?/}.match? i['src']
|
178
|
+
i['src']
|
172
179
|
else
|
173
|
-
File.join(@localdir, i[
|
180
|
+
File.join(@localdir, i['src'])
|
174
181
|
end
|
175
182
|
end
|
176
183
|
|
177
184
|
def labelled_ancestor(node)
|
178
|
-
|
179
|
-
|
185
|
+
!node.ancestors('example, requirement, recommendation, permission, '\
|
186
|
+
'table, figure, sourcecode').empty?
|
180
187
|
end
|
181
188
|
end
|
182
189
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sassc'
|
4
|
+
require 'isodoc/sassc_importer'
|
5
|
+
require 'rake/clean'
|
6
|
+
|
7
|
+
module IsoDoc
|
8
|
+
module GemTasks
|
9
|
+
extend Rake::DSL if defined? Rake::DSL
|
10
|
+
|
11
|
+
module_function
|
12
|
+
|
13
|
+
def install
|
14
|
+
rule '.css' => [proc { |tn| tn.sub(/\.css$/, '.scss') }] do |current_task|
|
15
|
+
begin
|
16
|
+
puts(current_task)
|
17
|
+
compile_scss_task(current_task)
|
18
|
+
rescue StandardError => e
|
19
|
+
puts(e.message)
|
20
|
+
puts("skiping #{current_task}")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
scss_files = Rake::FileList['lib/**/*.scss']
|
25
|
+
source_files = scss_files.ext('.css')
|
26
|
+
|
27
|
+
task :comment_out_liquid do
|
28
|
+
process_css_files(scss_files) do |file_name|
|
29
|
+
comment_out_liquid(File.read(file_name, encoding: 'UTF-8'))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
task build_scss: [:comment_out_liquid].push(*source_files) do
|
34
|
+
process_css_files(scss_files) do |file_name|
|
35
|
+
uncomment_out_liquid(File.read(file_name, encoding: 'UTF-8'))
|
36
|
+
end
|
37
|
+
puts('Built scss!')
|
38
|
+
end
|
39
|
+
|
40
|
+
Rake::Task['build'].enhance [:build_scss] do
|
41
|
+
Rake::Task[:clean].invoke
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def process_css_files(scss_files)
|
46
|
+
scss_files.each do |file_name|
|
47
|
+
result = yield(file_name)
|
48
|
+
File.open(file_name, 'w', encoding: 'UTF-8') do |file|
|
49
|
+
file.puts(result)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def comment_out_liquid(text)
|
55
|
+
text.split("\n").map do |line|
|
56
|
+
if line.match?(/{({|%).+(}|%)}/)
|
57
|
+
"/* LIQUID_COMMENT#{line}LIQUID_COMMENT */"
|
58
|
+
else
|
59
|
+
line
|
60
|
+
end
|
61
|
+
end
|
62
|
+
.join("\n")
|
63
|
+
end
|
64
|
+
|
65
|
+
def uncomment_out_liquid(text)
|
66
|
+
text
|
67
|
+
.gsub('/* LIQUID_COMMENT', '')
|
68
|
+
.gsub('LIQUID_COMMENT */', '')
|
69
|
+
.gsub('"{{', '{{').gsub('}}"', '}}')
|
70
|
+
end
|
71
|
+
|
72
|
+
def fonts_placeholder
|
73
|
+
<<~TEXT
|
74
|
+
$bodyfont: '{{bodyfont}}';
|
75
|
+
$headerfont: '{{headerfont}}';
|
76
|
+
$monospacefont: '{{monospacefont}}';
|
77
|
+
TEXT
|
78
|
+
end
|
79
|
+
|
80
|
+
def compile_scss(filename)
|
81
|
+
require 'sassc'
|
82
|
+
[File.join(Gem.loaded_specs['isodoc'].full_gem_path, 'lib', 'isodoc'),
|
83
|
+
File.dirname(filename)].each do |name|
|
84
|
+
SassC.load_paths << name
|
85
|
+
end
|
86
|
+
sheet_content = File.read(filename, encoding: 'UTF-8')
|
87
|
+
SassC::Engine.new(fonts_placeholder + sheet_content,
|
88
|
+
syntax: :scss,
|
89
|
+
importer: SasscImporter)
|
90
|
+
.render
|
91
|
+
end
|
92
|
+
|
93
|
+
def compile_scss_task(current_task)
|
94
|
+
filename = current_task.source
|
95
|
+
basename = File.basename(filename, '.*')
|
96
|
+
compiled_path = File.join(File.dirname(filename), "#{basename}.css")
|
97
|
+
content = uncomment_out_liquid(compile_scss(filename))
|
98
|
+
File.open(compiled_path, 'w:UTF-8') do |f|
|
99
|
+
f.write(content)
|
100
|
+
end
|
101
|
+
CLEAN << compiled_path
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -16,18 +16,19 @@ module IsoDoc
|
|
16
16
|
|
17
17
|
def initialize(options)
|
18
18
|
@format = :html
|
19
|
+
@suffix = "headless.html"
|
19
20
|
super
|
20
21
|
end
|
21
22
|
|
22
|
-
def convert(
|
23
|
-
file = File.read(
|
23
|
+
def convert(input_filename, file = nil, debug = false, output_filename = nil)
|
24
|
+
file = File.read(input_filename, encoding: "utf-8") if file.nil?
|
24
25
|
@openmathdelim, @closemathdelim = extract_delims(file)
|
25
|
-
docxml,
|
26
|
-
result = convert1(docxml,
|
26
|
+
docxml, filename, dir = convert_init(file, input_filename, debug)
|
27
|
+
result = convert1(docxml, filename, dir)
|
27
28
|
return result if debug
|
28
|
-
postprocess(result, filename + ".tmp", dir)
|
29
|
+
postprocess(result, filename + ".tmp.html", dir)
|
29
30
|
FileUtils.rm_rf dir
|
30
|
-
strip_head(filename + ".tmp.html",
|
31
|
+
strip_head(filename + ".tmp.html", output_filename || "#{filename}.#{@suffix}")
|
31
32
|
FileUtils.rm_rf ["#{filename}.tmp.html", tmpimagedir]
|
32
33
|
end
|
33
34
|
|
data/lib/isodoc/html_convert.rb
CHANGED
@@ -16,10 +16,11 @@ module IsoDoc
|
|
16
16
|
|
17
17
|
def initialize(options)
|
18
18
|
@format = :html
|
19
|
+
@suffix = "html"
|
19
20
|
super
|
20
21
|
end
|
21
22
|
|
22
|
-
def convert(filename, file = nil, debug = false)
|
23
|
+
def convert(filename, file = nil, debug = false, output_filename = nil)
|
23
24
|
ret = super
|
24
25
|
Dir.exists?(tmpimagedir) and Dir["#{tmpimagedir}/*"].empty? and
|
25
26
|
FileUtils.rm_r tmpimagedir
|
@@ -65,7 +65,7 @@ module IsoDoc::HtmlFunction
|
|
65
65
|
return table_footnote_parse(node, out) if (@in_table || @in_figure) &&
|
66
66
|
!node.ancestors.map {|m| m.name }.include?("name")
|
67
67
|
fn = node["reference"] || UUIDTools::UUID.random_create.to_s
|
68
|
-
attrs = {
|
68
|
+
attrs = { class: "FootnoteRef", href: "#fn:#{fn}" }
|
69
69
|
out.a **attrs do |a|
|
70
70
|
a.sup { |sup| sup << fn }
|
71
71
|
end
|
@@ -3,6 +3,18 @@ require "base64"
|
|
3
3
|
|
4
4
|
module IsoDoc::HtmlFunction
|
5
5
|
module Html
|
6
|
+
def convert1(docxml, filename, dir)
|
7
|
+
@xrefs.parse docxml
|
8
|
+
noko do |xml|
|
9
|
+
xml.html **{ lang: "#{@lang}" } do |html|
|
10
|
+
info docxml, nil
|
11
|
+
populate_css()
|
12
|
+
html.head { |head| define_head head, filename, dir }
|
13
|
+
make_body(html, docxml)
|
14
|
+
end
|
15
|
+
end.join("\n")
|
16
|
+
end
|
17
|
+
|
6
18
|
def make_body1(body, _docxml)
|
7
19
|
body.div **{ class: "title-section" } do |div1|
|
8
20
|
div1.p { |p| p << " " } # placeholder
|
@@ -90,7 +102,7 @@ module IsoDoc::HtmlFunction
|
|
90
102
|
def sourcecode_parse(node, out)
|
91
103
|
name = node.at(ns("./name"))
|
92
104
|
class1 = "prettyprint #{sourcecodelang(node&.at(ns('./@lang'))&.value)}"
|
93
|
-
out.pre **
|
105
|
+
out.pre **sourcecode_attrs(node).merge(class: class1) do |div|
|
94
106
|
@sourcecode = true
|
95
107
|
node.children.each { |n| parse(n, div) unless n.name == "name" }
|
96
108
|
@sourcecode = false
|
@@ -18,7 +18,7 @@ module IsoDoc::HtmlFunction
|
|
18
18
|
#result = populate_template(result, :html)
|
19
19
|
result = from_xhtml(move_images(to_xhtml(result)))
|
20
20
|
result = html5(script_cdata(inject_script(result)))
|
21
|
-
File.open(
|
21
|
+
File.open(filename, "w:UTF-8") { |f| f.write(result) }
|
22
22
|
end
|
23
23
|
|
24
24
|
def html5(doc)
|
@@ -179,7 +179,7 @@ module IsoDoc::HtmlFunction
|
|
179
179
|
def html_footnote_filter(docxml)
|
180
180
|
seen = {}
|
181
181
|
i = 1
|
182
|
-
docxml.xpath('//a[@
|
182
|
+
docxml.xpath('//a[@class = "FootnoteRef"]').each do |x|
|
183
183
|
fn = docxml.at(%<//*[@id = '#{x['href'].sub(/^#/, '')}']>) || next
|
184
184
|
i, seen = update_footnote_filter(fn, x, i, seen)
|
185
185
|
end
|
@@ -188,7 +188,7 @@ module IsoDoc::HtmlFunction
|
|
188
188
|
|
189
189
|
def footnote_backlinks(docxml)
|
190
190
|
seen = {}
|
191
|
-
docxml.xpath('//a[@
|
191
|
+
docxml.xpath('//a[@class = "FootnoteRef"]').each_with_index do |x, i|
|
192
192
|
seen[x["href"]] and next or seen[x["href"]] = true
|
193
193
|
fn = docxml.at(%<//*[@id = '#{x['href'].sub(/^#/, '')}']>) || next
|
194
194
|
xdup = x.dup
|
@@ -201,7 +201,7 @@ module IsoDoc::HtmlFunction
|
|
201
201
|
end
|
202
202
|
|
203
203
|
def footnote_format(docxml)
|
204
|
-
docxml.xpath("//a[@
|
204
|
+
docxml.xpath("//a[@class = 'FootnoteRef']/sup").each do |x|
|
205
205
|
footnote_reference_format(x)
|
206
206
|
end
|
207
207
|
docxml.xpath("//a[@class = 'TableFootnoteRef'] | "\
|
data/lib/isodoc/metadata.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './metadata_date'
|
2
4
|
|
3
5
|
module IsoDoc
|
4
6
|
class Metadata
|
5
7
|
DATETYPES = %w{published accessed created implemented obsoleted confirmed
|
6
|
-
|
7
|
-
|
8
|
+
updated issued received transmitted copied unchanged
|
9
|
+
circulated vote-started
|
10
|
+
vote-ended}.freeze
|
11
|
+
|
12
|
+
attr_accessor :fonts_options
|
8
13
|
|
9
14
|
def ns(xpath)
|
10
15
|
Common::ns(xpath)
|
@@ -14,13 +19,14 @@ module IsoDoc
|
|
14
19
|
IsoDoc::Function::I18n::l10n(a, b, c)
|
15
20
|
end
|
16
21
|
|
17
|
-
def initialize(lang, script, labels)
|
22
|
+
def initialize(lang, script, labels, fonts_options = {})
|
18
23
|
@metadata = {}
|
19
|
-
DATETYPES.each { |w| @metadata["#{w.gsub(/-/,
|
24
|
+
DATETYPES.each { |w| @metadata["#{w.gsub(/-/, '_')}date".to_sym] = 'XXX' }
|
20
25
|
@lang = lang
|
21
26
|
@script = script
|
22
27
|
@c = HTMLEntities.new
|
23
28
|
@labels = labels
|
29
|
+
@fonts_options = fonts_options
|
24
30
|
end
|
25
31
|
|
26
32
|
def get
|
@@ -36,26 +42,26 @@ module IsoDoc
|
|
36
42
|
end
|
37
43
|
|
38
44
|
def extract_person_names(authors)
|
39
|
-
authors.
|
40
|
-
if a.at(ns(
|
41
|
-
ret << a.at(ns(
|
45
|
+
authors.reduce([]) do |ret, a|
|
46
|
+
if a.at(ns('./name/completename'))
|
47
|
+
ret << a.at(ns('./name/completename')).text
|
42
48
|
else
|
43
49
|
fn = []
|
44
|
-
forenames = a.xpath(ns(
|
50
|
+
forenames = a.xpath(ns('./name/forename'))
|
45
51
|
forenames.each { |f| fn << f.text }
|
46
|
-
surname = a&.at(ns(
|
47
|
-
ret << fn.join(
|
52
|
+
surname = a&.at(ns('./name/surname'))&.text
|
53
|
+
ret << fn.join(' ') + ' ' + surname
|
48
54
|
end
|
49
55
|
end
|
50
56
|
end
|
51
57
|
|
52
58
|
def extract_person_affiliations(authors)
|
53
|
-
authors.
|
54
|
-
name = a&.at(ns(
|
55
|
-
location = a&.at(ns(
|
56
|
-
|
57
|
-
m << (
|
58
|
-
(name || location ||
|
59
|
+
authors.reduce([]) do |m, a|
|
60
|
+
name = a&.at(ns('./affiliation/organization/name'))&.text
|
61
|
+
location = a&.at(ns('./affiliation/organization/address/'\
|
62
|
+
'formattedAddress'))&.text
|
63
|
+
m << (!name.nil? && !location.nil? ? "#{name}, #{location}" :
|
64
|
+
(name || location || ''))
|
59
65
|
m
|
60
66
|
end
|
61
67
|
end
|
@@ -84,99 +90,99 @@ module IsoDoc
|
|
84
90
|
end
|
85
91
|
|
86
92
|
def bibdate(isoxml, _out)
|
87
|
-
isoxml.xpath(ns(
|
88
|
-
set("#{d['type'].gsub(/-/,
|
93
|
+
isoxml.xpath(ns('//bibdata/date')).each do |d|
|
94
|
+
set("#{d['type'].gsub(/-/, '_')}date".to_sym, Common::date_range(d))
|
89
95
|
end
|
90
96
|
end
|
91
97
|
|
92
98
|
def doctype(isoxml, _out)
|
93
|
-
b = isoxml&.at(ns(
|
94
|
-
t = b.split(/[- ]/).map
|
99
|
+
b = isoxml&.at(ns('//bibdata/ext/doctype'))&.text || return
|
100
|
+
t = b.split(/[- ]/).map(&:capitalize).join(' ')
|
95
101
|
set(:doctype, t)
|
96
102
|
end
|
97
103
|
|
98
104
|
def iso?(org)
|
99
|
-
name = org&.at(ns(
|
100
|
-
abbrev = org&.at(ns(
|
101
|
-
(abbrev ==
|
102
|
-
name ==
|
105
|
+
name = org&.at(ns('./name'))&.text
|
106
|
+
abbrev = org&.at(ns('./abbreviation'))&.text
|
107
|
+
(abbrev == 'ISO' ||
|
108
|
+
name == 'International Organization for Standardization')
|
103
109
|
end
|
104
110
|
|
105
111
|
def agency(xml)
|
106
|
-
agency =
|
112
|
+
agency = ''
|
107
113
|
publisher = []
|
108
114
|
xml.xpath(ns("//bibdata/contributor[xmlns:role/@type = 'publisher']/"\
|
109
|
-
|
110
|
-
name = org&.at(ns(
|
111
|
-
agency1 = org&.at(ns(
|
115
|
+
'organization')).each do |org|
|
116
|
+
name = org&.at(ns('./name'))&.text
|
117
|
+
agency1 = org&.at(ns('./abbreviation'))&.text || name
|
112
118
|
publisher << name if name
|
113
|
-
agency = iso?(org) ?
|
119
|
+
agency = iso?(org) ? "ISO/#{agency}" : "#{agency}#{agency1}/"
|
114
120
|
end
|
115
|
-
set(:agency, agency.sub(%r{/$},
|
116
|
-
set(:publisher, multiple_and(publisher, @labels[
|
121
|
+
set(:agency, agency.sub(%r{/$}, ''))
|
122
|
+
set(:publisher, multiple_and(publisher, @labels['and']))
|
117
123
|
end
|
118
124
|
|
119
125
|
def multiple_and(names, andword)
|
120
|
-
return
|
126
|
+
return '' if names.empty?
|
121
127
|
return names[0] if names.length == 1
|
122
|
-
names.length == 2
|
123
|
-
return l10n("#{names[0]} #{andword} #{names[1]}", @lang, @script)
|
124
|
-
l10n(names[0..-2].join(
|
128
|
+
(names.length == 2) &&
|
129
|
+
(return l10n("#{names[0]} #{andword} #{names[1]}", @lang, @script))
|
130
|
+
l10n(names[0..-2].join(', ') + " #{andword} #{names[-1]}", @lang, @script)
|
125
131
|
end
|
126
132
|
|
127
133
|
def docstatus(isoxml, _out)
|
128
|
-
docstatus = isoxml.at(ns(
|
134
|
+
docstatus = isoxml.at(ns('//bibdata/status/stage'))
|
129
135
|
set(:unpublished, true)
|
130
136
|
if docstatus
|
131
137
|
set(:stage, status_print(docstatus.text))
|
132
|
-
i = isoxml&.at(ns(
|
138
|
+
(i = isoxml&.at(ns('//bibdata/status/substage'))&.text) &&
|
133
139
|
set(:substage, i)
|
134
|
-
i = isoxml&.at(ns(
|
140
|
+
(i = isoxml&.at(ns('//bibdata/status/iteration'))&.text) &&
|
135
141
|
set(:iteration, i)
|
136
142
|
set(:unpublished, unpublished(docstatus.text))
|
137
|
-
unpublished(docstatus.text)
|
143
|
+
unpublished(docstatus.text) &&
|
138
144
|
set(:stageabbr, stage_abbr(docstatus.text))
|
139
145
|
end
|
140
146
|
end
|
141
147
|
|
142
148
|
def stage_abbr(docstatus)
|
143
|
-
status_print(docstatus).split(/ /)
|
144
|
-
|
149
|
+
status_print(docstatus).split(/ /)
|
150
|
+
.map { |s| s[0].upcase }.join('')
|
145
151
|
end
|
146
152
|
|
147
153
|
def unpublished(status)
|
148
|
-
!
|
154
|
+
!status.casecmp('published').zero?
|
149
155
|
end
|
150
156
|
|
151
157
|
def status_print(status)
|
152
|
-
status.split(/-/).map
|
158
|
+
status.split(/-/).map(&:capitalize).join(' ')
|
153
159
|
end
|
154
160
|
|
155
161
|
def docid(isoxml, _out)
|
156
|
-
dn = isoxml.at(ns(
|
162
|
+
dn = isoxml.at(ns('//bibdata/docidentifier'))
|
157
163
|
set(:docnumber, dn&.text)
|
158
164
|
end
|
159
165
|
|
160
166
|
def docnumeric(isoxml, _out)
|
161
|
-
dn = isoxml.at(ns(
|
167
|
+
dn = isoxml.at(ns('//bibdata/docnumber'))
|
162
168
|
set(:docnumeric, dn&.text)
|
163
169
|
end
|
164
170
|
|
165
171
|
def draftinfo(draft, revdate)
|
166
|
-
draftinfo =
|
172
|
+
draftinfo = ''
|
167
173
|
if draft
|
168
|
-
draftinfo = " (#{@labels[
|
174
|
+
draftinfo = " (#{@labels['draft_label']} #{draft}"
|
169
175
|
draftinfo += ", #{revdate}" if revdate
|
170
|
-
draftinfo +=
|
176
|
+
draftinfo += ')'
|
171
177
|
end
|
172
178
|
l10n(draftinfo, @lang, @script)
|
173
179
|
end
|
174
180
|
|
175
181
|
def version(isoxml, _out)
|
176
|
-
set(:edition, isoxml&.at(ns(
|
177
|
-
set(:docyear, isoxml&.at(ns(
|
178
|
-
set(:draft, isoxml&.at(ns(
|
179
|
-
revdate = isoxml&.at(ns(
|
182
|
+
set(:edition, isoxml&.at(ns('//bibdata/edition'))&.text)
|
183
|
+
set(:docyear, isoxml&.at(ns('//bibdata/copyright/from'))&.text)
|
184
|
+
set(:draft, isoxml&.at(ns('//version/draft'))&.text)
|
185
|
+
revdate = isoxml&.at(ns('//version/revision-date'))&.text
|
180
186
|
set(:revdate, revdate)
|
181
187
|
set(:revdate_monthyear, monthyr(revdate))
|
182
188
|
set(:draftinfo,
|
@@ -188,7 +194,7 @@ module IsoDoc
|
|
188
194
|
set(:doctitle, main)
|
189
195
|
end
|
190
196
|
|
191
|
-
def subtitle(
|
197
|
+
def subtitle(_isoxml, _out)
|
192
198
|
nil
|
193
199
|
end
|
194
200
|
|
@@ -199,24 +205,30 @@ module IsoDoc
|
|
199
205
|
|
200
206
|
def relations_partof(isoxml)
|
201
207
|
std = isoxml.at(ns("//bibdata/relation[@type = 'partOf']")) || return
|
202
|
-
id = std.at(ns(
|
208
|
+
id = std.at(ns('.//docidentifier'))
|
203
209
|
set(:partof, id.text) if id
|
204
210
|
end
|
205
211
|
|
206
212
|
def relations_obsoletes(isoxml)
|
207
213
|
std = isoxml.at(ns("//bibdata/relation[@type = 'obsoletes']")) || return
|
208
|
-
locality = std.at(ns(
|
209
|
-
id = std.at(ns(
|
214
|
+
locality = std.at(ns('.//locality'))
|
215
|
+
id = std.at(ns('.//docidentifier'))
|
210
216
|
set(:obsoletes, id.text) if id
|
211
217
|
set(:obsoletes_part, locality.text) if locality
|
212
218
|
end
|
213
219
|
|
214
220
|
def url(xml, _out)
|
215
|
-
a = xml.at(ns(
|
216
|
-
a = xml.at(ns("//bibdata/uri[@type = 'html']"))
|
217
|
-
a = xml.at(ns("//bibdata/uri[@type = 'xml']"))
|
218
|
-
a = xml.at(ns("//bibdata/uri[@type = 'pdf']"))
|
219
|
-
a = xml.at(ns("//bibdata/uri[@type = 'doc']"))
|
221
|
+
(a = xml.at(ns('//bibdata/uri[not(@type)]'))) && set(:url, a.text)
|
222
|
+
(a = xml.at(ns("//bibdata/uri[@type = 'html']"))) && set(:html, a.text)
|
223
|
+
(a = xml.at(ns("//bibdata/uri[@type = 'xml']"))) && set(:xml, a.text)
|
224
|
+
(a = xml.at(ns("//bibdata/uri[@type = 'pdf']"))) && set(:pdf, a.text)
|
225
|
+
(a = xml.at(ns("//bibdata/uri[@type = 'doc']"))) && set(:doc, a.text)
|
226
|
+
end
|
227
|
+
|
228
|
+
def keywords(isoxml, _out)
|
229
|
+
ret = []
|
230
|
+
isoxml.xpath(ns('//bibdata/keyword')).each { |kw| ret << kw.text }
|
231
|
+
set(:keywords, ret)
|
220
232
|
end
|
221
233
|
end
|
222
234
|
end
|