codeless_code 0.1.8 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|