coradoc 0.2.0 → 1.0.0
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/.docker/Dockerfile +1 -1
- data/.docker/docker-compose.yml +2 -2
- data/.editorconfig +15 -0
- data/CHANGELOG.md +4 -0
- data/README.md +4 -0
- data/Rakefile +10 -0
- data/coradoc.gemspec +11 -2
- data/exe/reverse_adoc +91 -0
- data/exe/w2a +72 -0
- data/lib/coradoc/document.rb +6 -6
- data/lib/coradoc/element/admonition.rb +8 -6
- data/lib/coradoc/element/attribute.rb +2 -2
- data/lib/coradoc/element/attribute_list.rb +94 -15
- data/lib/coradoc/element/audio.rb +14 -3
- data/lib/coradoc/element/author.rb +18 -14
- data/lib/coradoc/element/base.rb +69 -8
- data/lib/coradoc/element/block/core.rb +10 -6
- data/lib/coradoc/element/block/literal.rb +1 -1
- data/lib/coradoc/element/block/quote.rb +1 -1
- data/lib/coradoc/element/block/sourcecode.rb +2 -2
- data/lib/coradoc/element/break.rb +1 -1
- data/lib/coradoc/element/document_attributes.rb +6 -6
- data/lib/coradoc/element/header.rb +4 -2
- data/lib/coradoc/element/image/block_image.rb +13 -2
- data/lib/coradoc/element/image/core.rb +35 -5
- data/lib/coradoc/element/image/inline_image.rb +2 -2
- data/lib/coradoc/element/image.rb +0 -1
- data/lib/coradoc/element/inline/anchor.rb +4 -2
- data/lib/coradoc/element/inline/bold.rb +10 -4
- data/lib/coradoc/element/inline/cross_reference.rb +4 -2
- data/lib/coradoc/element/inline/hard_line_break.rb +1 -1
- data/lib/coradoc/element/inline/highlight.rb +12 -6
- data/lib/coradoc/element/inline/italic.rb +10 -4
- data/lib/coradoc/element/inline/link.rb +26 -10
- data/lib/coradoc/element/inline/monospace.rb +10 -4
- data/lib/coradoc/element/inline/quotation.rb +4 -1
- data/lib/coradoc/element/inline/subscript.rb +5 -2
- data/lib/coradoc/element/inline/superscript.rb +5 -2
- data/lib/coradoc/element/inline.rb +0 -1
- data/lib/coradoc/element/list/core.rb +10 -8
- data/lib/coradoc/element/list/definition.rb +19 -0
- data/lib/coradoc/element/list/ordered.rb +1 -1
- data/lib/coradoc/element/list/unordered.rb +1 -1
- data/lib/coradoc/element/list.rb +1 -1
- data/lib/coradoc/element/list_item.rb +9 -4
- data/lib/coradoc/element/list_item_definition.rb +32 -0
- data/lib/coradoc/element/paragraph.rb +5 -3
- data/lib/coradoc/element/revision.rb +20 -16
- data/lib/coradoc/element/section.rb +21 -4
- data/lib/coradoc/element/table.rb +36 -19
- data/lib/coradoc/element/text_element.rb +63 -17
- data/lib/coradoc/element/title.rb +27 -7
- data/lib/coradoc/element/video.rb +33 -6
- data/lib/coradoc/generator.rb +2 -2
- data/lib/coradoc/legacy_parser.rb +41 -41
- data/lib/coradoc/oscal.rb +2 -4
- data/lib/coradoc/parser/asciidoc/content.rb +15 -15
- data/lib/coradoc/parser/asciidoc/document_attributes.rb +1 -1
- data/lib/coradoc/parser/asciidoc/header.rb +6 -6
- data/lib/coradoc/parser/asciidoc/section.rb +1 -1
- data/lib/coradoc/reverse_adoc/LICENSE.txt +25 -0
- data/lib/coradoc/reverse_adoc/README.adoc +308 -0
- data/lib/coradoc/reverse_adoc/cleaner.rb +125 -0
- data/lib/coradoc/reverse_adoc/config.rb +73 -0
- data/lib/coradoc/reverse_adoc/converters/a.rb +47 -0
- data/lib/coradoc/reverse_adoc/converters/aside.rb +12 -0
- data/lib/coradoc/reverse_adoc/converters/audio.rb +25 -0
- data/lib/coradoc/reverse_adoc/converters/base.rb +104 -0
- data/lib/coradoc/reverse_adoc/converters/blockquote.rb +18 -0
- data/lib/coradoc/reverse_adoc/converters/br.rb +11 -0
- data/lib/coradoc/reverse_adoc/converters/bypass.rb +77 -0
- data/lib/coradoc/reverse_adoc/converters/code.rb +19 -0
- data/lib/coradoc/reverse_adoc/converters/div.rb +14 -0
- data/lib/coradoc/reverse_adoc/converters/dl.rb +55 -0
- data/lib/coradoc/reverse_adoc/converters/drop.rb +22 -0
- data/lib/coradoc/reverse_adoc/converters/em.rb +17 -0
- data/lib/coradoc/reverse_adoc/converters/figure.rb +21 -0
- data/lib/coradoc/reverse_adoc/converters/h.rb +38 -0
- data/lib/coradoc/reverse_adoc/converters/head.rb +19 -0
- data/lib/coradoc/reverse_adoc/converters/hr.rb +11 -0
- data/lib/coradoc/reverse_adoc/converters/ignore.rb +16 -0
- data/lib/coradoc/reverse_adoc/converters/img.rb +98 -0
- data/lib/coradoc/reverse_adoc/converters/li.rb +13 -0
- data/lib/coradoc/reverse_adoc/converters/mark.rb +15 -0
- data/lib/coradoc/reverse_adoc/converters/markup.rb +27 -0
- data/lib/coradoc/reverse_adoc/converters/math.rb +31 -0
- data/lib/coradoc/reverse_adoc/converters/ol.rb +60 -0
- data/lib/coradoc/reverse_adoc/converters/p.rb +19 -0
- data/lib/coradoc/reverse_adoc/converters/pass_through.rb +13 -0
- data/lib/coradoc/reverse_adoc/converters/pre.rb +51 -0
- data/lib/coradoc/reverse_adoc/converters/q.rb +12 -0
- data/lib/coradoc/reverse_adoc/converters/strong.rb +16 -0
- data/lib/coradoc/reverse_adoc/converters/sub.rb +18 -0
- data/lib/coradoc/reverse_adoc/converters/sup.rb +18 -0
- data/lib/coradoc/reverse_adoc/converters/table.rb +280 -0
- data/lib/coradoc/reverse_adoc/converters/td.rb +77 -0
- data/lib/coradoc/reverse_adoc/converters/text.rb +28 -0
- data/lib/coradoc/reverse_adoc/converters/th.rb +14 -0
- data/lib/coradoc/reverse_adoc/converters/tr.rb +18 -0
- data/lib/coradoc/reverse_adoc/converters/video.rb +25 -0
- data/lib/coradoc/reverse_adoc/converters.rb +53 -0
- data/lib/coradoc/reverse_adoc/errors.rb +10 -0
- data/lib/coradoc/reverse_adoc/html_converter.rb +150 -0
- data/lib/coradoc/reverse_adoc/plugin.rb +131 -0
- data/lib/coradoc/reverse_adoc/plugins/plateau.rb +174 -0
- data/lib/coradoc/reverse_adoc/postprocessor.rb +148 -0
- data/lib/coradoc/reverse_adoc.rb +30 -0
- data/lib/coradoc/transformer.rb +24 -14
- data/lib/coradoc/version.rb +1 -1
- data/lib/reverse_adoc.rb +20 -0
- metadata +184 -5
- data/lib/coradoc/element/inline/image.rb +0 -25
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 71bfd2ac723d58ca75b591bceabcdf834abd9cbbf32e54b96352da21b8f15095
|
|
4
|
+
data.tar.gz: 1a7ea6bf80d64ab4c1349c948aa2aee9ed704dc36ddd07fb7cce78293dca86cd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 555800621a06ffafc07e03a5c2cdca1210de6369d524a606de51df78b1ee9b19aaba30d32d8a448347237e488362a59677781a02502a1d8891fb89aa1cc267f5
|
|
7
|
+
data.tar.gz: 22707b18c6ed99fb4c6127885d871875ed1fed2906d2d10dcdd5f4ed9bdd1b1bfe3f19fd092768ccc4d488bdb7e705aba9ba7ab948ceace9cc679f1ee733eddc
|
data/.docker/Dockerfile
CHANGED
data/.docker/docker-compose.yml
CHANGED
data/.editorconfig
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# EditorConfig is awesome: http://EditorConfig.org
|
|
2
|
+
|
|
3
|
+
# top-most EditorConfig file
|
|
4
|
+
root = true
|
|
5
|
+
|
|
6
|
+
# Unix-style newlines with a newline ending every file
|
|
7
|
+
[*]
|
|
8
|
+
charset = utf-8
|
|
9
|
+
end_of_line = lf
|
|
10
|
+
|
|
11
|
+
[{*.adoc,*.html,*.js,*.json,*.rake,*.rb,*.rf,*.yaml,*.yml,Rakefile,rakefile}]
|
|
12
|
+
indent_style = space
|
|
13
|
+
indent_size = 2
|
|
14
|
+
insert_final_newline = true
|
|
15
|
+
trim_trailing_whitespace = true
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -66,4 +66,8 @@ Coradoc::Parser.parse(sample_asciidoc)
|
|
|
66
66
|
|
|
67
67
|
This interface will return the abstract syntax tree.
|
|
68
68
|
|
|
69
|
+
### Converting from HTML to AsciiDoc (reverse_adoc)
|
|
70
|
+
|
|
71
|
+
See: [reverse_adoc README](https://github.com/metanorma/coradoc/blob/main/lib/coradoc/reverse_adoc/README.adoc)
|
|
72
|
+
|
|
69
73
|
[sandi-metz]: http://robots.thoughtbot.com/post/50655960596/sandi-metz-rules-for-developers
|
data/Rakefile
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "bundler/gem_tasks"
|
|
4
|
+
|
|
5
|
+
if File.exist?(".codeclimate")
|
|
6
|
+
ENV["CODECLIMATE_REPO_TOKEN"] = File.read(".codeclimate").strip
|
|
7
|
+
end
|
|
8
|
+
|
|
4
9
|
require "rspec/core/rake_task"
|
|
5
10
|
|
|
6
11
|
RSpec::Core::RakeTask.new(:spec)
|
|
7
12
|
task default: :spec
|
|
13
|
+
|
|
14
|
+
desc "Open an irb session preloaded with this library"
|
|
15
|
+
task :console do
|
|
16
|
+
sh "irb -Ilib -rcoradoc -rcoradoc/reverse_adoc"
|
|
17
|
+
end
|
data/coradoc.gemspec
CHANGED
|
@@ -28,11 +28,20 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
spec.require_paths = ["lib"]
|
|
29
29
|
spec.required_ruby_version = ">= 2.7.0"
|
|
30
30
|
|
|
31
|
-
spec.add_dependency "
|
|
31
|
+
spec.add_dependency "marcel", "~> 1.0.0"
|
|
32
|
+
spec.add_dependency "mathml2asciimath"
|
|
33
|
+
spec.add_dependency "nokogiri", "~> 1.13"
|
|
32
34
|
spec.add_dependency "oscal", "~> 0.1.1"
|
|
33
|
-
|
|
35
|
+
spec.add_dependency "parslet"
|
|
36
|
+
spec.add_dependency "premailer", "~> 1.11.0"
|
|
37
|
+
spec.add_dependency "word-to-markdown"
|
|
38
|
+
spec.add_development_dependency "codeclimate-test-reporter"
|
|
34
39
|
spec.add_development_dependency "pry"
|
|
35
40
|
spec.add_development_dependency "rake"
|
|
41
|
+
spec.add_development_dependency "redcarpet"
|
|
36
42
|
spec.add_development_dependency "rspec"
|
|
37
43
|
spec.add_development_dependency "rubocop"
|
|
44
|
+
spec.add_development_dependency "rubocop-performance"
|
|
45
|
+
spec.add_development_dependency "simplecov"
|
|
46
|
+
# spec.add_runtime_dependency "thor"
|
|
38
47
|
end
|
data/exe/reverse_adoc
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# Usage: reverse_adoc [FILE]...
|
|
3
|
+
# Usage: cat FILE | reverse_adoc
|
|
4
|
+
require "rubygems"
|
|
5
|
+
require "bundler/setup"
|
|
6
|
+
|
|
7
|
+
require "coradoc/reverse_adoc"
|
|
8
|
+
require "optparse"
|
|
9
|
+
require "fileutils"
|
|
10
|
+
|
|
11
|
+
OptionParser.new do |opts|
|
|
12
|
+
opts.banner = "Usage: reverse_adoc [options] <file>"
|
|
13
|
+
opts.on("-m", "--mathml2asciimath", "Convert MathML to AsciiMath") do |_v|
|
|
14
|
+
Coradoc::ReverseAdoc.config.mathml2asciimath = true
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
opts.on("-oFILENAME", "--output=FILENAME", "Output file to write to") do |v|
|
|
18
|
+
Coradoc::ReverseAdoc.config.destination = File.expand_path(v)
|
|
19
|
+
# puts "output goes to #{Coradoc::ReverseAdoc.config.destination}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
opts.on("-e", "--external-images", "Export images if data URI") do |_v|
|
|
23
|
+
Coradoc::ReverseAdoc.config.external_images = true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
opts.on("-u", "--unknown_tags [pass_through, drop, bypass, raise]",
|
|
27
|
+
"Unknown tag handling (default: pass_through)") do |v|
|
|
28
|
+
Coradoc::ReverseAdoc.config.unknown_tags = v
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
opts.on("-r", "--require RUBYMODULE", "Require additional Ruby file") do |v|
|
|
32
|
+
require v
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
opts.on("--track-time", "Track time spent on each step") do
|
|
36
|
+
Coradoc::ReverseAdoc.config.track_time = true
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
opts.on("--split-sections LEVEL", "Split sections up to LEVEL") do |i|
|
|
40
|
+
Coradoc::ReverseAdoc.config.split_sections = i.to_i
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
opts.on("-v", "--version", "Version information") do |_v|
|
|
44
|
+
puts "reverse_adoc: v#{Coradoc::ReverseAdoc::VERSION}"
|
|
45
|
+
exit
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
opts.on("-h", "--help", "Prints this help") do
|
|
49
|
+
puts opts
|
|
50
|
+
exit
|
|
51
|
+
end
|
|
52
|
+
end.parse!
|
|
53
|
+
|
|
54
|
+
if filename = ARGV.pop
|
|
55
|
+
input_content = IO.read(filename)
|
|
56
|
+
Coradoc::ReverseAdoc.config.sourcedir = File.dirname(File.expand_path(filename))
|
|
57
|
+
else
|
|
58
|
+
if Coradoc::ReverseAdoc.config.external_images
|
|
59
|
+
raise "The -e | --external-images feature cannot be used with STDIN input. Exiting."
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
input_content = ARGF.read
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
if Coradoc::ReverseAdoc.config.external_images && Coradoc::ReverseAdoc.config.destination.nil?
|
|
66
|
+
raise "The -e | --external-images feature must be used with -o | --output. Exiting."
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
if Coradoc::ReverseAdoc.config.split_sections && Coradoc::ReverseAdoc.config.destination.nil?
|
|
70
|
+
raise "The --split_sections feature must be used with -o | --output. Exiting."
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Read from STDIN
|
|
74
|
+
adoc_content = Coradoc::ReverseAdoc.convert(input_content)
|
|
75
|
+
|
|
76
|
+
# Print to STDOUT
|
|
77
|
+
unless Coradoc::ReverseAdoc.config.destination
|
|
78
|
+
puts adoc_content
|
|
79
|
+
exit
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Write output to Coradoc::ReverseAdoc.config.destination
|
|
83
|
+
adoc_content = {nil => adoc_content} unless adoc_content.is_a? Hash
|
|
84
|
+
|
|
85
|
+
adoc_content.each do |file, content|
|
|
86
|
+
destination = Coradoc::ReverseAdoc.config.destination
|
|
87
|
+
destdir = File.dirname(destination)
|
|
88
|
+
filename = file ? "#{destdir}/#{file}" : destination
|
|
89
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
|
90
|
+
File.write(filename, content)
|
|
91
|
+
end
|
data/exe/w2a
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "rubygems"
|
|
5
|
+
require "bundler/setup"
|
|
6
|
+
|
|
7
|
+
require "word-to-markdown"
|
|
8
|
+
require "optparse"
|
|
9
|
+
require "coradoc/reverse_adoc"
|
|
10
|
+
|
|
11
|
+
ARGV.push("-h") if ARGV.empty?
|
|
12
|
+
|
|
13
|
+
OptionParser.new do |opts|
|
|
14
|
+
opts.banner = "Usage: w2a [options] <file>"
|
|
15
|
+
opts.on("-m", "--mathml2asciimath", "Convert MathML to AsciiMath") do |_v|
|
|
16
|
+
Coradoc::ReverseAdoc.config.mathml2asciimath = true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
opts.on("-oFILENAME", "--output=FILENAME", "Output file to write to") do |v|
|
|
20
|
+
Coradoc::ReverseAdoc.config.destination = File.expand_path(v)
|
|
21
|
+
# puts "output goes to #{Coradoc::ReverseAdoc.config.destination}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
opts.on("-e", "--external-images", "Export images if data URI") do |_v|
|
|
25
|
+
Coradoc::ReverseAdoc.config.external_images = true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
opts.on("-v", "--version", "Version information") do |_v|
|
|
29
|
+
puts "reverse_adoc: v#{Coradoc::ReverseAdoc::VERSION}"
|
|
30
|
+
puts "[dependency] WordToMarkdown: v#{WordToMarkdown::VERSION}"
|
|
31
|
+
if Gem.win_platform?
|
|
32
|
+
puts "[dependency] LibreOffice: version not available on Windows"
|
|
33
|
+
else
|
|
34
|
+
puts "[dependency] LibreOffice: v#{WordToMarkdown.soffice.version}"
|
|
35
|
+
end
|
|
36
|
+
exit
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
opts.on("-h", "--help", "Prints this help") do
|
|
40
|
+
puts opts
|
|
41
|
+
exit
|
|
42
|
+
end
|
|
43
|
+
end.parse!
|
|
44
|
+
|
|
45
|
+
filename = ARGV.pop
|
|
46
|
+
raise "Please provide an input file to process. Exiting." unless filename
|
|
47
|
+
|
|
48
|
+
if Coradoc::ReverseAdoc.config.external_images && Coradoc::ReverseAdoc.config.destination.nil?
|
|
49
|
+
raise "The -e | --external-images feature must be used with -o | --output. Exiting."
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
Coradoc::ReverseAdoc.config.sourcedir = Dir.mktmpdir
|
|
53
|
+
|
|
54
|
+
doc = WordToMarkdown.new(filename, Coradoc::ReverseAdoc.config.sourcedir)
|
|
55
|
+
# File.open("test.html", "w:UTF-8") { |f| f.write doc.document.html }
|
|
56
|
+
adoc_content = Coradoc::ReverseAdoc.convert(
|
|
57
|
+
Coradoc::ReverseAdoc.cleaner.preprocess_word_html(doc.document.html),
|
|
58
|
+
WordToMarkdown::REVERSE_MARKDOWN_OPTIONS,
|
|
59
|
+
)
|
|
60
|
+
# puts scrub_whitespace(doc.document.html)
|
|
61
|
+
|
|
62
|
+
# Print to STDOUT
|
|
63
|
+
unless Coradoc::ReverseAdoc.config.destination
|
|
64
|
+
puts adoc_content
|
|
65
|
+
exit
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Write output to Coradoc::ReverseAdoc.config.destination
|
|
69
|
+
FileUtils.mkdir_p(File.dirname(Coradoc::ReverseAdoc.config.destination))
|
|
70
|
+
File.open(Coradoc::ReverseAdoc.config.destination, "w") do |file|
|
|
71
|
+
file.write(adoc_content)
|
|
72
|
+
end
|
data/lib/coradoc/document.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require_relative "element/base"
|
|
1
2
|
require_relative "element/title"
|
|
2
3
|
require_relative "element/block"
|
|
3
4
|
require_relative "element/section"
|
|
@@ -20,7 +21,6 @@ require_relative "element/break"
|
|
|
20
21
|
|
|
21
22
|
module Coradoc
|
|
22
23
|
class Document
|
|
23
|
-
|
|
24
24
|
class << self
|
|
25
25
|
def from_adoc(filename)
|
|
26
26
|
ast = Coradoc::Parser.parse(filename)
|
|
@@ -43,22 +43,22 @@ module Coradoc
|
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
new(
|
|
47
47
|
document_attributes: @document_attributes,
|
|
48
48
|
header: @header,
|
|
49
|
-
sections: @sections
|
|
49
|
+
sections: @sections,
|
|
50
50
|
)
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
attr_accessor :header, :document_attributes, :sections
|
|
55
55
|
|
|
56
|
-
def initialize(options={})
|
|
57
|
-
@document_attributes = options.fetch(:document_attributes,
|
|
56
|
+
def initialize(options = {})
|
|
57
|
+
@document_attributes = options.fetch(:document_attributes,
|
|
58
|
+
Coradoc::Element::DocumentAttributes.new)
|
|
58
59
|
@header = options.fetch(:header, Coradoc::Element::Header.new(""))
|
|
59
60
|
@sections = options.fetch(:sections, [])
|
|
60
61
|
self
|
|
61
62
|
end
|
|
62
|
-
|
|
63
63
|
end
|
|
64
64
|
end
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
module Coradoc
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
module Element
|
|
3
|
+
class Admonition < Base
|
|
4
|
+
attr_accessor :type, :content, :line_break
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
def initialize(content, type, options = {})
|
|
7
|
+
@content = content
|
|
8
|
+
@type = type.downcase.to_sym
|
|
9
|
+
@line_break = options.fetch(:line_break, "")
|
|
10
|
+
end
|
|
9
11
|
end
|
|
10
12
|
end
|
|
11
13
|
end
|
|
@@ -1,45 +1,124 @@
|
|
|
1
1
|
module Coradoc
|
|
2
2
|
module Element
|
|
3
|
-
class AttributeList
|
|
4
|
-
|
|
3
|
+
class AttributeList < Base
|
|
4
|
+
attr_accessor :positional, :named, :rejected_positional, :rejected_named
|
|
5
|
+
|
|
6
|
+
declare_children :positional, :named
|
|
5
7
|
|
|
6
8
|
def initialize(*positional, **named)
|
|
7
9
|
@positional = positional || []
|
|
8
10
|
@named = named || {}
|
|
11
|
+
@rejected_positional = []
|
|
12
|
+
@rejected_named = []
|
|
9
13
|
end
|
|
10
14
|
|
|
11
|
-
def add_positional(attr)
|
|
12
|
-
@positional
|
|
15
|
+
def add_positional(*attr)
|
|
16
|
+
@positional += attr
|
|
13
17
|
end
|
|
14
18
|
|
|
15
19
|
def add_named(name, value)
|
|
16
20
|
@named[name] = value
|
|
17
21
|
end
|
|
18
22
|
|
|
23
|
+
def any?
|
|
24
|
+
!empty?
|
|
25
|
+
end
|
|
26
|
+
|
|
19
27
|
def empty?
|
|
20
28
|
@positional.empty? && @named.empty?
|
|
21
29
|
end
|
|
22
30
|
|
|
23
|
-
def
|
|
31
|
+
def validate_attr(attr, matcher)
|
|
32
|
+
matcher === attr
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def validate_positional(validators)
|
|
36
|
+
@positional.each_with_index do |value, i|
|
|
37
|
+
# TODO: Decide what to do with this value
|
|
38
|
+
_positional_name = validators[i][0]
|
|
39
|
+
|
|
40
|
+
validator = validators[i][1]
|
|
41
|
+
|
|
42
|
+
unless validator && validate_attr(value, validator)
|
|
43
|
+
@positional[i] = nil
|
|
44
|
+
@rejected_positional << [i, value]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
@positional.pop while !@positional.empty? && @positional.last.nil?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def validate_named(validators)
|
|
52
|
+
@named.each_with_index do |(name, value), i|
|
|
53
|
+
name = name.to_sym
|
|
54
|
+
validator = validators[name]
|
|
55
|
+
|
|
56
|
+
unless validator && validate_attr(value, validator)
|
|
57
|
+
@named.delete(name)
|
|
58
|
+
@rejected_named << [name, value]
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def to_adoc(show_empty = true)
|
|
24
64
|
return "[]" if [@positional, @named].all?(:empty?)
|
|
25
65
|
|
|
26
|
-
adoc = ""
|
|
27
|
-
|
|
66
|
+
adoc = +""
|
|
67
|
+
if !@positional.empty?
|
|
68
|
+
adoc << @positional.map { |p| [nil, ""].include?(p) ? '""' : p }.join(",")
|
|
69
|
+
end
|
|
28
70
|
adoc << "," if @positional.any? && @named.any?
|
|
29
71
|
adoc << @named.map do |k, v|
|
|
30
72
|
if v.is_a?(String)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
v2 = "\"#{v2}\""
|
|
73
|
+
v = v.gsub("\"", "\\\"")
|
|
74
|
+
if v.include?(" ") || v.include?(",") || v.include?('"')
|
|
75
|
+
v = "\"#{v}\""
|
|
35
76
|
end
|
|
36
77
|
elsif v.is_a?(Array)
|
|
37
|
-
|
|
78
|
+
v = "\"#{v.join(',')}\""
|
|
38
79
|
end
|
|
39
|
-
[k.to_s, "=",
|
|
80
|
+
[k.to_s, "=", v].join
|
|
40
81
|
end.join(",")
|
|
41
|
-
|
|
42
|
-
|
|
82
|
+
|
|
83
|
+
if !empty? || (empty? && show_empty)
|
|
84
|
+
"[#{adoc}]"
|
|
85
|
+
elsif empty? && !show_empty
|
|
86
|
+
adoc
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
module Matchers
|
|
91
|
+
def one(*args)
|
|
92
|
+
One.new(*args)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
class One
|
|
96
|
+
def initialize(*possibilities)
|
|
97
|
+
@possibilities = possibilities
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def ===(other)
|
|
101
|
+
@possibilities.any? { |i| i === other }
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def many(*args)
|
|
106
|
+
Many.new(*args)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# TODO: Find a way to only reject some values but not all?
|
|
110
|
+
class Many
|
|
111
|
+
def initialize(*possibilities)
|
|
112
|
+
@possibilities = possibilities
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def ===(other)
|
|
116
|
+
other = other.split(",") if other.is_a?(String)
|
|
117
|
+
|
|
118
|
+
other.is_a?(Array) &&
|
|
119
|
+
other.all? { |i| @possibilities.any? { |p| p === i } }
|
|
120
|
+
end
|
|
121
|
+
end
|
|
43
122
|
end
|
|
44
123
|
end
|
|
45
124
|
end
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
module Coradoc
|
|
2
2
|
module Element
|
|
3
|
-
class Audio
|
|
4
|
-
|
|
3
|
+
class Audio < Base
|
|
4
|
+
attr_accessor :id, :title, :src, :options, :anchor, :attributes
|
|
5
|
+
|
|
6
|
+
declare_children :id, :title, :anchor, :attributes
|
|
5
7
|
|
|
6
8
|
def initialize(title, options = {})
|
|
7
9
|
@title = title
|
|
8
10
|
@id = options.fetch(:id, nil)
|
|
9
11
|
@anchor = Inline::Anchor.new(@id) if @id
|
|
10
|
-
@src = options.fetch(:src,
|
|
12
|
+
@src = options.fetch(:src, "")
|
|
11
13
|
@attributes = options.fetch(:attributes, [])
|
|
12
14
|
end
|
|
13
15
|
|
|
@@ -17,6 +19,15 @@ module Coradoc
|
|
|
17
19
|
attrs = @attributes.empty? ? "\[\]" : @attributes.to_adoc
|
|
18
20
|
[anchor, title, "audio::", @src, attrs].join("")
|
|
19
21
|
end
|
|
22
|
+
|
|
23
|
+
extend AttributeList::Matchers
|
|
24
|
+
VALIDATORS_NAMED = {
|
|
25
|
+
title: String,
|
|
26
|
+
start: Integer,
|
|
27
|
+
end: Integer,
|
|
28
|
+
options: many("nofollow", "noopener", "inline", "interactive"),
|
|
29
|
+
opts: many("nofollow", "noopener", "inline", "interactive"),
|
|
30
|
+
}
|
|
20
31
|
end
|
|
21
32
|
end
|
|
22
33
|
end
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
module Coradoc
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
module Element
|
|
3
|
+
class Author < Base
|
|
4
|
+
attr_accessor :email, :last_name, :first_name
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
declare_children :email, :last_name, :first_name
|
|
7
|
+
|
|
8
|
+
def initialize(first_name, last_name, email, middle_name = nil)
|
|
9
|
+
@first_name = first_name
|
|
10
|
+
@last_name = last_name
|
|
11
|
+
@email = email
|
|
12
|
+
@middle_name = middle_name
|
|
13
|
+
end
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
def to_adoc
|
|
16
|
+
adoc = "#{@first_name} "
|
|
17
|
+
adoc << "#{@middle_name} " if @middle_name
|
|
18
|
+
adoc << @last_name.to_s
|
|
19
|
+
adoc << " <#{@email}>" if @email
|
|
20
|
+
adoc
|
|
21
|
+
end
|
|
18
22
|
end
|
|
19
23
|
end
|
|
20
24
|
end
|
data/lib/coradoc/element/base.rb
CHANGED
|
@@ -1,17 +1,78 @@
|
|
|
1
1
|
module Coradoc
|
|
2
2
|
module Element
|
|
3
3
|
class Base
|
|
4
|
-
#
|
|
4
|
+
# The idea here, is that HTML content generators may often introduce
|
|
5
|
+
# a lot of unnecessary markup, that only makes sense in the HTML+CSS
|
|
6
|
+
# context. The idea is that certain cases can be simplified, making it
|
|
7
|
+
# so that the result is equivalent, but much simpler, allowing us to
|
|
8
|
+
# generate a nicer AsciiDoc syntax for those cases.
|
|
9
|
+
def simplify_block_content(content)
|
|
10
|
+
content = Array(content)
|
|
11
|
+
collected_content = []
|
|
12
|
+
content.each do |i|
|
|
13
|
+
case i
|
|
14
|
+
when Coradoc::Element::Section
|
|
15
|
+
return content unless i.safe_to_collapse?
|
|
5
16
|
|
|
6
|
-
|
|
7
|
-
# @document_attributes = extract_document_attributes(asciidoc)
|
|
8
|
-
# end
|
|
17
|
+
simplified = simplify_block_content(i.contents)
|
|
9
18
|
|
|
10
|
-
|
|
19
|
+
if simplified && !simplified.empty?
|
|
20
|
+
collected_content << simplified
|
|
21
|
+
end
|
|
22
|
+
else
|
|
23
|
+
collected_content << i
|
|
24
|
+
end
|
|
25
|
+
end
|
|
11
26
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
27
|
+
collected_content = collected_content.compact
|
|
28
|
+
|
|
29
|
+
# We can safely do this optimization only if there's just one other
|
|
30
|
+
# element inside this structure.
|
|
31
|
+
if collected_content.length <= 1
|
|
32
|
+
collected_content
|
|
33
|
+
else
|
|
34
|
+
content
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.declare_children(*children)
|
|
39
|
+
@children = (@children || []).dup + children
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.visit(element, &block)
|
|
43
|
+
element = yield element, :pre
|
|
44
|
+
element = if element.respond_to? :visit
|
|
45
|
+
element.visit(&block)
|
|
46
|
+
elsif element.is_a? Array
|
|
47
|
+
element.map { |child| visit(child, &block) }.flatten.compact
|
|
48
|
+
elsif element.is_a? Hash
|
|
49
|
+
element.to_h do |k, v|
|
|
50
|
+
[visit(k, &block), visit(v, &block)]
|
|
51
|
+
end
|
|
52
|
+
else
|
|
53
|
+
element
|
|
54
|
+
end
|
|
55
|
+
yield element, :post
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.children_accessors
|
|
59
|
+
@children || []
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def children_accessors
|
|
63
|
+
self.class.children_accessors
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def visit(&block)
|
|
67
|
+
children_accessors.each do |accessor|
|
|
68
|
+
child = public_send(accessor)
|
|
69
|
+
result = self.class.visit(child, &block)
|
|
70
|
+
if result != child
|
|
71
|
+
public_send(:"#{accessor}=", result)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
self
|
|
75
|
+
end
|
|
15
76
|
end
|
|
16
77
|
end
|
|
17
78
|
end
|