article_json 0.2.1 → 0.3.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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/README.md +34 -2
  4. data/lib/article_json/article.rb +50 -10
  5. data/lib/article_json/configuration.rb +6 -27
  6. data/lib/article_json/elements/paragraph.rb +10 -0
  7. data/lib/article_json/elements/text.rb +8 -0
  8. data/lib/article_json/export/amp/elements/embed.rb +4 -1
  9. data/lib/article_json/export/common/elements/base.rb +84 -0
  10. data/lib/article_json/export/common/html/elements/base.rb +2 -70
  11. data/lib/article_json/export/common/html/elements/embed.rb +5 -2
  12. data/lib/article_json/export/common/html/elements/image.rb +3 -1
  13. data/lib/article_json/export/common/html/elements/quote.rb +16 -2
  14. data/lib/article_json/export/facebook_instant_article/elements/base.rb +30 -0
  15. data/lib/article_json/export/facebook_instant_article/elements/embed.rb +44 -0
  16. data/lib/article_json/export/facebook_instant_article/elements/heading.rb +11 -0
  17. data/lib/article_json/export/facebook_instant_article/elements/image.rb +11 -0
  18. data/lib/article_json/export/facebook_instant_article/elements/list.rb +11 -0
  19. data/lib/article_json/export/facebook_instant_article/elements/paragraph.rb +11 -0
  20. data/lib/article_json/export/facebook_instant_article/elements/quote.rb +30 -0
  21. data/lib/article_json/export/facebook_instant_article/elements/text.rb +11 -0
  22. data/lib/article_json/export/facebook_instant_article/elements/text_box.rb +40 -0
  23. data/lib/article_json/export/facebook_instant_article/exporter.rb +17 -0
  24. data/lib/article_json/export/plain_text/elements/base.rb +53 -0
  25. data/lib/article_json/export/plain_text/elements/embed.rb +16 -0
  26. data/lib/article_json/export/plain_text/elements/heading.rb +27 -0
  27. data/lib/article_json/export/plain_text/elements/image.rb +16 -0
  28. data/lib/article_json/export/plain_text/elements/list.rb +50 -0
  29. data/lib/article_json/export/plain_text/elements/paragraph.rb +33 -0
  30. data/lib/article_json/export/plain_text/elements/quote.rb +35 -0
  31. data/lib/article_json/export/plain_text/elements/text.rb +16 -0
  32. data/lib/article_json/export/plain_text/elements/text_box.rb +16 -0
  33. data/lib/article_json/export/plain_text/exporter.rb +23 -0
  34. data/lib/article_json/import/google_doc/html/shared/caption.rb +4 -3
  35. data/lib/article_json/utils/additional_element_placer.rb +69 -42
  36. data/lib/article_json/version.rb +1 -1
  37. data/lib/article_json.rb +24 -0
  38. metadata +23 -2
@@ -0,0 +1,30 @@
1
+ module ArticleJSON
2
+ module Export
3
+ module FacebookInstantArticle
4
+ module Elements
5
+ class Quote < Base
6
+ include ArticleJSON::Export::Common::HTML::Elements::Quote
7
+
8
+ private
9
+
10
+ # @return [Hash]
11
+ def node_opts
12
+ {}
13
+ end
14
+
15
+ # HTML tag for the wrapping node
16
+ # @return [Symbol]
17
+ def quote_tag
18
+ :aside
19
+ end
20
+
21
+ # HTML tag for the node containing the caption
22
+ # @return [Symbol]
23
+ def caption_tag
24
+ :cite
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,11 @@
1
+ module ArticleJSON
2
+ module Export
3
+ module FacebookInstantArticle
4
+ module Elements
5
+ class Text < Base
6
+ include ArticleJSON::Export::Common::HTML::Elements::Text
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,40 @@
1
+ module ArticleJSON
2
+ module Export
3
+ module FacebookInstantArticle
4
+ module Elements
5
+ class TextBox < Base
6
+ include ArticleJSON::Export::Common::HTML::Elements::TextBox
7
+
8
+ # Generate a `<div>` node containing all text box elements and
9
+ # surrounded by an ASCII-art line to the top and bottom
10
+ # @return [Nokogiri::XML::NodeSet]
11
+ def export
12
+ create_element(:div, class: 'text-box') do |div|
13
+ div.add_child(ascii_art_line_node)
14
+ @element.content.each do |child_element|
15
+ div.add_child(base_class.new(child_element).export)
16
+ end
17
+ div.add_child(ascii_art_line_node)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ # Returns a paragraph with the `ascii_art_line_text_element`. This
24
+ # gets inserted above and below the text box content
25
+ # @return [Nokogiri::XML::NodeSet]
26
+ def ascii_art_line_node
27
+ create_element(:p) { |p| p.add_child ascii_art_line_text_element }
28
+ end
29
+
30
+ # Returns the delimiter of text boxes. Overwrite this method to have a
31
+ # custom text box delimiter
32
+ # @return [String]
33
+ def ascii_art_line_text_element
34
+ '────────'
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,17 @@
1
+ module ArticleJSON
2
+ module Export
3
+ module FacebookInstantArticle
4
+ class Exporter
5
+ include ArticleJSON::Export::Common::HTML::Exporter
6
+
7
+ class << self
8
+ # Return the module namespace this class is nested in
9
+ # @return [Module]
10
+ def namespace
11
+ ArticleJSON::Export::FacebookInstantArticle
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,53 @@
1
+ module ArticleJSON
2
+ module Export
3
+ module PlainText
4
+ module Elements
5
+ class Base
6
+ include ArticleJSON::Export::Common::Elements::Base
7
+
8
+ # Export the given element. Dynamically looks up the right
9
+ # export-element-class, instantiates it and then calls the `#export`
10
+ # method.
11
+ # Defaults to an empty string, e.g. if no exporter is specified for
12
+ # the given type.
13
+ # @return [String]
14
+ def export
15
+ super || ''
16
+ end
17
+
18
+ class << self
19
+ # Return the module namespace this class and its subclasses are
20
+ # nested in
21
+ # @return [Module]
22
+ def namespace
23
+ ArticleJSON::Export::PlainText::Elements
24
+ end
25
+
26
+ private
27
+
28
+ # The format this exporter is returning. This is used to determine
29
+ # which custom element exporters should be applied from the
30
+ # configuration.
31
+ # @return [Symbol]
32
+ def export_format
33
+ :plain_text
34
+ end
35
+
36
+ def default_exporter_mapping
37
+ {
38
+ text: namespace::Text,
39
+ paragraph: namespace::Paragraph,
40
+ heading: namespace::Heading,
41
+ list: namespace::List,
42
+ quote: namespace::Quote,
43
+ image: nil,
44
+ embed: nil,
45
+ text_box: nil,
46
+ }
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,16 @@
1
+ module ArticleJSON
2
+ module Export
3
+ module PlainText
4
+ module Elements
5
+ class Embed < Base
6
+ # Embedded elements are being skipped when rendering plain text.
7
+ # Therefore, return an empty string.
8
+ # @return [String]
9
+ def export
10
+ ''
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ module ArticleJSON
2
+ module Export
3
+ module PlainText
4
+ module Elements
5
+ class Heading < Base
6
+ # Headline separated by newlines
7
+ # @return [String]
8
+ def export
9
+ "#{leading_newlines}#{@element.content}\n\n"
10
+ end
11
+
12
+ private
13
+
14
+ # String with dynamic number of newlines, depending on heading level.
15
+ # @return [String]
16
+ def leading_newlines
17
+ case @element.level
18
+ when 1 then "\n\n\n"
19
+ when 2 then "\n\n"
20
+ else "\n"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+ module ArticleJSON
2
+ module Export
3
+ module PlainText
4
+ module Elements
5
+ class Image < Base
6
+ # Images are being skipped when rendering plain text. Therefore,
7
+ # return an empty string.
8
+ # @return [String]
9
+ def export
10
+ ''
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,50 @@
1
+ module ArticleJSON
2
+ module Export
3
+ module PlainText
4
+ module Elements
5
+ class List < Base
6
+ # List of strings, one per line. If the list type is "ordered" then
7
+ # each line is preceded with a number, otherwise a dash. Newlines
8
+ # within a list item are indented accordingly.
9
+ # @return [String]
10
+ def export
11
+ "#{list}\n"
12
+ end
13
+
14
+ private
15
+
16
+ # Plain-text list of items using the right prefix
17
+ # @return [String]
18
+ def list
19
+ @element
20
+ .content
21
+ &.each_with_index
22
+ &.map do |content, index|
23
+ "#{prefix(index)} #{paragraph_exporter.new(content).export}"
24
+ .gsub(/\n(?!$)/, newline_with_indention)
25
+ end&.join || ''
26
+ end
27
+
28
+ # Prefix used for every list item
29
+ # @param [String] index
30
+ def prefix(index)
31
+ @element.list_type == :ordered ? "#{index + 1}." : '-'
32
+ end
33
+
34
+ # Newline followed by the right amount of spaces to align with the
35
+ # indentation from the prefix
36
+ # @return [String]
37
+ def newline_with_indention
38
+ "\n " + ' ' * prefix(0).length
39
+ end
40
+
41
+ # Get the exporter class for paragraph elements
42
+ # @return [ArticleJSON::Export::Common::HTML::Elements::Base]
43
+ def paragraph_exporter
44
+ self.class.exporter_by_type(:paragraph)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,33 @@
1
+ module ArticleJSON
2
+ module Export
3
+ module PlainText
4
+ module Elements
5
+ class Paragraph < Base
6
+ # Plain text from the paragraph. Any formatting is disregarded.
7
+ # Followed by a newline.
8
+ # @return [String]
9
+ def export
10
+ "#{text}\n"
11
+ end
12
+
13
+ private
14
+
15
+ # Plain text of the paragraph
16
+ # @return [String]
17
+ def text
18
+ @element
19
+ .content
20
+ &.map { |text_element| text_exporter.new(text_element).export }
21
+ &.join
22
+ end
23
+
24
+ # Get the exporter class for text elements
25
+ # @return [ArticleJSON::Export::PlainText::Elements::Base]
26
+ def text_exporter
27
+ self.class.exporter_by_type(:text)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,35 @@
1
+ module ArticleJSON
2
+ module Export
3
+ module PlainText
4
+ module Elements
5
+ class Quote < Base
6
+ # Quotes are just rendered with a preceding blank line. If a caption
7
+ # is present, it is rendered below the quote indented with two dashes.
8
+ # @return [String]
9
+ def export
10
+ "\n#{quote_text}\n"
11
+ end
12
+
13
+ private
14
+
15
+ # Plain text representation of the entire quote
16
+ # @return [String]
17
+ def quote_text
18
+ extract_text(@element.content).tap do |text|
19
+ if @element.caption&.any?
20
+ text << " --#{extract_text(@element.caption)}\n"
21
+ end
22
+ end
23
+ end
24
+
25
+ # Extract plain text from given element
26
+ # @param [ArticleJSON::Elements::Base] elements
27
+ # @return [String]
28
+ def extract_text(elements)
29
+ elements.map { |text| base_class.new(text).export }.join
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,16 @@
1
+ module ArticleJSON
2
+ module Export
3
+ module PlainText
4
+ module Elements
5
+ class Text < Base
6
+ # Text is just returned plain, no formatting or linking is taken into
7
+ # account.
8
+ # @return [String]
9
+ def export
10
+ @element.content
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module ArticleJSON
2
+ module Export
3
+ module PlainText
4
+ module Elements
5
+ class TextBox < Base
6
+ # Text boxes are being skipped when rendering plain text. Therefore,
7
+ # return an empty string.
8
+ # @return [String]
9
+ def export
10
+ ''
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ module ArticleJSON
2
+ module Export
3
+ module PlainText
4
+ class Exporter
5
+ # @param [Array[ArticleJSON::Elements::Base]] elements
6
+ def initialize(elements)
7
+ @elements = elements
8
+ end
9
+
10
+ # Generate a string with the plain text representation of all elements
11
+ # @return [String]
12
+ def text
13
+ @text ||=
14
+ @elements.map do |element|
15
+ ArticleJSON::Export::PlainText::Elements::Base
16
+ .build(element)
17
+ &.export
18
+ end.join.strip
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -7,7 +7,7 @@ module ArticleJSON
7
7
  # Parse the caption node
8
8
  # @return [Array[ArticleJSON::Elements::Text]]
9
9
  def caption
10
- return empty_caption if @caption_node.nil?
10
+ return [] if no_caption?
11
11
  ArticleJSON::Import::GoogleDoc::HTML::TextParser.extract(
12
12
  node: @caption_node,
13
13
  css_analyzer: @css_analyzer
@@ -16,8 +16,9 @@ module ArticleJSON
16
16
 
17
17
  private
18
18
 
19
- def empty_caption
20
- [ArticleJSON::Elements::Text.new(content: '&nbsp;')]
19
+ def no_caption?
20
+ @caption_node.nil? ||
21
+ @caption_node.inner_text.strip == '[no-caption]'
21
22
  end
22
23
  end
23
24
  end
@@ -2,64 +2,91 @@ module ArticleJSON
2
2
  module Utils
3
3
  # This class allows the user to place additional elements within an article.
4
4
  # It distributes elements over the whole article and ensures that an
5
- # additional element is only ever placed between two paragraph elements. If
6
- # there are not enough spaces, the remaining additional elements will be
7
- # appended to the existing article elements.
5
+ # additional element is only ever placed between two paragraph elements or
6
+ # after a paragraph and before the next headline. If there are not enough
7
+ # spaces, the remaining additional elements will be appended to the existing
8
+ # article elements.
8
9
  class AdditionalElementPlacer
9
- # @param [ArticleJSON::Article] article
10
+ # @param [Array[ArticleJSON::Article::Elements::Base]] elements
10
11
  # @param [Array[Object]] additional_elements
11
- def initialize(article, additional_elements)
12
- @elements = article.elements.dup
12
+ def initialize(elements, additional_elements)
13
+ @elements = elements.dup
13
14
  @additional_elements = additional_elements
14
15
  end
15
16
 
16
17
  # Distribute additional elements evenly throughout the article elements
18
+ #
19
+ # Outline of the algorithm:
20
+ # 1. It calculates every how many characters (only considering paragraphs)
21
+ # an additional element should be inserted, given the number of
22
+ # additional elements provided
23
+ # 2. It then iterates over the existing elements within the article,
24
+ # inserting them into the resulting, merged article
25
+ # 3. As soon as it has passed the right amount characters, it checks if
26
+ # the current position is eligible for inserting an additional element
27
+ # (the previous element needs to be a paragraph and the following needs
28
+ # to be either a paragraph or a headline)
29
+ # a) If so, it inserts the additional element and recalculates in how
30
+ # many characters the next element should be inserted, based on the
31
+ # remaining number of characters and remaining additional elements
32
+ # b) If not, it keeps iterating over the article until it finds an
33
+ # eligible position and only then inserts the additional element
34
+ # and recalculates the number of characters until the next
35
+ # insertion
36
+ # 4. If there are still additional elements remaining which couldn't be
37
+ # inserted (due to not finding enough eligible positions), they are
38
+ # appended to the end of the article
39
+ #
17
40
  # @return [Array[ArticleJSON::Elements::Base|Object]]
18
41
  def merge_elements
19
- indexes = indexes_for_additional_elements
20
-
21
- if indexes.count < @additional_elements.count
22
- @elements.push(*@additional_elements[indexes.count..-1])
23
- end
24
-
25
- indexes
26
- .reverse
27
- .zip(@additional_elements[0...indexes.count].reverse)
28
- .each { |index, element| @elements.insert(index, element) }
29
-
42
+ remaining_elements = @additional_elements.dup
43
+ next_in = insert_next_element_in(0, remaining_elements)
44
+ characters_passed = 0
30
45
  @elements
46
+ .each_cons(2)
47
+ .each_with_object([]) do |(element, next_element), result|
48
+ result << element
49
+ characters_passed += element.length if element.respond_to?(:length)
50
+ next_in -= element.length if element.respond_to?(:length)
51
+ if insert_here?(next_in, element, next_element)
52
+ result << remaining_elements.shift
53
+ next_in = insert_next_element_in(characters_passed,
54
+ remaining_elements)
55
+ end
56
+ end
57
+ .push(@elements.last, # add last element
58
+ *remaining_elements) # followed by remaining ads
31
59
  end
32
60
 
33
61
  private
34
62
 
35
- # Find indexes within article elements where there is a paragraph on the
36
- # current and on the next node
37
- # @return [Array[Integer]]
38
- def indexes_between_paragraphs
39
- @elements
40
- .each_cons(2) # iterate over elements in consecutive sets of 2
41
- .with_index
42
- .each_with_object([]) do |((current, following), index), possibilities|
43
- if current.type == :paragraph && following.type == :paragraph
44
- possibilities << index + 1
45
- end
46
- end
63
+ # Calculate in how many characters the next additional element should be
64
+ # inserted
65
+ # @param [Integer] characters_passed
66
+ # @param [Array] left_elements
67
+ # @return [Integer]
68
+ def insert_next_element_in(characters_passed, left_elements)
69
+ (total_length - characters_passed) / (left_elements.size + 1)
47
70
  end
48
71
 
49
- # Return evenly spread indexes of positions to insert a given number of
50
- # additional elements
51
- # @return [Array[Integer]]
52
- def indexes_for_additional_elements
53
- indexes = indexes_between_paragraphs
54
- insert_every = indexes.count / @additional_elements.count
55
-
56
- # in case there are more elements to add than available positions:
57
- insert_every = 1 if insert_every == 0
72
+ # Return the total length of the given elements
73
+ # @return [Integer]
74
+ def total_length
75
+ @total_length ||= @elements.reduce(0) do |sum, element|
76
+ sum + (element.respond_to?(:length) ? element.length : 0)
77
+ end
78
+ end
58
79
 
59
- indexes
60
- .reject
61
- .with_index { |_, index| (index + 1) % insert_every != 0 }
62
- .take(@additional_elements.count)
80
+ # Check if the given position is eligible for inserting an additional
81
+ # element
82
+ # @param [Integer] next_in
83
+ # @param [ArticleJSON::Elements::Base] element
84
+ # @param [ArticleJSON::Elements::Base] next_element
85
+ # @return [Boolean]
86
+ def insert_here?(next_in, element, next_element)
87
+ next_in <= 0 &&
88
+ element.type == :paragraph &&
89
+ %i(paragraph heading).include?(next_element.type)
63
90
  end
64
91
  end
65
92
  end
@@ -1,3 +1,3 @@
1
1
  module ArticleJSON
2
- VERSION = '0.2.1'
2
+ VERSION = '0.3.0'
3
3
  end
data/lib/article_json.rb CHANGED
@@ -39,6 +39,19 @@ require_relative 'article_json/import/google_doc/html/embedded_slideshare_parser
39
39
  require_relative 'article_json/import/google_doc/html/embedded_tweet_parser'
40
40
  require_relative 'article_json/import/google_doc/html/parser'
41
41
 
42
+ require_relative 'article_json/export/common/elements/base'
43
+
44
+ require_relative 'article_json/export/plain_text/elements/base'
45
+ require_relative 'article_json/export/plain_text/elements/text'
46
+ require_relative 'article_json/export/plain_text/elements/heading'
47
+ require_relative 'article_json/export/plain_text/elements/paragraph'
48
+ require_relative 'article_json/export/plain_text/elements/list'
49
+ require_relative 'article_json/export/plain_text/elements/image'
50
+ require_relative 'article_json/export/plain_text/elements/text_box'
51
+ require_relative 'article_json/export/plain_text/elements/quote'
52
+ require_relative 'article_json/export/plain_text/elements/embed'
53
+ require_relative 'article_json/export/plain_text/exporter'
54
+
42
55
  require_relative 'article_json/export/common/html/elements/shared/caption'
43
56
  require_relative 'article_json/export/common/html/elements/shared/float'
44
57
  require_relative 'article_json/export/common/html/elements/base'
@@ -75,4 +88,15 @@ require_relative 'article_json/export/amp/elements/embed'
75
88
  require_relative 'article_json/export/amp/custom_element_library_resolver'
76
89
  require_relative 'article_json/export/amp/exporter'
77
90
 
91
+ require_relative 'article_json/export/facebook_instant_article/elements/base'
92
+ require_relative 'article_json/export/facebook_instant_article/elements/text'
93
+ require_relative 'article_json/export/facebook_instant_article/elements/paragraph'
94
+ require_relative 'article_json/export/facebook_instant_article/elements/list'
95
+ require_relative 'article_json/export/facebook_instant_article/elements/heading'
96
+ require_relative 'article_json/export/facebook_instant_article/elements/quote'
97
+ require_relative 'article_json/export/facebook_instant_article/elements/text_box'
98
+ require_relative 'article_json/export/facebook_instant_article/elements/image'
99
+ require_relative 'article_json/export/facebook_instant_article/elements/embed'
100
+ require_relative 'article_json/export/facebook_instant_article/exporter'
101
+
78
102
  require_relative 'article_json/article'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: article_json
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Sager
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-11-08 00:00:00.000000000 Z
13
+ date: 2017-11-21 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: nokogiri
@@ -138,6 +138,7 @@ files:
138
138
  - lib/article_json/export/amp/elements/text.rb
139
139
  - lib/article_json/export/amp/elements/text_box.rb
140
140
  - lib/article_json/export/amp/exporter.rb
141
+ - lib/article_json/export/common/elements/base.rb
141
142
  - lib/article_json/export/common/html/elements/base.rb
142
143
  - lib/article_json/export/common/html/elements/embed.rb
143
144
  - lib/article_json/export/common/html/elements/heading.rb
@@ -150,6 +151,16 @@ files:
150
151
  - lib/article_json/export/common/html/elements/text.rb
151
152
  - lib/article_json/export/common/html/elements/text_box.rb
152
153
  - lib/article_json/export/common/html/exporter.rb
154
+ - lib/article_json/export/facebook_instant_article/elements/base.rb
155
+ - lib/article_json/export/facebook_instant_article/elements/embed.rb
156
+ - lib/article_json/export/facebook_instant_article/elements/heading.rb
157
+ - lib/article_json/export/facebook_instant_article/elements/image.rb
158
+ - lib/article_json/export/facebook_instant_article/elements/list.rb
159
+ - lib/article_json/export/facebook_instant_article/elements/paragraph.rb
160
+ - lib/article_json/export/facebook_instant_article/elements/quote.rb
161
+ - lib/article_json/export/facebook_instant_article/elements/text.rb
162
+ - lib/article_json/export/facebook_instant_article/elements/text_box.rb
163
+ - lib/article_json/export/facebook_instant_article/exporter.rb
153
164
  - lib/article_json/export/html/elements/base.rb
154
165
  - lib/article_json/export/html/elements/embed.rb
155
166
  - lib/article_json/export/html/elements/heading.rb
@@ -160,6 +171,16 @@ files:
160
171
  - lib/article_json/export/html/elements/text.rb
161
172
  - lib/article_json/export/html/elements/text_box.rb
162
173
  - lib/article_json/export/html/exporter.rb
174
+ - lib/article_json/export/plain_text/elements/base.rb
175
+ - lib/article_json/export/plain_text/elements/embed.rb
176
+ - lib/article_json/export/plain_text/elements/heading.rb
177
+ - lib/article_json/export/plain_text/elements/image.rb
178
+ - lib/article_json/export/plain_text/elements/list.rb
179
+ - lib/article_json/export/plain_text/elements/paragraph.rb
180
+ - lib/article_json/export/plain_text/elements/quote.rb
181
+ - lib/article_json/export/plain_text/elements/text.rb
182
+ - lib/article_json/export/plain_text/elements/text_box.rb
183
+ - lib/article_json/export/plain_text/exporter.rb
163
184
  - lib/article_json/import/google_doc/html/css_analyzer.rb
164
185
  - lib/article_json/import/google_doc/html/embedded_facebook_video_parser.rb
165
186
  - lib/article_json/import/google_doc/html/embedded_parser.rb