├── .gitignore
├── Gemfile
├── lib
├── kramdown-prismic
│ └── version.rb
├── kramdown-prismic.rb
└── kramdown
│ ├── parser
│ └── prismic.rb
│ └── converter
│ └── prismic.rb
├── kramdown1.gemfile
├── kramdown2.gemfile
├── bin
├── html2prismic
├── markdown2prismic
└── prismic2markdown
├── Rakefile
├── Gemfile.lock
├── .github
└── workflows
│ └── ci.yml
├── kramdown-prismic.gemspec
├── LICENSE
├── CHANGELOG.md
├── README.md
└── test
├── parser_test.rb
└── converter_test.rb
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | /.bundle
3 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source 'https://rubygems.org'
4 |
5 | gemspec
6 |
--------------------------------------------------------------------------------
/lib/kramdown-prismic/version.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module KramdownPrismic
4 | VERSION = '0.3.10'
5 | end
6 |
--------------------------------------------------------------------------------
/kramdown1.gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source 'https://rubygems.org'
4 |
5 | gemspec
6 | gem 'kramdown', '~> 1.0'
7 |
--------------------------------------------------------------------------------
/kramdown2.gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source 'https://rubygems.org'
4 |
5 | gemspec
6 | gem 'kramdown', '~> 2.0'
7 |
--------------------------------------------------------------------------------
/bin/html2prismic:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | require 'kramdown-prismic'
4 | require 'json'
5 |
6 | print Kramdown::Document.new(ARGV[0], input: :html).to_prismic.to_json.to_s
7 |
--------------------------------------------------------------------------------
/bin/markdown2prismic:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | require 'kramdown-prismic'
4 | require 'json'
5 |
6 | print Kramdown::Document.new(ARGV[0], input: :markdown).to_prismic.to_json.to_s
7 |
--------------------------------------------------------------------------------
/lib/kramdown-prismic.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'kramdown'
4 |
5 | require 'kramdown/parser/prismic'
6 | require 'kramdown/converter/prismic'
7 | require 'kramdown-prismic/version'
8 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'rake/testtask'
4 |
5 | Rake::TestTask.new do |t|
6 | t.libs << 'test'
7 | t.test_files = FileList['test/*_test.rb']
8 | t.verbose = true
9 | end
10 |
--------------------------------------------------------------------------------
/bin/prismic2markdown:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | require 'kramdown-prismic'
4 | require 'json'
5 |
6 | source = JSON.parse(ARGV[0], symbolize_names: true)
7 |
8 | print Kramdown::Document.new(source, input: :prismic).to_kramdown
9 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | PATH
2 | remote: .
3 | specs:
4 | kramdown-prismic (0.3.10)
5 | kramdown (>= 1, < 3)
6 |
7 | GEM
8 | remote: https://rubygems.org/
9 | specs:
10 | kramdown (2.4.0)
11 | rexml
12 | minitest (5.16.3)
13 | rake (13.0.6)
14 | rexml (3.2.5)
15 |
16 | PLATFORMS
17 | ruby
18 |
19 | DEPENDENCIES
20 | kramdown-prismic!
21 | minitest (~> 5.0)
22 | rake (~> 13.0)
23 |
24 | BUNDLED WITH
25 | 2.1.4
26 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on: [push, pull_request]
4 | jobs:
5 | test-kramdown2:
6 | strategy:
7 | fail-fast: false
8 | matrix:
9 | ruby: [2.6, 2.7, "3.0", "3.1", "3.2"]
10 | gemfile: [ kramdown2 ]
11 | env:
12 | BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | - uses: ruby/setup-ruby@v1
17 | with:
18 | ruby-version: ${{ matrix.ruby }}
19 | bundler-cache: true
20 | - run: bundle exec rake test
21 |
22 | test-kramdown1:
23 | strategy:
24 | fail-fast: false
25 | matrix:
26 | ruby: [2.6, 2.7]
27 | gemfile: [ kramdown1 ]
28 | env:
29 | BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile
30 | runs-on: ubuntu-latest
31 | steps:
32 | - uses: actions/checkout@v4
33 | - uses: ruby/setup-ruby@v1
34 | with:
35 | ruby-version: ${{ matrix.ruby }}
36 | bundler-cache: true
37 | - run: bundle exec rake test
38 |
--------------------------------------------------------------------------------
/kramdown-prismic.gemspec:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require File.expand_path('lib/kramdown-prismic/version', __dir__)
4 |
5 | Gem::Specification.new do |s|
6 | s.name = 'kramdown-prismic'
7 | s.version = KramdownPrismic::VERSION
8 | s.summary = 'A Kramdown converter to convert documents into prismic rich text format and the other way around.'
9 | s.description = 'A Kramdown converter to convert documents into prismic rich text format and the other way around.'
10 | s.authors = ['François de Metz']
11 | s.email = 'francois@2metz.fr'
12 |
13 | s.executables << 'markdown2prismic'
14 | s.executables << 'html2prismic'
15 | s.executables << 'prismic2markdown'
16 | s.files = `git ls-files`.split("\n")
17 | s.test_files = `git ls-files -- test/*`.split("\n")
18 |
19 | s.homepage = 'https://github.com/stormz/kramdown-prismic'
20 | s.license = 'MIT'
21 |
22 | s.add_dependency 'kramdown', '>= 1', '< 3'
23 | s.add_development_dependency 'minitest', '~> 5.0'
24 | s.add_development_dependency 'rake', '~> 13.0'
25 | end
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Stormz
4 | Copyright (c) 2021 François de Metz
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## Version 0.3.10
4 |
5 | - Fix the embed_url conversion
6 |
7 | ## Version 0.3.9
8 |
9 | - Convert the target attribute on links
10 |
11 | ## Version 0.3.8
12 |
13 | - Convert nested html_elements when converting from HTML.
14 |
15 | ## Version 0.3.7
16 |
17 | - Fix converting nested headers
18 |
19 | ## Version 0.3.6
20 |
21 | - Fix converting nested numbered list.
22 |
23 | ## Version 0.3.5
24 |
25 | - Convert `br` element when converting HTML documents.
26 |
27 | ## Version 0.3.4
28 |
29 | - Convert `strong` and `em` elements when converting HTML documents.
30 |
31 | ## Version 0.3.3
32 |
33 | - Renable converting xml comments
34 |
35 | ## Version 0.3.2
36 |
37 | - Parse ordered and unordered lists
38 | - Parse image with link
39 |
40 | ## Version 0.3.1
41 |
42 | - Add binaries `html2primisc`, `markdown2prismic` and `primisc2markdown`.
43 | - Add parsed embed support
44 |
45 | ## Version 0.3.0
46 |
47 | - Relax the kramdown dependency to allows the version 2.
48 | - XML elements support have been removed.
49 |
50 | ## Version 0.2.2
51 |
52 | - Convert links with only an image inside. See #1.
53 |
54 | ## Version 0.2.1
55 |
56 | - Parse embed elements
57 | - Convert inline code
58 |
59 | ## Version 0.2.0
60 |
61 | - Add parser to convert prismic to markdown
62 |
63 | ## Version 0.1.2
64 |
65 | - fix output with empty paragraph
66 |
67 | ## Version 0.1.1
68 |
69 | - Fix json of the image
70 |
71 | ## Version 0.1.0
72 |
73 | - Initial version
74 |
--------------------------------------------------------------------------------
/lib/kramdown/parser/prismic.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Kramdown
4 | module Parser
5 | class Prismic < Base
6 | def parse
7 | @root.options[:encoding] = 'UTF-8'
8 | @root.children = @source.reduce([]) do |memo, block|
9 | parse_element(block, memo)
10 | end
11 | end
12 |
13 | private
14 |
15 | def parse_element(block, memo)
16 | type = block[:type].gsub('-', '_')
17 | type = 'heading' if type.match(/heading/)
18 | if type == 'list_item'
19 | parse_list(:ul, block, memo)
20 | memo
21 | elsif type == 'o_list_item'
22 | parse_list(:ol, block, memo)
23 | memo
24 | else
25 | element = send("parse_#{type}", block)
26 | parse_spans(element, block)
27 | memo << element
28 | end
29 | end
30 |
31 | def parse_heading(block)
32 | level = block[:type].match(/heading([1-6])/)[1].to_i
33 | Element.new(:header, nil, nil, { level: level, raw_text: '' })
34 | end
35 |
36 | def parse_paragraph(_block)
37 | Element.new(:p)
38 | end
39 |
40 | def parse_image(block)
41 | p = Element.new(:p)
42 | img = Element.new(:img, nil, { 'src' => block[:data][:origin][:url], 'alt' => block[:data][:alt] })
43 | if block[:data][:linkTo]
44 | a = Element.new(:a, nil, { 'href' => block[:data][:linkTo][:url] })
45 | a.children << img
46 | p.children << a
47 | else
48 | p.children << img
49 | end
50 | p
51 | end
52 |
53 | def parse_preformatted(_block)
54 | Element.new(:blockquote)
55 | end
56 |
57 | def parse_list(type, block, memo)
58 | list = memo.last
59 | unless list && list.type == type
60 | list = Element.new(type)
61 | memo << list
62 | end
63 | li = Element.new(:li, nil, nil)
64 | list.children << li
65 | p = Element.new(:p, nil, nil, transparent: true)
66 | li.children << p
67 | parse_spans(p, block)
68 | end
69 |
70 | def parse_embed(block)
71 | Element.new(:html_element, 'iframe', { src: block[:data][:embed_url] })
72 | end
73 |
74 | def parse_spans(element, block)
75 | stack = []
76 |
77 | (block[:content][:text].size + 1).times do |index|
78 | starting_spans = find_starting_spans_for(block, index)
79 | ending_spans = find_ending_spans_for(block, index)
80 |
81 | ending_spans.each do |_ending_span|
82 | el = stack.pop
83 | if stack.empty?
84 | element.children << el
85 | else
86 | stack[-1].children << el
87 | end
88 | end
89 | starting_spans.each do |starting_span|
90 | stack << if starting_span[:type] == 'hyperlink'
91 | Element.new(:a, nil, { 'href' => starting_span[:data][:url] })
92 | else
93 | Element.new(starting_span[:type].to_sym)
94 | end
95 | end
96 |
97 | char = block[:content][:text][index]
98 | next if char.nil?
99 |
100 | current_text = if stack.empty?
101 | element.children.last
102 | else
103 | stack[-1].children.last
104 | end
105 | if current_text.nil? || current_text.type != :text
106 | current_text = Element.new(:text, '')
107 | if stack.empty?
108 | element.children << current_text
109 | else
110 | stack[-1].children << current_text
111 | end
112 | end
113 | current_text.value += char
114 | end
115 | end
116 |
117 | def find_starting_spans_for(block, index)
118 | block[:content][:spans].find_all do |span|
119 | span[:start] == index
120 | end.sort_by do |span|
121 | -span[:end]
122 | end
123 | end
124 |
125 | def find_ending_spans_for(block, index)
126 | block[:content][:spans].find_all do |span|
127 | span[:end] == index
128 | end
129 | end
130 | end
131 | end
132 | end
133 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Kramdown Prismic  [](https://rubygems.org/gems/kramdown-prismic)
2 |
3 | A [Kramdown][] parser and converter to convert documents into [prismic][] rich text format and the other way around.
4 |
5 | A useful usage is to convert markdown documents to prismic for [import purpose][prismic-import]. Then you can even convert prismic format back to markdown.
6 |
7 | [Learn more how to import markdown document to Prismic](https://2metz.fr/blog/import-markdown-into-prismic/).
8 |
9 | ## Status
10 |
11 | The converter part (kramdown to prismic) is working and fairly complete. See *Difference between markdown and rich text* below to know more about limitations.
12 |
13 | The parser part is quite new and not feature complete.
14 |
15 | ## Install
16 |
17 | ```ruby
18 | gem 'kramdown-prismic', '~> 0.1'
19 | ```
20 |
21 | ## Usage
22 |
23 | ### With executables
24 |
25 | *markdown2prismic*:
26 |
27 | markdown2prismic $'# My Title\n\nHello world'
28 |
29 | *html2prismic*:
30 |
31 | html2prismic '
My Title Hello world
'
32 |
33 | *prismic2markdown*:
34 |
35 | prismic2markdown '[{"type":"heading1","content":{"text":"My Title","spans":[]}},{"type":"paragraph","content":{"text":"Test","spans":[]}}]'
36 |
37 | ### As a library
38 |
39 | **Convert kramdown documents to Prismic**
40 |
41 | ```ruby
42 | require 'kramdown-prismic'
43 |
44 | kramdown = '# Hello world'
45 | Kramdown::Document.new(kramdown).to_prismic
46 | ```
47 |
48 | **Convert markdown documents to Prismic**
49 |
50 | ```ruby
51 | require 'kramdown-prismic'
52 |
53 | markdown = '# Hello world'
54 | Kramdown::Document.new(markdown, input: :markdown).to_prismic
55 | ```
56 |
57 | **Convert HTML documents to Prismic**
58 |
59 | ```ruby
60 | require 'kramdown-prismic'
61 |
62 | html = 'Hello world '
63 | Kramdown::Document.new(html, input: :html).to_prismic
64 | ```
65 |
66 | **Convert Prismic to markdown**
67 |
68 | ```ruby
69 | require 'kramdown-prismic'
70 | prismic = [
71 | {
72 | type: "heading1",
73 | content: {
74 | text: "This is the document title",
75 | spans: []
76 | }
77 | }
78 | ]
79 | Kramdown::Document.new(prismic, input: :prismic).to_kramdown
80 | ```
81 |
82 | You can also convert to or from others formats supported by Kramdown. See [kramdown documentation](https://kramdown.gettalong.org/documentation.html).
83 |
84 | ### Lookup for warnings
85 |
86 | If there is some elements that cannot be converted (see the status table), a warning will be emitted.
87 |
88 | For instance, html elements in the markdown is not supported:
89 |
90 | ```ruby
91 | require 'kramdown-prismic'
92 |
93 | markdown = 'Hello world '
94 | result = Kramdown::Document.new(markdown, input: :markdown)
95 | result.to_prismic
96 | p result.warnings
97 | ```
98 |
99 | ### Difference between markdown and rich text
100 |
101 | Some elements cannot be converted, due to some Prismic limitations. The table below explain the difference and limitations of the current converter:
102 |
103 | | Markdown | Prismic |
104 | |------------------|----------------------------|
105 | | blockquote | converted to preformatted |
106 | | hr | nothing |
107 | | img | moved to the top level |
108 | | nested list | moved to the top level |
109 | | entity | converted to unicode |
110 | | typographic_sym | converted to unicode |
111 | | smart_quote | converted to unicode |
112 | | dl | not supported |
113 | | dt | not supported |
114 | | dd | not supported |
115 | | table | not supported |
116 | | thead | not supported |
117 | | tobdy | not supported |
118 | | tfoot | not supported |
119 | | tr | not supported |
120 | | td | not supported |
121 | | math | not supported |
122 | | footnote | not supported |
123 | | abbreviation | not supported |
124 | | html_element | not supported |
125 | | xml_comment | not supported |
126 | | xml_pi | not supported |
127 | | comment | not supported |
128 | | raw | not supported |
129 |
130 | ## Develop
131 |
132 | Install dependencies:
133 |
134 | bundle install
135 |
136 | Run tests:
137 |
138 | bundle exec rake test
139 |
140 | ## License
141 |
142 | MIT
143 |
144 | [Kramdown]: https://kramdown.gettalong.org/
145 | [prismic]: https://prismic.io/
146 | [prismic-import]: https://prismic.io/docs/core-concepts/how-to-import-content
147 |
--------------------------------------------------------------------------------
/test/parser_test.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'minitest/autorun'
4 | require 'kramdown-prismic'
5 |
6 | class KramdownPrismicParserTest < Minitest::Test
7 | 6.times do |heading|
8 | define_method "test_parse_heading_#{heading}" do
9 | prismic = [
10 | {
11 | type: "heading#{heading + 1}",
12 | content: {
13 | text: 'This is the document title',
14 | spans: []
15 | }
16 | }
17 | ]
18 | expected = "#{'#' * (heading + 1)} This is the document title\n\n"
19 | doc = Kramdown::Document.new(prismic, input: :prismic)
20 | assert_equal expected, doc.to_kramdown
21 | end
22 | end
23 |
24 | def test_parse_paragraph
25 | prismic = [
26 | {
27 | type: 'paragraph',
28 | content: {
29 | text: 'This is a paragraph',
30 | spans: []
31 | }
32 | }
33 | ]
34 | expected = "This is a paragraph\n\n"
35 | doc = Kramdown::Document.new(prismic, input: :prismic)
36 | assert_equal expected, doc.to_kramdown
37 | end
38 |
39 | def test_parse_paragraph_with_spans
40 | prismic = [
41 | {
42 | type: 'paragraph',
43 | content: {
44 | text: 'This is a paragraph',
45 | spans: [
46 | {
47 | type: 'em',
48 | start: 0,
49 | end: 4
50 | }
51 | ]
52 | }
53 | }
54 | ]
55 | expected = "*This* is a paragraph\n\n"
56 | doc = Kramdown::Document.new(prismic, input: :prismic)
57 | assert_equal expected, doc.to_kramdown
58 | end
59 |
60 | def test_parse_paragraph_with_multiple_spans
61 | prismic = [
62 | {
63 | type: 'paragraph',
64 | content: {
65 | text: 'This is a paragraph',
66 | spans: [
67 | {
68 | type: 'em',
69 | start: 0,
70 | end: 4
71 | },
72 | {
73 | type: 'strong',
74 | start: 5,
75 | end: 7
76 | }
77 | ]
78 | }
79 | }
80 | ]
81 | expected = "*This* **is** a paragraph\n\n"
82 | doc = Kramdown::Document.new(prismic, input: :prismic)
83 | assert_equal expected, doc.to_kramdown
84 | end
85 |
86 | def test_parse_paragraph_with_link
87 | prismic = [
88 | {
89 | type: 'paragraph',
90 | content: {
91 | text: 'This is a paragraph',
92 | spans: [
93 | {
94 | type: 'hyperlink',
95 | start: 0,
96 | end: 19,
97 | data: {
98 | url: 'https://prismic.io'
99 | }
100 | }
101 | ]
102 | }
103 | }
104 | ]
105 | expected = "[This is a paragraph][1]\n\n\n\n[1]: https://prismic.io\n"
106 | doc = Kramdown::Document.new(prismic, input: :prismic)
107 | assert_equal expected, doc.to_kramdown
108 | end
109 |
110 | def test_parse_paragraph_with_nested_spans
111 | prismic = [
112 | {
113 | type: 'paragraph',
114 | content: {
115 | text: 'This is a paragraph',
116 | spans: [
117 | {
118 | type: 'em',
119 | start: 0,
120 | end: 4
121 | },
122 | {
123 | type: 'hyperlink',
124 | start: 0,
125 | end: 19,
126 | data: {
127 | url: 'https://prismic.io'
128 | }
129 | }
130 | ]
131 | }
132 | }
133 | ]
134 | expected = "[*This* is a paragraph][1]\n\n\n\n[1]: https://prismic.io\n"
135 | doc = Kramdown::Document.new(prismic, input: :prismic)
136 | assert_equal expected, doc.to_kramdown
137 | end
138 |
139 | def test_parse_list_item
140 | prismic = [
141 | {
142 | type: 'list-item',
143 | content: {
144 | text: 'Hello',
145 | spans: []
146 | }
147 | },
148 | {
149 | type: 'list-item',
150 | content: {
151 | text: 'World',
152 | spans: []
153 | }
154 | }
155 | ]
156 | expected = "* Hello\n* World\n\n"
157 | doc = Kramdown::Document.new(prismic, input: :prismic)
158 | assert_equal expected, doc.to_kramdown
159 | end
160 |
161 | def test_parse_list_item_and_spans
162 | prismic = [
163 | {
164 | type: 'list-item',
165 | content: {
166 | text: 'Hello',
167 | spans: [
168 | {
169 | type: 'em',
170 | start: 0,
171 | end: 5
172 | }
173 | ]
174 | }
175 | },
176 | {
177 | type: 'list-item',
178 | content: {
179 | text: 'World',
180 | spans: []
181 | }
182 | }
183 | ]
184 | expected = "* *Hello*\n* World\n\n"
185 | doc = Kramdown::Document.new(prismic, input: :prismic)
186 | assert_equal expected, doc.to_kramdown
187 | end
188 |
189 | def test_parse_o_list_item
190 | prismic = [
191 | {
192 | type: 'o-list-item',
193 | content: {
194 | text: 'Hello',
195 | spans: []
196 | }
197 | },
198 | {
199 | type: 'o-list-item',
200 | content: {
201 | text: 'World',
202 | spans: []
203 | }
204 | }
205 | ]
206 | expected = "1. Hello\n2. World\n\n"
207 | doc = Kramdown::Document.new(prismic, input: :prismic)
208 | assert_equal expected, doc.to_kramdown
209 | end
210 |
211 | def test_parse_o_list_item_and_list_item
212 | prismic = [
213 | {
214 | type: 'o-list-item',
215 | content: {
216 | text: 'Hello',
217 | spans: []
218 | }
219 | },
220 | {
221 | type: 'o-list-item',
222 | content: {
223 | text: 'World',
224 | spans: []
225 | }
226 | },
227 | {
228 | type: 'list-item',
229 | content: {
230 | text: 'Test',
231 | spans: []
232 | }
233 | },
234 | {
235 | type: 'list-item',
236 | content: {
237 | text: 'roger',
238 | spans: []
239 | }
240 | }
241 | ]
242 | expected = "1. Hello\n2. World\n\n* Test\n* roger\n\n"
243 | doc = Kramdown::Document.new(prismic, input: :prismic)
244 | assert_equal expected, doc.to_kramdown
245 | end
246 |
247 | def test_parse_image
248 | prismic = [
249 | {
250 | type: 'image',
251 | content: {
252 | text: '',
253 | spans: []
254 | },
255 | data: {
256 | origin: {
257 | url: '/img.png'
258 | },
259 | alt: 'alt text'
260 | }
261 | }
262 | ]
263 | expected = "\n\n"
264 | doc = Kramdown::Document.new(prismic, input: :prismic)
265 | assert_equal expected, doc.to_kramdown
266 | end
267 |
268 | def test_parse_img_with_link
269 | prismic = [
270 | {
271 | type: 'image',
272 | content: {
273 | text: '',
274 | spans: []
275 | },
276 | data: {
277 | origin: {
278 | url: '/img.png'
279 | },
280 | alt: 'alt text',
281 | linkTo: {
282 | url: 'https://example.net/'
283 | }
284 | }
285 | }
286 | ]
287 | expected = "[][1]\n\n\n\n[1]: https://example.net/\n"
288 | doc = Kramdown::Document.new(prismic, input: :prismic)
289 | assert_equal expected, doc.to_kramdown
290 | end
291 |
292 | def test_parse_preformatted
293 | prismic = [
294 | {
295 | type: 'preformatted',
296 | content: {
297 | text: "This is a pre block\n",
298 | spans: []
299 | }
300 | }
301 | ]
302 | expected = "> This is a pre block \n\n"
303 | doc = Kramdown::Document.new(prismic, input: :prismic)
304 | assert_equal expected, doc.to_kramdown
305 | end
306 |
307 | def test_parse_embed
308 | prismic = [
309 | {
310 | type: 'embed',
311 | data: {
312 | type: 'video',
313 | embed_url: 'https://www.youtube.com/watch?v=y6y_4_b6RS8'
314 | },
315 | content: {
316 | text: '',
317 | spans: []
318 | }
319 | }
320 | ]
321 | expected = "VIDEO \n"
322 | doc = Kramdown::Document.new(prismic, input: :prismic)
323 | assert_equal expected, doc.to_kramdown
324 | end
325 | end
326 |
--------------------------------------------------------------------------------
/lib/kramdown/converter/prismic.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'kramdown/converter/base'
4 |
5 | module Kramdown
6 | module Converter
7 | class Prismic < Base
8 | def convert(root)
9 | cleanup_ast(root).map do |child|
10 | convert_element(child)
11 | end.compact.flatten
12 | end
13 |
14 | private
15 |
16 | def cleanup_ast(root)
17 | remove_blanks(root)
18 | root.children.map do |child|
19 | elements = []
20 | extract_non_nestable_elements(child, elements)
21 | [child, elements]
22 | end.flatten.compact
23 | end
24 |
25 | def remove_blanks(root)
26 | root.children = root.children.each_with_object([]) do |child, memo|
27 | unless child.type == :blank
28 | remove_blanks(child)
29 | memo << child
30 | end
31 | end
32 | end
33 |
34 | def extract_non_nestable_elements(child, elements)
35 | child.children = child.children.each_with_object([]) do |element, memo|
36 | if element.type == :a && element.children.size == 1 && element.children.first.type == :img
37 | elements << element
38 | elsif element.type == :img
39 | elements << element
40 | if child.children.size > 1
41 | warning('images inside content will be moved to the top level and may be rendered differently')
42 | end
43 | elsif [:ul, :ol].include?(element.type)
44 | warning('nested list moved to the top level')
45 | elements << element
46 | extract_non_nestable_elements(element, elements)
47 | elsif element.type == :header
48 | warning('header moved to the top level')
49 | elements << element
50 | extract_non_nestable_elements(element, elements)
51 | else
52 | memo << element
53 | extract_non_nestable_elements(element, elements)
54 | end
55 | end
56 | end
57 |
58 | def convert_element(element)
59 | send("convert_#{element.type}", element)
60 | end
61 |
62 | def convert_header(element)
63 | {
64 | type: "heading#{element.options[:level]}",
65 | content: extract_content(element)
66 | }
67 | end
68 |
69 | def convert_p(element)
70 | return nil if element.children.size.zero?
71 |
72 | {
73 | type: 'paragraph',
74 | content: extract_content(element)
75 | }
76 | end
77 |
78 | def convert_ol(element)
79 | convert_list(element, 'o-list-item')
80 | end
81 |
82 | def convert_ul(element)
83 | convert_list(element, 'list-item')
84 | end
85 |
86 | def convert_list(element, type)
87 | element.children.map do |child|
88 | convert_li(type, child)
89 | end
90 | end
91 |
92 | def convert_li(type, element)
93 | {
94 | type: type,
95 | content: extract_content(element)
96 | }
97 | end
98 |
99 | def convert_codeblock(element)
100 | {
101 | type: 'preformatted',
102 | content: {
103 | text: element.value,
104 | spans: []
105 | }
106 | }
107 | end
108 |
109 | def convert_blockquote(element)
110 | {
111 | type: 'preformatted',
112 | content: extract_content(element)
113 | }
114 | end
115 |
116 | def convert_hr(element); end
117 | def convert_br(element); end
118 |
119 | def convert_img(element)
120 | {
121 | type: 'image',
122 | content: {
123 | text: '',
124 | spans: []
125 | },
126 | data: {
127 | origin: {
128 | url: element.attr['src']
129 | },
130 | alt: element.attr['alt']
131 | }
132 | }
133 | end
134 |
135 | # This can only apply when an link with an image inside has been detected
136 | def convert_a(element)
137 | image = element.children.first
138 | {
139 | type: 'image',
140 | content: {
141 | text: '',
142 | spans: []
143 | },
144 | data: {
145 | origin: {
146 | url: image.attr['src']
147 | },
148 | alt: image.attr['alt'],
149 | linkTo: {
150 | url: element.attr['href']
151 | }
152 | }
153 | }
154 | end
155 |
156 | def convert_strong(element)
157 | convert_sub_html_element(element, 'strong')
158 | end
159 |
160 | def convert_em(element)
161 | convert_sub_html_element(element, 'em')
162 | end
163 |
164 | def convert_sub_html_element(element, type)
165 | content = extract_content(element)
166 | content[:spans].push({ type: type, start: 0, end: content[:text].size })
167 | {
168 | type: 'paragraph',
169 | content: content
170 | }
171 | end
172 |
173 | def convert_html_element(element)
174 | if element.value == 'iframe'
175 | {
176 | content: {
177 | spans: [],
178 | text: ''
179 | },
180 | type: 'embed',
181 | data: {
182 | embed_url: element.attr['src'],
183 | type: 'link'
184 | }
185 | }
186 | else
187 | warning('translating html elements is not supported')
188 | nil
189 | end
190 | end
191 |
192 | def convert_table(_element)
193 | warning('translating table is not supported')
194 | nil
195 | end
196 |
197 | def convert_dl(_element)
198 | warning('translating dl is not supported')
199 | nil
200 | end
201 |
202 | def convert_math(_element)
203 | warning('translating math is not supported')
204 | nil
205 | end
206 |
207 | def convert_comment(_element)
208 | warning('translating comment is not supported')
209 | nil
210 | end
211 |
212 | def convert_xml_comment(_element)
213 | warning('translating xml comment is not supported')
214 | nil
215 | end
216 |
217 | def convert_raw(_element)
218 | warning('translating raw is not supported')
219 | nil
220 | end
221 |
222 | def convert_text(element)
223 | {
224 | type: 'paragraph',
225 | content: {
226 | text: element.value,
227 | spans: []
228 | }
229 | }
230 | end
231 |
232 | def extract_content(element, memo = { text: '', spans: [] })
233 | element.children.each_with_object(memo) do |child, memo2|
234 | send("extract_span_#{child.type}", child, memo2)
235 | end
236 | end
237 |
238 | def insert_span(element, memo, span)
239 | span[:start] = memo[:text].size
240 | extract_content(element, memo)
241 | span[:end] = memo[:text].size
242 | memo[:spans] << span
243 | memo
244 | end
245 |
246 | def extract_span_text(element, memo)
247 | memo[:text] += element.value
248 | memo
249 | end
250 |
251 | def extract_span_a(element, memo)
252 | target = element.attr['target']
253 | insert_span(element, memo, {
254 | type: 'hyperlink',
255 | data: {
256 | url: element.attr['href'],
257 | **(target ? { target: target } : {}),
258 | }
259 | })
260 | end
261 |
262 | def extract_span_strong(element, memo)
263 | insert_span(element, memo, {
264 | type: 'strong'
265 | })
266 | end
267 |
268 | def extract_span_em(element, memo)
269 | insert_span(element, memo, {
270 | type: 'em'
271 | })
272 | end
273 |
274 | def extract_span_p(element, memo)
275 | extract_content(element, memo)
276 | end
277 |
278 | def extract_span_br(_element, memo)
279 | memo[:text] += "\n"
280 | end
281 |
282 | def extract_span_codespan(element, memo)
283 | warning('translating inline code is not supported')
284 | memo[:text] += element.value
285 | end
286 |
287 | def extract_span_html_element(element, memo)
288 | if respond_to?("extract_span_#{element.value}", true)
289 | send("extract_span_#{element.value}", element, memo)
290 | else
291 | warning("translating html element '#{element.value}' is not supported")
292 | end
293 | end
294 |
295 | def extract_span_footnote(_element, _memo)
296 | warning('translating footnote is not supported')
297 | end
298 |
299 | def extract_span_abbreviation(element, memo)
300 | warning('translating abbreviation is not supported')
301 | memo[:text] += element.value
302 | end
303 |
304 | def extract_span_xml_comment(element, memo)
305 | warning('translating xml comment is not supported')
306 | end
307 |
308 | TYPOGRAPHIC_SYMS = {
309 | mdash: [Utils::Entities.entity('mdash')],
310 | ndash: [Utils::Entities.entity('ndash')],
311 | hellip: [Utils::Entities.entity('hellip')],
312 | laquo_space: [Utils::Entities.entity('laquo'), Utils::Entities.entity('nbsp')],
313 | raquo_space: [Utils::Entities.entity('nbsp'), Utils::Entities.entity('raquo')],
314 | laquo: [Utils::Entities.entity('laquo')],
315 | raquo: [Utils::Entities.entity('raquo')]
316 | }.freeze
317 | def extract_span_typographic_sym(element, memo)
318 | value = TYPOGRAPHIC_SYMS[element.value].map(&:char).join('')
319 | memo[:text] += value
320 | end
321 |
322 | def extract_span_entity(element, memo)
323 | memo[:text] += element.value.char
324 | end
325 |
326 | def extract_span_smart_quote(element, memo)
327 | memo[:text] += Utils::Entities.entity(element.value.to_s).char
328 | end
329 | end
330 | end
331 | end
332 |
--------------------------------------------------------------------------------
/test/converter_test.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'minitest/autorun'
4 | require 'kramdown-prismic'
5 |
6 | class KramdownPrismicConverterTest < Minitest::Test
7 | 6.times do |heading|
8 | define_method "test_convert_heading_#{heading}" do
9 | expected = [
10 | {
11 | type: "heading#{heading + 1}",
12 | content: {
13 | text: 'This is the document title',
14 | spans: []
15 | }
16 | }
17 | ]
18 | markdown = "#{'#' * (heading + 1)} This is the document title"
19 | assert_equal expected, Kramdown::Document.new(markdown, input: :kramdown).to_prismic
20 | end
21 | end
22 |
23 | def test_convert_heading7
24 | expected = [
25 | {
26 | type: 'heading6',
27 | content: {
28 | text: '# This is the document title',
29 | spans: []
30 | }
31 | }
32 | ]
33 | markdown = '####### This is the document title'
34 | assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic
35 | end
36 |
37 | def test_convert_heading_with_spans
38 | expected = [
39 | {
40 | type: 'heading2',
41 | content: {
42 | text: 'This is a document title',
43 | spans: [
44 | {
45 | type: 'em',
46 | start: 0,
47 | end: 4
48 | }
49 | ]
50 | }
51 | }
52 | ]
53 | markdown = '## *This* is a document title'
54 | assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic
55 | end
56 |
57 | def test_convert_paragraph
58 | expected = [
59 | {
60 | type: 'paragraph',
61 | content: {
62 | text: 'This is a paragraph',
63 | spans: []
64 | }
65 | }
66 | ]
67 | markdown = 'This is a paragraph'
68 | assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic
69 | end
70 |
71 | def test_convert_paragraph_with_spans
72 | expected = [
73 | {
74 | type: 'paragraph',
75 | content: {
76 | text: 'This is a paragraph',
77 | spans: [
78 | {
79 | type: 'hyperlink',
80 | start: 0,
81 | end: 19,
82 | data: {
83 | url: 'https://prismic.io'
84 | }
85 | }
86 | ]
87 | }
88 | }
89 | ]
90 | markdown = '[This is a paragraph](https://prismic.io)'
91 | assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic
92 | end
93 |
94 | def test_convert_paragraph_with_strong
95 | expected = [
96 | {
97 | type: 'paragraph',
98 | content: {
99 | text: 'This is a paragraph',
100 | spans: [
101 | {
102 | type: 'strong',
103 | start: 0,
104 | end: 19
105 | }
106 | ]
107 | }
108 | }
109 | ]
110 | markdown = '**This is a paragraph**'
111 | assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic
112 | end
113 |
114 | def test_convert_paragraph_with_strong2
115 | expected = [
116 | {
117 | type: 'paragraph',
118 | content: {
119 | text: 'This is a paragraph',
120 | spans: [
121 | {
122 | type: 'strong',
123 | start: 0,
124 | end: 4
125 | }
126 | ]
127 | }
128 | }
129 | ]
130 | markdown = '**This** is a paragraph'
131 | assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic
132 | end
133 |
134 | def test_convert_html_strong
135 | expected = [
136 | {
137 | type: 'paragraph',
138 | content: {
139 | text: 'This is a paragraph',
140 | spans: [
141 | {
142 | type: 'strong',
143 | start: 0,
144 | end: 19
145 | }
146 | ]
147 | }
148 | }
149 | ]
150 | markdown = 'This is a paragraph '
151 | assert_equal expected, Kramdown::Document.new(markdown, input: :html).to_prismic
152 | end
153 |
154 | def test_convert_paragraph_with_em
155 | expected = [
156 | {
157 | type: 'paragraph',
158 | content: {
159 | text: 'This is a paragraph',
160 | spans: [
161 | {
162 | type: 'em',
163 | start: 0,
164 | end: 4
165 | }
166 | ]
167 | }
168 | }
169 | ]
170 | markdown = '*This* is a paragraph'
171 | assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic
172 | end
173 |
174 | def test_convert_html_em
175 | expected = [
176 | {
177 | type: 'paragraph',
178 | content: {
179 | text: 'This',
180 | spans: [
181 | {
182 | type: 'em',
183 | start: 0,
184 | end: 4
185 | }
186 | ]
187 | }
188 | }
189 | ]
190 | markdown = 'This '
191 | assert_equal expected, Kramdown::Document.new(markdown, input: :html).to_prismic
192 | end
193 |
194 | def test_convert_list_o
195 | expected = [
196 | {
197 | type: 'o-list-item',
198 | content: {
199 | text: 'This is a list item',
200 | spans: [
201 | {
202 | type: 'em',
203 | start: 0,
204 | end: 4
205 | }
206 | ]
207 | }
208 | },
209 | {
210 | type: 'o-list-item',
211 | content: {
212 | text: 'This is a second list item',
213 | spans: []
214 | }
215 | }
216 | ]
217 | markdown = "1. *This* is a list item\n2. This is a second list item"
218 | assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic
219 | end
220 |
221 | def test_convert_list_u
222 | expected = [
223 | {
224 | type: 'list-item',
225 | content: {
226 | text: 'This is a list item',
227 | spans: [
228 | {
229 | type: 'em',
230 | start: 0,
231 | end: 4
232 | }
233 | ]
234 | }
235 | },
236 | {
237 | type: 'list-item',
238 | content: {
239 | text: 'This is a second list item',
240 | spans: []
241 | }
242 | }
243 | ]
244 | markdown = "- *This* is a list item\n- This is a second list item"
245 | assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic
246 | end
247 |
248 | def test_convert_nested_ul
249 | expected = [
250 | {
251 | type: 'list-item',
252 | content: {
253 | text: "item1\n",
254 | spans: []
255 | }
256 | },
257 | {
258 | type: 'list-item',
259 | content: {
260 | text: 'item2',
261 | spans: []
262 | }
263 | }
264 | ]
265 | markdown = "- item1\n - item2"
266 | doc = Kramdown::Document.new(markdown, input: :markdown)
267 | assert_equal expected, doc.to_prismic
268 | assert_equal 1, doc.warnings.size
269 | end
270 |
271 | def test_convert_nested_ol
272 | expected = [
273 | {
274 | type: 'list-item',
275 | content: {
276 | text: "item1\n",
277 | spans: []
278 | }
279 | },
280 | {
281 | type: 'o-list-item',
282 | content: {
283 | text: 'item2',
284 | spans: []
285 | }
286 | }
287 | ]
288 | markdown = "- item1\n 1. item2"
289 | doc = Kramdown::Document.new(markdown, input: :markdown)
290 | assert_equal expected, doc.to_prismic
291 | assert_equal 1, doc.warnings.size
292 | end
293 |
294 | def test_convert_nested_nested_ul
295 | expected = [
296 | {
297 | type: 'list-item',
298 | content: {
299 | text: "item1\n",
300 | spans: []
301 | }
302 | },
303 | {
304 | type: 'list-item',
305 | content: {
306 | text: "item2\n",
307 | spans: []
308 | }
309 | },
310 | {
311 | type: 'list-item',
312 | content: {
313 | text: 'item3',
314 | spans: []
315 | }
316 | }
317 | ]
318 | markdown = "- item1\n - item2\n - item3"
319 | doc = Kramdown::Document.new(markdown, input: :markdown)
320 | assert_equal expected, doc.to_prismic
321 | assert_equal 2, doc.warnings.size
322 | end
323 |
324 | def test_convert_heading_in_list
325 | expected = [
326 | {
327 | type: 'list-item',
328 | content: {
329 | text: "",
330 | spans: []
331 | }
332 | },
333 | {
334 | type: 'heading4',
335 | content: {
336 | text: 'Title',
337 | spans: []
338 | }
339 | }
340 | ]
341 | html = ""
342 | doc = Kramdown::Document.new(html, input: :html)
343 | assert_equal expected, doc.to_prismic
344 | assert_equal 1, doc.warnings.size
345 | end
346 |
347 | def test_convert_preformatted
348 | expected = [
349 | {
350 | type: 'preformatted',
351 | content: {
352 | text: "This is a pre block\n",
353 | spans: []
354 | }
355 | }
356 | ]
357 | markdown = " This is a pre block\n"
358 | assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic
359 | end
360 |
361 | def test_convert_blockquote
362 | expected = [
363 | {
364 | type: 'preformatted',
365 | content: {
366 | text: 'This is a blockquote',
367 | spans: []
368 | }
369 | }
370 | ]
371 | markdown = "> This is a blockquote\n"
372 | assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic
373 | end
374 |
375 | def test_convert_empty
376 | expected = []
377 | markdown = ''
378 | assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic
379 | end
380 |
381 | def test_convert_span_blank
382 | expected = [
383 | {
384 | type: 'o-list-item',
385 | content: {
386 | text: 'Testtest',
387 | spans: []
388 | }
389 | }
390 | ]
391 | markdown = "\n1. Test\n\n test\n"
392 | assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic
393 | end
394 |
395 | def test_convert_hr
396 | expected = []
397 | markdown = '---'
398 | assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic
399 | end
400 |
401 | def test_convert_img
402 | expected = [
403 | {
404 | type: 'image',
405 | content: {
406 | text: '',
407 | spans: []
408 | },
409 | data: {
410 | origin: {
411 | url: '/img.png'
412 | },
413 | alt: 'alt text'
414 | }
415 | }
416 | ]
417 | markdown = ''
418 | doc = Kramdown::Document.new(markdown)
419 | assert_equal expected, doc.to_prismic
420 | assert_equal 0, doc.warnings.size
421 | end
422 |
423 | def test_convert_double_img
424 | expected = [
425 | {
426 | type: 'image',
427 | content: {
428 | text: '',
429 | spans: []
430 | },
431 | data: {
432 | origin: {
433 | url: '/img.png'
434 | },
435 | alt: ''
436 | }
437 | },
438 | {
439 | type: 'image',
440 | content: {
441 | text: '',
442 | spans: []
443 | },
444 | data: {
445 | origin: {
446 | url: '/img2.png'
447 | },
448 | alt: ''
449 | }
450 | }
451 | ]
452 | markdown = ''
453 | doc = Kramdown::Document.new(markdown)
454 | assert_equal expected, doc.to_prismic
455 | assert_equal 2, doc.warnings.size
456 | end
457 |
458 | def test_convert_img_with_link
459 | expected = [
460 | {
461 | type: 'image',
462 | content: {
463 | text: '',
464 | spans: []
465 | },
466 | data: {
467 | origin: {
468 | url: '/img.png'
469 | },
470 | alt: 'alt text',
471 | linkTo: {
472 | url: 'https://example.net/'
473 | }
474 | }
475 | }
476 | ]
477 | markdown = '[](https://example.net/)'
478 | doc = Kramdown::Document.new(markdown)
479 | assert_equal expected, doc.to_prismic
480 | assert_equal 0, doc.warnings.size
481 | end
482 |
483 | def test_convert_entity
484 | expected = [
485 | {
486 | type: 'paragraph',
487 | content: {
488 | text: "\u00a0",
489 | spans: []
490 | }
491 | }
492 | ]
493 | markdown = ' '
494 | assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic
495 | end
496 |
497 | [['mdash', ' ---', ' —'],
498 | ['ndash', ' --', ' –'],
499 | ['hellip', ' ...', ' …'],
500 | ['laquo', ' <<', ' «'],
501 | ['raquo', '>>', '»'],
502 | ['laquo_space', ' << T', ' « T'],
503 | ['raquo_space', ' >>', ' »']].each do |symbol|
504 | define_method "test_convert_typographic_symbols_#{symbol[0]}" do
505 | expected = [
506 | {
507 | type: 'paragraph',
508 | content: {
509 | text: "Hello#{symbol[2]}",
510 | spans: []
511 | }
512 | }
513 | ]
514 | markdown = "Hello#{symbol[1]}"
515 | assert_equal expected, Kramdown::Document.new(markdown, input: :kramdown).to_prismic
516 | end
517 | end
518 |
519 | def test_convert_smart_quote
520 | expected = [
521 | {
522 | type: 'paragraph',
523 | content: {
524 | text: "Test\u2019",
525 | spans: []
526 | }
527 | }
528 | ]
529 | markdown = "Test'"
530 | assert_equal expected, Kramdown::Document.new(markdown, input: :kramdown).to_prismic
531 | end
532 |
533 | def test_convert_inline_code
534 | expected = [
535 | {
536 | type: 'paragraph',
537 | content: {
538 | text: 'Hello code',
539 | spans: []
540 | }
541 | }
542 | ]
543 | markdown = 'Hello `code`'
544 | doc = Kramdown::Document.new(markdown)
545 | assert_equal expected, doc.to_prismic
546 | assert_equal 1, doc.warnings.size
547 | end
548 |
549 | def test_convert_br
550 | expected = [
551 | {
552 | type: 'paragraph',
553 | content: {
554 | text: "Test\n",
555 | spans: []
556 | }
557 | }
558 | ]
559 | html = 'Test
'
560 | assert_equal expected, Kramdown::Document.new(html, input: :html).to_prismic
561 | end
562 |
563 | def test_convert_br_in_root_element
564 | expected = [
565 | {
566 | type: 'paragraph',
567 | content: {
568 | text: "Test\n",
569 | spans: []
570 | }
571 | }
572 | ]
573 | html = 'Test
'
574 | assert_equal expected, Kramdown::Document.new(html, input: :html).to_prismic
575 | end
576 |
577 | def test_convert_html_with_no_tags
578 | expected_text = if Gem::Version.new(Kramdown::VERSION) >= Gem::Version.new("2.3.2")
579 | "Test "
580 | else
581 | "Test\n"
582 | end
583 | expected = [
584 | {
585 | type: 'paragraph',
586 | content: {
587 | text: expected_text,
588 | spans: []
589 | }
590 | }
591 | ]
592 | html = 'Test'
593 | assert_equal expected, Kramdown::Document.new(html, input: :html).to_prismic
594 | end
595 |
596 | def test_convert_iframe
597 | expected = [
598 | {
599 | type: 'embed',
600 | content: {
601 | text: '',
602 | spans: []
603 | },
604 | data: {
605 | embed_url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
606 | type: 'link'
607 | }
608 | }
609 | ]
610 | html = 'VIDEO '
611 | doc = Kramdown::Document.new(html, input: :markdown)
612 | assert_equal expected, doc.to_prismic
613 | end
614 |
615 | def test_convert_link
616 | expected = [
617 | {
618 | type: 'paragraph',
619 | content: {
620 | text: 'Test',
621 | spans: [{type: 'hyperlink', data: {url: 'http://example.net', target: '_blank'}, start: 0, end: 4}]
622 | }
623 | }
624 | ]
625 | html = 'Test '
626 | doc = Kramdown::Document.new(html, input: :markdown)
627 | assert_equal expected, doc.to_prismic
628 | end
629 |
630 | def test_convert_html
631 | expected = []
632 | html = '
'
633 | doc = Kramdown::Document.new(html, input: :markdown)
634 | assert_equal expected, doc.to_prismic
635 | assert_equal 1, doc.warnings.size
636 | end
637 |
638 | def test_convert_span_html_strong
639 | expected = [
640 | {
641 | type: 'paragraph',
642 | content: {
643 | text: 'This is a paragraph',
644 | spans: [
645 | {
646 | type: 'strong',
647 | start: 10,
648 | end: 20
649 | }
650 | ]
651 | }
652 | }
653 | ]
654 | html = 'This is a paragraph
'
655 | doc = Kramdown::Document.new(html, input: :html)
656 | assert_equal expected, doc.to_prismic
657 | assert_equal 0, doc.warnings.size
658 | end
659 |
660 | def test_convert_span_html_br
661 | expected = [
662 | {
663 | type: 'paragraph',
664 | content: {
665 | text: "\n",
666 | spans: []
667 | }
668 | }
669 | ]
670 | html = ' '
671 | doc = Kramdown::Document.new(html, input: :markdown)
672 | assert_equal expected, doc.to_prismic
673 | assert_equal 0, doc.warnings.size
674 | end
675 |
676 | def test_convert_span_html_unknown
677 | expected = [
678 | {
679 | type: 'paragraph',
680 | content: {
681 | text: 'This is a ',
682 | spans: []
683 | }
684 | }
685 | ]
686 | html = 'This is a detail
'
687 | doc = Kramdown::Document.new(html, input: :html)
688 | assert_equal expected, doc.to_prismic
689 | assert_equal 1, doc.warnings.size
690 | assert_equal "translating html element 'details' is not supported", doc.warnings.first
691 | end
692 |
693 | def test_convert_table
694 | expected = []
695 | markdown = '| First cell|Second cell|Third cell|'
696 | doc = Kramdown::Document.new(markdown, input: :kramdown)
697 | assert_equal expected, doc.to_prismic
698 | assert_equal 1, doc.warnings.size
699 | end
700 |
701 | def test_convert_definition
702 | expected = []
703 | markdown = "kramdown\n: A Markdown-superset converter"
704 | doc = Kramdown::Document.new(markdown, input: :kramdown)
705 | assert_equal expected, doc.to_prismic
706 | assert_equal 1, doc.warnings.size
707 | end
708 |
709 | def test_convert_math
710 | expected = []
711 | markdown = '$$ 5 + 5 $$'
712 | doc = Kramdown::Document.new(markdown, input: :kramdown)
713 | assert_equal expected, doc.to_prismic
714 | assert_equal 1, doc.warnings.size
715 | end
716 |
717 | def test_convert_footnote
718 | expected = [
719 | {
720 | type: 'paragraph',
721 | content: {
722 | text: 'test',
723 | spans: []
724 | }
725 | }
726 | ]
727 | markdown = "test[^1]\n\n[^1]: test"
728 | doc = Kramdown::Document.new(markdown, input: :kramdown)
729 | assert_equal expected, doc.to_prismic
730 | assert_equal 1, doc.warnings.size
731 | end
732 |
733 | def test_convert_abbreviation
734 | expected = [
735 | {
736 | type: 'paragraph',
737 | content: {
738 | text: 'HTML',
739 | spans: []
740 | }
741 | }
742 | ]
743 | markdown = "HTML\n\n*[HTML]: test"
744 | doc = Kramdown::Document.new(markdown, input: :kramdown)
745 | assert_equal expected, doc.to_prismic
746 | assert_equal 1, doc.warnings.size
747 | end
748 |
749 | def test_convert_xml_comment
750 | expected = []
751 | markdown = ""
752 | doc = Kramdown::Document.new(markdown, input: :kramdown)
753 | assert_equal expected, doc.to_prismic
754 | assert_equal 1, doc.warnings.size
755 | end
756 |
757 | def test_convert_span_xml_comment
758 | expected = [
759 | {
760 | type: 'paragraph',
761 | content: {
762 | text: 'test test',
763 | spans: []
764 | }
765 | }
766 | ]
767 | markdown = "test test"
768 | doc = Kramdown::Document.new(markdown, input: :kramdown)
769 | assert_equal expected, doc.to_prismic
770 | assert_equal 1, doc.warnings.size
771 | end
772 |
773 | def test_convert_comment
774 | expected = []
775 | markdown = "{::comment}\nComment\n{:/comment}"
776 | doc = Kramdown::Document.new(markdown, input: :kramdown)
777 | assert_equal expected, doc.to_prismic
778 | assert_equal 1, doc.warnings.size
779 | end
780 |
781 | def test_convert_raw
782 | expected = []
783 | markdown = "{::nomarkdown}\nComment\n{:/nomarkdown}"
784 | doc = Kramdown::Document.new(markdown, input: :kramdown)
785 | assert_equal expected, doc.to_prismic
786 | assert_equal 1, doc.warnings.size
787 | end
788 | end
789 |
--------------------------------------------------------------------------------