reverse_markdown 0.4.7 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +2 -3
  4. data/LICENSE +13 -0
  5. data/README.md +69 -30
  6. data/bin/reverse_markdown +1 -1
  7. data/lib/reverse_markdown/cleaner.rb +66 -0
  8. data/lib/reverse_markdown/config.rb +20 -0
  9. data/lib/reverse_markdown/converters/a.rb +19 -0
  10. data/lib/reverse_markdown/converters/base.rb +24 -0
  11. data/lib/reverse_markdown/converters/blockquote.rb +13 -0
  12. data/lib/reverse_markdown/converters/br.rb +11 -0
  13. data/lib/reverse_markdown/converters/code.rb +11 -0
  14. data/lib/reverse_markdown/converters/div.rb +11 -0
  15. data/lib/reverse_markdown/converters/dump.rb +9 -0
  16. data/lib/reverse_markdown/converters/em.rb +21 -0
  17. data/lib/reverse_markdown/converters/h.rb +17 -0
  18. data/lib/reverse_markdown/converters/hr.rb +11 -0
  19. data/lib/reverse_markdown/converters/img.rb +14 -0
  20. data/lib/reverse_markdown/converters/li.rb +28 -0
  21. data/lib/reverse_markdown/converters/ol.rb +12 -0
  22. data/lib/reverse_markdown/converters/p.rb +11 -0
  23. data/lib/reverse_markdown/converters/pass_through.rb +14 -0
  24. data/lib/reverse_markdown/converters/pre.rb +17 -0
  25. data/lib/reverse_markdown/converters/strong.rb +21 -0
  26. data/lib/reverse_markdown/converters/table.rb +11 -0
  27. data/lib/reverse_markdown/converters/td.rb +13 -0
  28. data/lib/reverse_markdown/converters/text.rb +30 -0
  29. data/lib/reverse_markdown/converters/tr.rb +21 -0
  30. data/lib/reverse_markdown/converters.rb +22 -0
  31. data/lib/reverse_markdown/errors.rb +6 -2
  32. data/lib/reverse_markdown/version.rb +1 -1
  33. data/lib/reverse_markdown.rb +40 -8
  34. data/reverse_markdown.gemspec +3 -1
  35. data/spec/assets/lists.html +24 -0
  36. data/spec/assets/unknown_tags.html +9 -0
  37. data/spec/components/anchors_spec.rb +5 -5
  38. data/spec/components/basic_spec.rb +5 -5
  39. data/spec/components/code_spec.rb +5 -5
  40. data/spec/components/escapables_spec.rb +3 -3
  41. data/spec/components/from_the_wild_spec.rb +5 -5
  42. data/spec/components/html_fragment_spec.rb +2 -2
  43. data/spec/components/lists_spec.rb +18 -7
  44. data/spec/components/paragraphs_spec.rb +2 -2
  45. data/spec/components/quotation_spec.rb +5 -5
  46. data/spec/components/tables_spec.rb +2 -2
  47. data/spec/components/unknown_tags_spec.rb +21 -0
  48. data/spec/html_to_markdown_to_html_spec.rb +1 -2
  49. data/spec/lib/reverse_markdown/cleaner_spec.rb +76 -0
  50. data/spec/lib/reverse_markdown/converters/blockquote_spec.rb +18 -0
  51. data/spec/lib/reverse_markdown/converters/br_spec.rb +9 -0
  52. data/spec/lib/reverse_markdown_spec.rb +37 -0
  53. data/spec/spec_helper.rb +9 -1
  54. metadata +83 -24
  55. data/License-MIT +0 -7
  56. data/lib/reverse_markdown/mapper.rb +0 -241
  57. data/spec/mapper_spec.rb +0 -63
  58. data/spec/reverse_markdown_spec.rb +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fb69e03d2dc1bfd473c2073a44a890d25a6c9a25
4
- data.tar.gz: 91a7b52f84751dcaf6246024aae160a702fb6fcf
3
+ metadata.gz: d29227386b5418e906da5a4cb42ce616a2d3872b
4
+ data.tar.gz: 0f433297212a99d783573daac3fd3723e7d9f6a0
5
5
  SHA512:
6
- metadata.gz: acd40208862365222a27f1f4430f6ce067e75b2235cd2d403ac7dc126b408352e934e31ac9380914b41a3fe03ce299fadecc1a78298c92a00e104812e7a5780a
7
- data.tar.gz: d1f17eb2540c99d07065f4d8f78bdadee8d2aa88650070fd59ce4d62d560ec27f0e8521d400f7d920e3be4e26346acc2ee5a24e508a9f33abe867b9fb264713e
6
+ metadata.gz: 23ff8eb3e7a76e197b5526fcdf6c14d899e1ec600f1b40046d5584e2c40d62a9f22734656b5843f38ec5fa53dcf3a31f7b9baa7c2962e993eb07e5d4486f3afa
7
+ data.tar.gz: 2e46ce50817a0e735329dd2e73a9d47943e284a7cfb440362c8f8b6b1cbbb4d9945a6c492bafe8bd34843b7987fe1556410d29d4f6b34ce1d7936c570759f5dc
data/.gitignore CHANGED
@@ -6,3 +6,4 @@
6
6
  Gemfile.lock
7
7
  pkg/*
8
8
  coverage/*
9
+ TODO
data/.travis.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  rvm:
2
- - 1.9.2
3
- - 1.9.3
4
2
  - 2.0.0
3
+ - 2.1.0
4
+ - 2.1.1
5
5
 
6
6
  script: "bundle exec rake spec"
7
7
 
@@ -9,4 +9,3 @@ notifications:
9
9
  disabled: false
10
10
  recipients:
11
11
  - xijo@gmx.de
12
- - code@harlantwood.net
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (C) 2014 Johannes Opper <xijo@gmx.de>
5
+
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
data/README.md CHANGED
@@ -1,69 +1,108 @@
1
1
  # Summary
2
2
 
3
- Transform existing html into markdown in a simple way, for example if you want to import existings tags into your markdown based application.
3
+ Transform html into markdown. Useful for example if you want to import html into your markdown based application.
4
4
 
5
- [![Build Status](https://secure.travis-ci.org/xijo/reverse_markdown.png?branch=master)](https://travis-ci.org/xijo/reverse_markdown) [![Gem Version](https://badge.fury.io/rb/reverse_markdown.png)](http://badge.fury.io/rb/reverse_markdown)
5
+ [![Build Status](https://secure.travis-ci.org/xijo/reverse_markdown.png?branch=master)](https://travis-ci.org/xijo/reverse_markdown) [![Gem Version](https://badge.fury.io/rb/reverse_markdown.png)](http://badge.fury.io/rb/reverse_markdown) [![Code Climate](https://codeclimate.com/github/xijo/reverse_markdown.png)](https://codeclimate.com/github/xijo/reverse_markdown) [![Code Climate](https://codeclimate.com/github/xijo/reverse_markdown/coverage.png)](https://codeclimate.com/github/xijo/reverse_markdown)
6
6
 
7
- # Requirements
7
+ ## Migrate to 0.5.0
8
8
 
9
- Depends on [Nokogiri](http://nokogiri.org/).
9
+ There were some breaking changes, please make sure you don't miss them:
10
10
 
11
- # Installation
11
+ 1. Only ruby versions 2.0.0 or a above are supported
12
+ 2. There is no `Mapper` class any more. Just use `ReverseMarkdown.convert(input, options)`
13
+ 3. Config option `github_style_code_blocks` changed its name to `github_flavored`
12
14
 
13
- Install the gem:
15
+ Please open an issue and let me know about it if you have any trouble with the new version.
14
16
 
15
- [sudo] gem install reverse_markdown
17
+ ## Requirements
16
18
 
17
- If you want to use it in Rails context, add it to your Gemfile:
19
+ 1. [Nokogiri](http://nokogiri.org/)
20
+ 2. Ruby 2.0.0 or higher
21
+
22
+ ## Installation
23
+
24
+ Install the gem
25
+
26
+ ```sh
27
+ [sudo] gem install reverse_markdown
28
+ ```
29
+
30
+ or add it to your Gemfile
18
31
 
19
32
  ```ruby
20
33
  gem 'reverse_markdown'
21
34
  ```
22
35
 
23
- # Synopsis
36
+ ## Features
24
37
 
25
- Given you have html content as string or Nokogiri document or element just pass it over to the module like this:
38
+ - Supports all the established html tags like `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `p`, `em`, `strong`, `i`, `b`, `blockquote`, `code`, `img`, `a`, `hr`, `li`, `ol`, `ul`, `table`, `tr`, `th`, `td`, `br`
39
+ - Module based - if you miss a tag, just add it
40
+ - Can deal with nested lists
41
+ - Inline and block code is supported
42
+ - Supports blockquote
26
43
 
27
- ```ruby
28
- ReverseMarkdown.parse content
29
- ````
30
44
 
31
- However, the old syntax is still supported:
45
+ # Usage
46
+
47
+ ## Ruby
48
+
49
+ You can convert html content as string or Nokogiri document:
32
50
 
33
51
  ```ruby
34
- ReverseMarkdown.parse_element content
35
- ReverseMarkdown.parse_string content
52
+ input = '<strong>feelings</strong>'
53
+ result = ReverseMarkdown.convert input
54
+ result.inspect # " **feelings** "
36
55
  ````
37
56
 
38
- You can also convert html files to markdown from the command line:
57
+ ## Commandline
58
+
59
+ It's also possible to convert html files to markdown using the binary:
39
60
 
40
61
  ```sh
41
- $ reverse_markdown file.html > file.markdown
42
- $ cat file.html | reverse_markdown > file.markdown
62
+ $ reverse_markdown file.html > file.md
63
+ $ cat file.html | reverse_markdown > file.md
43
64
  ````
44
65
 
45
- Additionally there is a support for github-like multiline code which is indented with "`":
66
+ ## Configuration
67
+
68
+ The following options are available:
69
+
70
+ - `ignore_unknown_tags` (default `true`) - bypass unknown tags instead of raising an `ReverseMarkdown::UnknownTagError`
71
+ - `github_flavored` (default `false`) - use [github flavored markdown](https://help.github.com/articles/github-flavored-markdown) (yet only code blocks are supported)
72
+
73
+ ### As options
74
+
75
+ Just pass your chosen configuration options in after the input
46
76
 
47
77
  ```ruby
48
- ReverseMarkdown.parse_string(input, github_style_code_blocks: true)
49
- ````
78
+ ReverseMarkdown.convert(input, ignore_unknown_tags: false, github_flavored: true)
79
+ ```
80
+
81
+ ### Preconfigure
50
82
 
51
- # Tag support
83
+ Or configure it block style on a initializer level
52
84
 
53
- Only basic html tags are supported right now. However, it should not be to difficult to add some. Feel free to contribute or notify me about missing stuff.
85
+ ```ruby
86
+ ReverseMarkdown.config do |config|
87
+ config.ignore_unknown_tags = false
88
+ config.github_flavored = true
89
+ end
90
+ ```
54
91
 
55
- - supported tags: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `p`, `em`, `strong`, `i`, `b`, `blockquote`, `code`, `img`, `a`, `hr`, `li`, `ol`, `ul`, `table`, `tr`, `th`, `td`
56
- - nested lists
57
- - inline and block code
58
92
 
59
- # See as well
93
+ # Related stuff
60
94
 
61
- - [wmd-editor](http://wmd-editor.com) - Markdown flavored text editor
95
+ - [html_massage](https://github.com/harlantwood/html_massage) - A gem by Harlan T. Wood to convert regular sites into markdown using reverse_markdown
96
+ - [word-to-markdown](https://github.com/benbalter/word-to-markdown) - Convert word docs into markdown while using reverse_markdown, by Ben Balter
62
97
  - [markdown syntax](http://daringfireball.net/projects/markdown) - The markdown syntax specification
63
- - [html_massage](https://rubygems.org/gems/html_massage) - A gem by Harlan T. Wood to convert regular sites into markdown
98
+ - [github flavored markdown](https://help.github.com/articles/github-flavored-markdown) - Githubs extension to markdown
99
+ - [wmd-editor](http://wmd-editor.com) - Markdown flavored text editor
100
+
64
101
 
65
102
  # Thanks
66
103
 
67
104
  ..to Ben Woosley for his improvements to the first version.
68
105
 
69
106
  ..to Harlan T. Wood for his help with the newer versions.
107
+
108
+ ..and all contributors
data/bin/reverse_markdown CHANGED
@@ -2,4 +2,4 @@
2
2
  # Usage: reverse_markdown [FILE]...
3
3
  # Usage: cat FILE | reverse_markdown
4
4
  require 'reverse_markdown'
5
- puts ReverseMarkdown.parse(ARGF.read)
5
+ puts ReverseMarkdown.convert(ARGF.read)
@@ -0,0 +1,66 @@
1
+ module ReverseMarkdown
2
+ class Cleaner
3
+
4
+ def tidy(string)
5
+ clean_tag_borders(remove_leading_newlines(remove_newlines(remove_inner_whitespaces(string))))
6
+ end
7
+
8
+ def remove_newlines(string)
9
+ string.gsub(/\n{3,}/, "\n\n")
10
+ end
11
+
12
+ def remove_leading_newlines(string)
13
+ string.gsub /\A\n\n?/, ''
14
+ end
15
+
16
+ def remove_inner_whitespaces(string)
17
+ string.each_line.inject("") do |memo, line|
18
+ memo + preserve_border_whitespaces(line) do
19
+ line.strip.gsub(/[ \t]{2,}/, ' ')
20
+ end
21
+ end
22
+ end
23
+
24
+ # Find non-asterisk content that is enclosed by two or
25
+ # more asterisks. Ensure that only one whitespace occur
26
+ # in the border area.
27
+ # Same for underscores and brackets.
28
+ def clean_tag_borders(string)
29
+ result = string.gsub /\s?\*{2,}.*?\*{2,}\s?/ do |match|
30
+ preserve_border_whitespaces(match, default_border: ' ') do
31
+ match.strip.sub('** ', '**').sub(' **', '**')
32
+ end
33
+ end
34
+
35
+ result = result.gsub /\s?\_{2,}.*?\_{2,}\s?/ do |match|
36
+ preserve_border_whitespaces(match, default_border: ' ') do
37
+ match.strip.sub('__ ', '__').sub(' __', '__')
38
+ end
39
+ end
40
+
41
+ result.gsub /\s?\[.*?\]\s?/ do |match|
42
+ preserve_border_whitespaces(match) do
43
+ match.strip.sub('[ ', '[').sub(' ]', ']')
44
+ end
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def preserve_border_whitespaces(string, default_border: '', &block)
51
+ string_start = present_or_default(string[/\A\s*/], default_border)
52
+ string_end = present_or_default(string[/\s*\Z/], default_border)
53
+ result = yield
54
+ string_start + result + string_end
55
+ end
56
+
57
+ def present_or_default(string, default)
58
+ if string.nil? || string.empty?
59
+ default
60
+ else
61
+ string
62
+ end
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,20 @@
1
+ module ReverseMarkdown
2
+ class Config
3
+ attr_accessor :ignore_unknown_tags, :github_flavored
4
+
5
+ def initialize
6
+ reset
7
+ end
8
+
9
+ def apply(options = {})
10
+ options.each do |method, value|
11
+ __send__(:"#{method}=", value)
12
+ end
13
+ end
14
+
15
+ def reset
16
+ @ignore_unknown_tags = true
17
+ @github_flavored = false
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class A < Base
4
+ def convert(node)
5
+ name = treat_children(node)
6
+ href = node['href']
7
+ title = extract_title(node)
8
+
9
+ if href.to_s.start_with?('#') || href.to_s.empty? || name.empty?
10
+ name
11
+ else
12
+ " [#{name}](#{href}#{title})"
13
+ end
14
+ end
15
+ end
16
+
17
+ register :a, A.new
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Base
4
+ def treat_children(node)
5
+ node.children.inject('') do |memo, child|
6
+ memo << treat(child)
7
+ end
8
+ end
9
+
10
+ def treat(node)
11
+ ReverseMarkdown::Converters.lookup(node.name).convert(node)
12
+ end
13
+
14
+ def escape_keychars(string)
15
+ string.gsub(/[\*\_]/, '*' => '\*', '_' => '\_')
16
+ end
17
+
18
+ def extract_title(node)
19
+ title = escape_keychars(node['title'].to_s)
20
+ title.empty? ? '' : %[ "#{title}"]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,13 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Blockquote < Base
4
+ def convert(node)
5
+ content = treat_children(node).strip
6
+ content = ReverseMarkdown.cleaner.remove_newlines(content)
7
+ '> ' << content.lines.join('> ')
8
+ end
9
+ end
10
+
11
+ register :blockquote, Blockquote.new
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Br < Base
4
+ def convert(node)
5
+ " \n"
6
+ end
7
+ end
8
+
9
+ register :br, Br.new
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Code < Base
4
+ def convert(node)
5
+ "`#{node.text}`"
6
+ end
7
+ end
8
+
9
+ register :code, Code.new
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Div < Base
4
+ def convert(node)
5
+ "\n" << treat_children(node) << "\n"
6
+ end
7
+ end
8
+
9
+ register :div, Div.new
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Dump < Base
4
+ def convert(node)
5
+ node.to_s
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Em < Base
4
+ def convert(node)
5
+ content = treat_children(node)
6
+ if content.strip.empty? || already_italic?(node)
7
+ content
8
+ else
9
+ "_#{content}_"
10
+ end
11
+ end
12
+
13
+ def already_italic?(node)
14
+ node.ancestors('italic').size > 0 || node.ancestors('em').size > 0
15
+ end
16
+ end
17
+
18
+ register :em, Em.new
19
+ register :i, Em.new
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class H < Base
4
+ def convert(node)
5
+ prefix = '#' * node.name[/\d/].to_i
6
+ ["\n", prefix, ' ', treat_children(node), "\n"].join
7
+ end
8
+ end
9
+
10
+ register :h1, H.new
11
+ register :h2, H.new
12
+ register :h3, H.new
13
+ register :h4, H.new
14
+ register :h5, H.new
15
+ register :h6, H.new
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Hr < Base
4
+ def convert(node)
5
+ "\n* * *\n"
6
+ end
7
+ end
8
+
9
+ register :hr, Hr.new
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Img < Base
4
+ def convert(node)
5
+ alt = node['alt']
6
+ src = node['src']
7
+ title = extract_title(node)
8
+ " ![#{alt}](#{src}#{title})"
9
+ end
10
+ end
11
+
12
+ register :img, Img.new
13
+ end
14
+ end
@@ -0,0 +1,28 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Li < Base
4
+ def convert(node)
5
+ content = treat_children(node)
6
+ indentation = indentation_for(node)
7
+ prefix = prefix_for(node)
8
+ "#{indentation}#{prefix}#{content}\n"
9
+ end
10
+
11
+ def prefix_for(node)
12
+ if node.parent.name == 'ol'
13
+ index = node.parent.xpath('li').index(node)
14
+ "#{index.to_i + 1}. "
15
+ else
16
+ '- '
17
+ end
18
+ end
19
+
20
+ def indentation_for(node)
21
+ length = node.ancestors('ol').size + node.ancestors('ul').size
22
+ ' ' * (length - 1)
23
+ end
24
+ end
25
+
26
+ register :li, Li.new
27
+ end
28
+ end
@@ -0,0 +1,12 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Ol < Base
4
+ def convert(node)
5
+ "\n" << treat_children(node)
6
+ end
7
+ end
8
+
9
+ register :ol, Ol.new
10
+ register :ul, Ol.new
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class P < Base
4
+ def convert(node)
5
+ "\n\n" << treat_children(node).strip << "\n\n"
6
+ end
7
+ end
8
+
9
+ register :p, P.new
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class PassThrough < Base
4
+ def convert(node)
5
+ treat_children(node)
6
+ end
7
+ end
8
+
9
+ register :document, PassThrough.new
10
+ register :html, PassThrough.new
11
+ register :body, PassThrough.new
12
+ register :span, PassThrough.new
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ require 'base64'
2
+
3
+ module ReverseMarkdown
4
+ module Converters
5
+ class Pre < Base
6
+ def convert(node)
7
+ if ReverseMarkdown.config.github_flavored
8
+ "```\n" << node.text.strip << "\n```\n"
9
+ else
10
+ "\n\n " << node.text.strip.lines.join(" ") << "\n\n"
11
+ end
12
+ end
13
+ end
14
+
15
+ register :pre, Pre.new
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Strong < Base
4
+ def convert(node)
5
+ content = treat_children(node)
6
+ if content.strip.empty? || already_strong?(node)
7
+ content
8
+ else
9
+ "**#{content}**"
10
+ end
11
+ end
12
+
13
+ def already_strong?(node)
14
+ node.ancestors('strong').size > 0 || node.ancestors('b').size > 0
15
+ end
16
+ end
17
+
18
+ register :strong, Strong.new
19
+ register :b, Strong.new
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Table < Base
4
+ def convert(node)
5
+ "\n\n" << treat_children(node) << "\n"
6
+ end
7
+ end
8
+
9
+ register :table, Table.new
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Td < Base
4
+ def convert(node)
5
+ content = treat_children(node)
6
+ " #{content} |"
7
+ end
8
+ end
9
+
10
+ register :td, Td.new
11
+ register :th, Td.new
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Text < Base
4
+ def convert(node, options = {})
5
+ if node.text.strip.empty?
6
+ treat_empty(node)
7
+ else
8
+ treat_text(node)
9
+ end
10
+ end
11
+
12
+ def treat_empty(node)
13
+ parent = node.parent.name.to_sym
14
+ if [:ol, :ul].include?(parent) # Otherwise the identation is broken
15
+ ''
16
+ elsif node.text == ' ' # Regular whitespace text node
17
+ ' '
18
+ else
19
+ ''
20
+ end
21
+ end
22
+
23
+ def treat_text(node)
24
+ escape_keychars node.text.tr("\n\t", '').squeeze(' ')
25
+ end
26
+ end
27
+
28
+ register :text, Text.new
29
+ end
30
+ end
@@ -0,0 +1,21 @@
1
+ module ReverseMarkdown
2
+ module Converters
3
+ class Tr < Base
4
+ def convert(node)
5
+ content = treat_children(node).rstrip
6
+ result = "|#{content}\n"
7
+ table_header_row?(node) ? result + underline_for(node) : result
8
+ end
9
+
10
+ def table_header_row?(node)
11
+ node.element_children.all? {|child| child.name.to_sym == :th}
12
+ end
13
+
14
+ def underline_for(node)
15
+ "| " + (['---'] * node.element_children.size).join(' | ') + " |\n"
16
+ end
17
+ end
18
+
19
+ register :tr, Tr.new
20
+ end
21
+ end