codeless_code 0.1.8 → 0.2.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/.gitmodules +1 -1
- data/.reek.yml +2 -0
- data/Gemfile +0 -1
- data/Gemfile.lock +0 -2
- data/Guardfile +15 -13
- data/VERSION +1 -1
- data/codeless_code.gemspec +11 -10
- data/data/the-codeless-code/de-andrebogus/case-193.txt +1 -1
- data/data/the-codeless-code/de-andrebogus/case-74.txt +1 -1
- data/data/the-codeless-code/en-qi/case-194.txt +1 -1
- data/data/the-codeless-code/en-qi/case-74.txt +1 -1
- data/lib/codeless_code/cli.rb +1 -1
- data/lib/codeless_code/fable.rb +1 -1
- data/lib/codeless_code/formats/base.rb +2 -19
- data/lib/codeless_code/formats/plain.rb +34 -21
- data/lib/codeless_code/formats/term.rb +48 -18
- data/lib/codeless_code/markup/converter.rb +78 -0
- data/lib/codeless_code/markup/nodes.rb +64 -0
- data/lib/codeless_code/markup/parser.rb +152 -0
- data/lib/codeless_code/renderers/term_page.rb +1 -1
- data/lib/codeless_code.rb +7 -7
- data/test/codeless_code/filters/{test_langs.rb → test_lang.rb} +0 -0
- data/test/codeless_code/formats/test_plain.rb +74 -0
- data/{lib/codeless_code/formats/parsers/plain.rb → test/codeless_code/formats/test_raw.rb} +6 -28
- data/test/codeless_code/formats/test_term.rb +72 -0
- data/test/codeless_code/markup/test_parser.rb +177 -0
- data/test/codeless_code/test_cli.rb +75 -2
- data/test/support/fs.rb +15 -0
- metadata +10 -20
- data/lib/codeless_code/formats/parsers/base.rb +0 -106
- data/lib/codeless_code/formats/parsers/term.rb +0 -79
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c894ee4dd542acaa1728467fed14bb268637e7ff83b879b124f2b1c7648822f4
|
4
|
+
data.tar.gz: 0a7e08880e5a9f3391602f0a78519456f82b3dff75128ddc72ca50e043355d04
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f3696c7bdaafdd0da45751f727c48c1a2cf1aa258a66a5f430f759d09514c67f81f7dca8641d1a4f4d4ae645090561ea25346e5d4b4e6978c4a900b6c35b076
|
7
|
+
data.tar.gz: d5c134eac07fb092af685b8e547e07447b72d99301ae225b60168c3c4ef6232a755b699f7e66e2873f3ff8aef9cd9a203c97a9c10d04c6f9d5d9182f34965af8
|
data/.gitmodules
CHANGED
data/.reek.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -74,7 +74,6 @@ GEM
|
|
74
74
|
rb-inotify (~> 0.9, >= 0.9.7)
|
75
75
|
ruby_dep (~> 1.2)
|
76
76
|
lumberjack (1.0.13)
|
77
|
-
mediacloth (0.6)
|
78
77
|
method_source (0.9.0)
|
79
78
|
mime-types (2.99.3)
|
80
79
|
mini_portile2 (2.3.0)
|
@@ -161,7 +160,6 @@ DEPENDENCIES
|
|
161
160
|
guard-reek (~> 1.2)
|
162
161
|
guard-rubocop (~> 1.3)
|
163
162
|
jeweler (~> 2.0)
|
164
|
-
mediacloth (~> 0.6)
|
165
163
|
minitest (~> 5.11)
|
166
164
|
minitest-reporters (~> 1.3)
|
167
165
|
nokogiri (~> 1.8)
|
data/Guardfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
+
# vim:ft=ruby:
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
|
-
# vim:ft=ruby:
|
4
4
|
# codeless_code filters and prints fables from http://thecodelesscode.com
|
5
5
|
# Copyright (C) 2018 Jon Sangster
|
6
6
|
#
|
@@ -16,18 +16,20 @@
|
|
16
16
|
#
|
17
17
|
# You should have received a copy of the GNU General Public License along with
|
18
18
|
# this program. If not, see <https://www.gnu.org/licenses/>.
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
group :everything, halt_on_fail: true do
|
20
|
+
guard :minitest, all_after_pass: true do
|
21
|
+
watch(%r{^test/(.*)\/?test_(.*)\.rb$})
|
22
|
+
watch(%r{^lib/(.*/)?([^/]+)\.rb$}) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
|
23
|
+
watch(%r{^test/helper\.rb$}) { 'test' }
|
24
|
+
end
|
24
25
|
|
25
|
-
guard :reek do
|
26
|
-
|
27
|
-
|
28
|
-
end
|
26
|
+
guard :reek do
|
27
|
+
watch(%r{^lib/.+\.rb$})
|
28
|
+
watch('.reek.yml')
|
29
|
+
end
|
29
30
|
|
30
|
-
guard :rubocop do
|
31
|
-
|
32
|
-
|
31
|
+
guard :rubocop do
|
32
|
+
watch(/.+\.rb$/)
|
33
|
+
watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
|
34
|
+
end
|
33
35
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/codeless_code.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: codeless_code 0.
|
5
|
+
# stub: codeless_code 0.2.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "codeless_code".freeze
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.2.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Jon Sangster".freeze]
|
14
|
-
s.date = "2018-11-
|
14
|
+
s.date = "2018-11-17"
|
15
15
|
s.description = "http://thecodelesscode.com contains many humorous and interesting fables and koans. The authors have open-sourced these fables, and many tanslations, available at https://github.com/aldesantis/the-codeless-code. This tool provides a CLI to filter through these fables and view them.".freeze
|
16
16
|
s.email = "jon@ertt.ca".freeze
|
17
17
|
s.executables = ["codeless_code".freeze]
|
@@ -1495,13 +1495,13 @@ Gem::Specification.new do |s|
|
|
1495
1495
|
"lib/codeless_code/filters/lang.rb",
|
1496
1496
|
"lib/codeless_code/filters/translator.rb",
|
1497
1497
|
"lib/codeless_code/formats/base.rb",
|
1498
|
-
"lib/codeless_code/formats/parsers/base.rb",
|
1499
|
-
"lib/codeless_code/formats/parsers/plain.rb",
|
1500
|
-
"lib/codeless_code/formats/parsers/term.rb",
|
1501
1498
|
"lib/codeless_code/formats/plain.rb",
|
1502
1499
|
"lib/codeless_code/formats/raw.rb",
|
1503
1500
|
"lib/codeless_code/formats/term.rb",
|
1504
1501
|
"lib/codeless_code/language_set.rb",
|
1502
|
+
"lib/codeless_code/markup/converter.rb",
|
1503
|
+
"lib/codeless_code/markup/nodes.rb",
|
1504
|
+
"lib/codeless_code/markup/parser.rb",
|
1505
1505
|
"lib/codeless_code/options.rb",
|
1506
1506
|
"lib/codeless_code/renderers/fable.rb",
|
1507
1507
|
"lib/codeless_code/renderers/term_page.rb",
|
@@ -1511,8 +1511,12 @@ Gem::Specification.new do |s|
|
|
1511
1511
|
"test/codeless_code/filters/test_builders.rb",
|
1512
1512
|
"test/codeless_code/filters/test_composite.rb",
|
1513
1513
|
"test/codeless_code/filters/test_date.rb",
|
1514
|
-
"test/codeless_code/filters/
|
1514
|
+
"test/codeless_code/filters/test_lang.rb",
|
1515
1515
|
"test/codeless_code/filters/test_translator.rb",
|
1516
|
+
"test/codeless_code/formats/test_plain.rb",
|
1517
|
+
"test/codeless_code/formats/test_raw.rb",
|
1518
|
+
"test/codeless_code/formats/test_term.rb",
|
1519
|
+
"test/codeless_code/markup/test_parser.rb",
|
1516
1520
|
"test/codeless_code/renderers/test_fable.rb",
|
1517
1521
|
"test/codeless_code/renderers/test_term_page.rb",
|
1518
1522
|
"test/codeless_code/test_catalog.rb",
|
@@ -1534,7 +1538,6 @@ Gem::Specification.new do |s|
|
|
1534
1538
|
|
1535
1539
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
1536
1540
|
s.add_runtime_dependency(%q<colorize>.freeze, ["~> 0.8"])
|
1537
|
-
s.add_runtime_dependency(%q<mediacloth>.freeze, ["~> 0.6"])
|
1538
1541
|
s.add_runtime_dependency(%q<nokogiri>.freeze, ["~> 1.8"])
|
1539
1542
|
s.add_runtime_dependency(%q<slop>.freeze, ["~> 4.6"])
|
1540
1543
|
s.add_development_dependency(%q<bundler>.freeze, ["~> 1.17"])
|
@@ -1554,7 +1557,6 @@ Gem::Specification.new do |s|
|
|
1554
1557
|
s.add_development_dependency(%q<yard>.freeze, ["~> 0.9"])
|
1555
1558
|
else
|
1556
1559
|
s.add_dependency(%q<colorize>.freeze, ["~> 0.8"])
|
1557
|
-
s.add_dependency(%q<mediacloth>.freeze, ["~> 0.6"])
|
1558
1560
|
s.add_dependency(%q<nokogiri>.freeze, ["~> 1.8"])
|
1559
1561
|
s.add_dependency(%q<slop>.freeze, ["~> 4.6"])
|
1560
1562
|
s.add_dependency(%q<bundler>.freeze, ["~> 1.17"])
|
@@ -1575,7 +1577,6 @@ Gem::Specification.new do |s|
|
|
1575
1577
|
end
|
1576
1578
|
else
|
1577
1579
|
s.add_dependency(%q<colorize>.freeze, ["~> 0.8"])
|
1578
|
-
s.add_dependency(%q<mediacloth>.freeze, ["~> 0.6"])
|
1579
1580
|
s.add_dependency(%q<nokogiri>.freeze, ["~> 1.8"])
|
1580
1581
|
s.add_dependency(%q<slop>.freeze, ["~> 4.6"])
|
1581
1582
|
s.add_dependency(%q<bundler>.freeze, ["~> 1.17"])
|
@@ -51,4 +51,4 @@ aufgenommen werden können?"
|
|
51
51
|
lieben?"
|
52
52
|
|
53
53
|
|
54
|
-
{{*}} "Stealthy Wombat" spendete folgendes Gedicht:<p>Enkudu nahm zur Tausend-Meilen-Reise<br>Gehstock, Fisch -- und Navigationsgerät<br>wie glücklich die ersten zwei Schwestern,<br>dass Enkudu ihre Liebe nie schmäht
|
54
|
+
{{*}} "Stealthy Wombat" spendete folgendes Gedicht:<p>Enkudu nahm zur Tausend-Meilen-Reise<br>Gehstock, Fisch -- und Navigationsgerät<br>wie glücklich die ersten zwei Schwestern,<br>dass Enkudu ihre Liebe nie schmäht.
|
@@ -42,4 +42,4 @@ Schalen hässlich und seine Lager klein sind."
|
|
42
42
|
ihrem Handtuch. "Nun sitzt er in einem Haufen Perlen, und hungert nach
|
43
43
|
Austernfleisch."
|
44
44
|
|
45
|
-
{{*}} "Stealthy Wombat" bietet uns dies Gedicht:<p> Yishi-Shing verliert seine Perle im Saal,<br> lässt Yíwen und Hwidah lang sie suchen,<br> Und Ahab quert die See, findet doch nicht den Wal,<br> und so bleibet ihm nichts als zu fluchen
|
45
|
+
{{*}} "Stealthy Wombat" bietet uns dies Gedicht:<p> Yishi-Shing verliert seine Perle im Saal,<br> lässt Yíwen und Hwidah lang sie suchen,<br> Und Ahab quert die See, findet doch nicht den Wal,<br> und so bleibet ihm nichts als zu fluchen.
|
@@ -86,4 +86,4 @@ between order and chaos."
|
|
86
86
|
|
87
87
|
Hearing these words, Zjing was enlightened.
|
88
88
|
|
89
|
-
{{*}} Translator Andre Bogus offers the following poem:<p>The herd was still, the cattle grazed<br>Zjing saw them and was amazed<br>How full of harmony those cows<br>unlike her monks the meadow browse
|
89
|
+
{{*}} Translator Andre Bogus offers the following poem:<p>The herd was still, the cattle grazed<br>Zjing saw them and was amazed<br>How full of harmony those cows<br>unlike her monks the meadow browse
|
@@ -49,4 +49,4 @@ Hwídah from under her towel. 'Now, bedecked in orphan
|
|
49
49
|
pearls, we will starve for want of oyster-meat."
|
50
50
|
|
51
51
|
|
52
|
-
{{*}} "Stealthy Wombat" offers this poem:<p>Yíwen and Hwídah sift the yard for Yishi-Shing's pearl<br>In spring, he loses it again<br>Ahab searched the seas for the white whale<br>The whale was white, but oh! So broad the ocean
|
52
|
+
{{*}} "Stealthy Wombat" offers this poem:<p>Yíwen and Hwídah sift the yard for Yishi-Shing's pearl<br>In spring, he loses it again<br>Ahab searched the seas for the white whale<br>The whale was white, but oh! So broad the ocean!
|
data/lib/codeless_code/cli.rb
CHANGED
@@ -32,7 +32,6 @@ module CodelessCode
|
|
32
32
|
call_io(user_io)
|
33
33
|
rescue Slop::Error => err
|
34
34
|
warn format("%s\n\n%s", err, options.help)
|
35
|
-
exit 1
|
36
35
|
ensure
|
37
36
|
user_io&.close
|
38
37
|
end
|
@@ -98,6 +97,7 @@ module CodelessCode
|
|
98
97
|
end
|
99
98
|
end
|
100
99
|
|
100
|
+
# @return [Random] with a seed value determined by the current date
|
101
101
|
# :reek:UtilityFunction
|
102
102
|
def date_random_generator
|
103
103
|
Random.new(::Date.today.strftime('%Y%m%d').to_i)
|
data/lib/codeless_code/fable.rb
CHANGED
@@ -15,7 +15,6 @@
|
|
15
15
|
#
|
16
16
|
# You should have received a copy of the GNU General Public License along with
|
17
17
|
# this program. If not, see <https://www.gnu.org/licenses/>.
|
18
|
-
require 'mediacloth'
|
19
18
|
require 'nokogiri'
|
20
19
|
|
21
20
|
module CodelessCode
|
@@ -30,24 +29,8 @@ module CodelessCode
|
|
30
29
|
|
31
30
|
protected
|
32
31
|
|
33
|
-
def
|
34
|
-
|
35
|
-
MediaCloth.wiki_to_html(doc.to_s, generator: parser)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# MediaCloth expects XHTML-ish pages and chokes on ommited end tags
|
40
|
-
class XhtmlDoc
|
41
|
-
def self.parse(html)
|
42
|
-
new(Nokogiri::HTML(html))
|
43
|
-
end
|
44
|
-
|
45
|
-
def initialize(doc)
|
46
|
-
@doc = doc
|
47
|
-
end
|
48
|
-
|
49
|
-
def to_s
|
50
|
-
@doc.css('body > *').to_xhtml
|
32
|
+
def render_children(node)
|
33
|
+
node.children.map(&method(:render)).join
|
51
34
|
end
|
52
35
|
end
|
53
36
|
end
|
@@ -15,39 +15,52 @@
|
|
15
15
|
#
|
16
16
|
# You should have received a copy of the GNU General Public License along with
|
17
17
|
# this program. If not, see <https://www.gnu.org/licenses/>.
|
18
|
-
require 'mediacloth'
|
19
|
-
|
20
18
|
module CodelessCode
|
21
19
|
module Formats
|
22
20
|
# Prints the {Fable} without any formatting, but removes the markup.
|
23
21
|
class Plain < Base
|
22
|
+
include Markup::Nodes
|
23
|
+
|
24
24
|
def call
|
25
|
-
|
26
|
-
|
27
|
-
.join("\n\n")
|
25
|
+
main = Markup::Parser.new(raw).call
|
26
|
+
render(Markup::Converter.new(main).call).rstrip
|
28
27
|
end
|
29
28
|
|
30
|
-
|
29
|
+
private
|
31
30
|
|
32
|
-
def
|
33
|
-
|
31
|
+
def render(node)
|
32
|
+
render_leaf(node) || render_container(node) ||
|
33
|
+
raise(format('Unexpected %s: %p', node.class, node))
|
34
|
+
end
|
35
|
+
|
36
|
+
# :reek:UtilityFunction
|
37
|
+
def render_leaf(node)
|
38
|
+
case node
|
39
|
+
when String then node
|
40
|
+
when LineBreak then "\n"
|
41
|
+
when Rule then '- - - - - - - - -' + "\n\n"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def render_container(node)
|
46
|
+
case node
|
47
|
+
when Doc, Bold, Em, Link then render_children(node)
|
48
|
+
when Reference then format('[%s]', render_children(node))
|
49
|
+
when Header then render_header(node)
|
50
|
+
when Para then render_children(node) + "\n\n"
|
51
|
+
when Quote then render_quote(node)
|
52
|
+
end
|
34
53
|
end
|
35
|
-
end
|
36
54
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
@body = body
|
55
|
+
def render_header(node)
|
56
|
+
inner = render_children(node)
|
57
|
+
format("%s\n%s", inner, '-' * inner.length) + "\n\n"
|
41
58
|
end
|
42
59
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
[%r{<b>([^<]+)</b>}mi, '\1'],
|
48
|
-
[%r{<a[^>]+>([^<]+)</a>}mi, '\1'],
|
49
|
-
[%r{/(\w+)/}, '\1']
|
50
|
-
].inject(@body) { |str, args| str.gsub(*args) }
|
60
|
+
def render_quote(node)
|
61
|
+
render_children(node).lines
|
62
|
+
.map { |line| "\t" + line }
|
63
|
+
.join + "\n\n"
|
51
64
|
end
|
52
65
|
end
|
53
66
|
end
|
@@ -16,39 +16,69 @@
|
|
16
16
|
# You should have received a copy of the GNU General Public License along with
|
17
17
|
# this program. If not, see <https://www.gnu.org/licenses/>.
|
18
18
|
require 'colorized_string'
|
19
|
-
require 'mediacloth'
|
20
19
|
|
21
20
|
module CodelessCode
|
22
21
|
module Formats
|
23
22
|
# Renders the {Fable} using ANSI control characters for bold, italics,
|
24
23
|
# colors, etc.
|
25
24
|
class Term < Base
|
25
|
+
include Markup::Nodes
|
26
|
+
|
26
27
|
def call
|
27
|
-
|
28
|
+
render(
|
29
|
+
Markup::Converter.new(
|
30
|
+
Markup::Parser.new(raw).call
|
31
|
+
).call
|
32
|
+
).strip
|
28
33
|
end
|
29
34
|
|
30
|
-
|
31
|
-
|
32
|
-
|
35
|
+
private
|
36
|
+
|
37
|
+
def render(node)
|
38
|
+
render_leaf(node) || render_container(node) || render_style(node) ||
|
39
|
+
raise(format('Unexpected %s: %p', node.class, node))
|
33
40
|
end
|
34
41
|
|
35
|
-
|
42
|
+
def render_leaf(node)
|
43
|
+
case node
|
44
|
+
when String then node
|
45
|
+
when LineBreak then "\n"
|
46
|
+
when Rule then format("%s\n\n", color('- - - - - - - - -').yellow)
|
47
|
+
end
|
48
|
+
end
|
36
49
|
|
37
|
-
def
|
38
|
-
|
50
|
+
def render_style(node)
|
51
|
+
case node
|
52
|
+
when Bold then color(render_children(node)).bold
|
53
|
+
when Em then color(render_children(node)).italic
|
54
|
+
when Reference then color(render_children(node)).yellow
|
55
|
+
end
|
39
56
|
end
|
40
57
|
|
41
|
-
|
58
|
+
def render_container(node)
|
59
|
+
case node
|
60
|
+
when Doc then render_children(node)
|
61
|
+
when Header then render_header(node)
|
62
|
+
when Link then color(render_children(node)).underline
|
63
|
+
when Para then render_children(node) + "\n\n"
|
64
|
+
when Quote then render_quote(node)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def render_header(node)
|
69
|
+
inner = render_children(node)
|
70
|
+
color(format("%s\n%s", inner, '-' * inner.length)).blue + "\n\n"
|
71
|
+
end
|
42
72
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
73
|
+
def render_quote(node)
|
74
|
+
render_children(node).lines
|
75
|
+
.map { |line| "\t" + color(line).green }
|
76
|
+
.join + "\n\n"
|
77
|
+
end
|
78
|
+
|
79
|
+
# :reek:UtilityFunction
|
80
|
+
def color(str)
|
81
|
+
ColorizedString.new(str.to_s)
|
52
82
|
end
|
53
83
|
end
|
54
84
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# codeless_code filters and prints fables from http://thecodelesscode.com
|
4
|
+
# Copyright (C) 2018 Jon Sangster
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify it under
|
7
|
+
# the terms of the GNU General Public License as published by the Free Software
|
8
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
9
|
+
# version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
12
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
+
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
14
|
+
# details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License along with
|
17
|
+
# this program. If not, see <https://www.gnu.org/licenses/>.
|
18
|
+
module CodelessCode
|
19
|
+
module Markup
|
20
|
+
CONTAINER_HTML = {
|
21
|
+
'blockquote' => Nodes::Quote,
|
22
|
+
'b' => Nodes::Bold,
|
23
|
+
'div' => Nodes::Para,
|
24
|
+
'em' => Nodes::Em,
|
25
|
+
'h2' => Nodes::Header,
|
26
|
+
'i' => Nodes::Em,
|
27
|
+
'main' => Nodes::Doc,
|
28
|
+
'p' => Nodes::Para,
|
29
|
+
'span' => Nodes::Para,
|
30
|
+
'strong' => Nodes::Bold,
|
31
|
+
'sup' => Nodes::Reference,
|
32
|
+
'tt' => Nodes::Bold
|
33
|
+
}.freeze
|
34
|
+
|
35
|
+
# Converts {Nokogiri} elements to {Nodes::Node} elements
|
36
|
+
class Converter
|
37
|
+
def initialize(elem)
|
38
|
+
@elem = elem
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [Nodes::Node]
|
42
|
+
def call
|
43
|
+
convert_elem(@elem)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# :reek:FeatureEnvy
|
49
|
+
def convert_elem(elem)
|
50
|
+
if elem.text?
|
51
|
+
elem.content
|
52
|
+
elsif (type = CONTAINER_HTML[elem.name])
|
53
|
+
type.new(convert_children(elem))
|
54
|
+
else
|
55
|
+
convert_special(elem)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def convert_children(elem)
|
60
|
+
elem.children.map { |ch| self.class.new(ch).call }
|
61
|
+
end
|
62
|
+
|
63
|
+
def convert_special(elem)
|
64
|
+
case elem.name
|
65
|
+
when 'a' then convert_link(elem)
|
66
|
+
when 'br' then Nodes::LineBreak.new
|
67
|
+
when 'hr' then Nodes::Rule.new
|
68
|
+
else
|
69
|
+
raise format('Unexpected: %p', elem)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def convert_link(elem)
|
74
|
+
Nodes::Link.new(elem['href'], convert_children(elem))
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# codeless_code filters and prints fables from http://thecodelesscode.com
|
4
|
+
# Copyright (C) 2018 Jon Sangster
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify it under
|
7
|
+
# the terms of the GNU General Public License as published by the Free Software
|
8
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
9
|
+
# version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
12
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
+
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
14
|
+
# details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License along with
|
17
|
+
# this program. If not, see <https://www.gnu.org/licenses/>.
|
18
|
+
module CodelessCode
|
19
|
+
module Markup
|
20
|
+
# Elements representing the markup of a Fable
|
21
|
+
# :reek:ModuleInitialize
|
22
|
+
module Nodes
|
23
|
+
ELEM_CONTAINERS = %i[Doc Para Quote Bold Em Reference Header].freeze
|
24
|
+
ELEM_VOID = %i[LineBreak Rule].freeze
|
25
|
+
|
26
|
+
# An element in the syntax tree
|
27
|
+
class Node
|
28
|
+
def initialize(children = nil)
|
29
|
+
@children = children
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
children.map(&:to_s).join
|
34
|
+
end
|
35
|
+
|
36
|
+
def children
|
37
|
+
@children || []
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
ELEM_CONTAINERS.each do |name|
|
42
|
+
const_set(name, Class.new(Node))
|
43
|
+
end
|
44
|
+
|
45
|
+
ELEM_VOID.each do |name|
|
46
|
+
const_set(name, Class.new(Node) do
|
47
|
+
def initialize
|
48
|
+
super()
|
49
|
+
end
|
50
|
+
end)
|
51
|
+
end
|
52
|
+
|
53
|
+
# A hyperlink. Either +<a href=""></a>+, +[[label]]+, or +[[url|label]]+
|
54
|
+
class Link < Node
|
55
|
+
attr_reader :href
|
56
|
+
|
57
|
+
def initialize(href = nil, children = [])
|
58
|
+
super(children)
|
59
|
+
@href = href
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|