article_json 0.3.7 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/README.md +118 -67
  4. data/bin/article_json_export_amp.rb +15 -0
  5. data/bin/article_json_export_apple_news.rb +15 -0
  6. data/bin/article_json_export_facebook.rb +16 -0
  7. data/bin/article_json_export_html.rb +1 -0
  8. data/bin/article_json_export_plain_text.rb +15 -0
  9. data/bin/article_json_parse_google_doc.rb +1 -0
  10. data/bin/check_google_doc_export.rb +41 -0
  11. data/bin/update_oembed_request-stubs.sh +11 -0
  12. data/bin/update_reference_document.sh +16 -0
  13. data/lib/article_json/article.rb +22 -2
  14. data/lib/article_json/configuration.rb +2 -1
  15. data/lib/article_json/elements/base.rb +0 -1
  16. data/lib/article_json/elements/image.rb +7 -3
  17. data/lib/article_json/export/amp/elements/embed.rb +1 -1
  18. data/lib/article_json/export/apple_news/elements/base.rb +53 -0
  19. data/lib/article_json/export/apple_news/elements/embed.rb +130 -0
  20. data/lib/article_json/export/apple_news/elements/heading.rb +32 -0
  21. data/lib/article_json/export/apple_news/elements/image.rb +58 -0
  22. data/lib/article_json/export/apple_news/elements/list.rb +67 -0
  23. data/lib/article_json/export/apple_news/elements/paragraph.rb +36 -0
  24. data/lib/article_json/export/apple_news/elements/quote.rb +60 -0
  25. data/lib/article_json/export/apple_news/elements/text.rb +42 -0
  26. data/lib/article_json/export/apple_news/elements/text_box.rb +51 -0
  27. data/lib/article_json/export/apple_news/exporter.rb +37 -0
  28. data/lib/article_json/export/common/html/elements/image.rb +1 -1
  29. data/lib/article_json/import/google_doc/html/image_parser.rb +24 -3
  30. data/lib/article_json/import/google_doc/html/node_analyzer.rb +11 -1
  31. data/lib/article_json/import/google_doc/html/parser.rb +6 -1
  32. data/lib/article_json/utils/o_embed_resolver/facebook_video.rb +17 -1
  33. data/lib/article_json/utils/o_embed_resolver/youtube_video.rb +1 -1
  34. data/lib/article_json/version.rb +1 -1
  35. data/lib/article_json.rb +11 -0
  36. metadata +37 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2820900cbe5eeba0352a764674bf7dbc1a5a1d2353c0fe5fcacea19799891378
4
- data.tar.gz: 95c0cba7f4896556710fa621ea07576979b98ec62b7975e5ef330883f66b98b1
3
+ metadata.gz: 561ba1f1fff25cba3e32eea10bdff57757ab6776a688bc78f85ec4eafeb62b32
4
+ data.tar.gz: e72e2425f7008d24be098be9024a27f493c2f13c99577ec71d7dda953564bcef
5
5
  SHA512:
6
- metadata.gz: 0bd444a45513d39b0499188b7ade246cfde9e215df63b9652dc16435bde2570c51a4ed9cb5124c24a0848b63df3eacd3a2538bcb8ba5829b96b4afc7e5f93ff7
7
- data.tar.gz: 4effc300873b4203bbc4e9594cc49ae871275e3d5c0e92940b10fad380e7c06acd1b42b14b869d00f28385102bb2c7646eca0424f4e9ca4957c7796fa497aaa1
6
+ metadata.gz: 14e75d7a01ad409337b79b98075063807de0d18dd911980c7ef816668ddf4adc6f02211fb36ed54a530962bf0839628b217cfd6c849ff6153575c9e9274500b2
7
+ data.tar.gz: a2a1eac1de2d0d8b0379c1d1bbc85a7af99e33c44ebdc544d88de7983597be878e59c9bc90a2a1a4958b4dcb1ea26d4bc5817fb6944e04e02224d1af8fd52353
data/CHANGELOG.md CHANGED
@@ -1,4 +1,35 @@
1
1
  # Changelog
2
+ ## 0.4.0 - 2024/01/17
3
+ In this fourth release we **added support for Apple News**:
4
+ **New**:
5
+ Support for Apple News Format, specifically the following elements:
6
+ - text
7
+ - text boxes
8
+ - lists
9
+ - pull quotes
10
+ - image
11
+ - embed objects (posts from X etc.)
12
+ - image captions for images and embed objects
13
+ - video
14
+ Support for Ruby 3.2
15
+
16
+ **Removes**:
17
+ Support for Ruby 2.3
18
+
19
+ **Refactoring**:
20
+ - Rubocop autocorrections
21
+
22
+ **Fix:**
23
+ - Fix failing rspec tests
24
+
25
+
26
+ ## 0.3.8 - 2020/7/31
27
+ - **Improvements:**
28
+ - Add a script to update oembed stubs fixtures.
29
+ - Support for `alt` attribute in images.
30
+
31
+ - **Fix:** Fix a bug when using the `[image-link-to: ]` tag.
32
+
2
33
  ## 0.3.7 - 2019/8/21
3
34
  - **Fix:** Only use https for soundcloud oembed api
4
35
 
data/README.md CHANGED
@@ -1,10 +1,25 @@
1
1
  # article_json
2
- JSON Format for News Articles & Ruby Gem.
2
+ The `article_json` gem is a Ruby library designed to simplify the conversion and manipulation of structured articles in various formats, allowing easy importing, manipulation and export of content across different platforms and environments.
3
+
4
+ It takes an article from a Google Doc and creates a JSON version of it.
5
+
6
+ From there it can export the article:
7
+ - as HTML
8
+ - as AMP
9
+ - as Apple News Format (ANF)
10
+ - as Facebook Instant Article HTML
11
+ - as plain text
12
+ - as JSON
13
+
14
+ It also provides functionalities to parse content from Google Document HTML exports and initialize articles from JSON strings or already parsed JSON.
15
+
16
+ ---
3
17
 
4
18
  ## Status
5
19
  [![Gem Version](https://badge.fury.io/rb/article_json.svg)](https://badge.fury.io/rb/article_json)
6
- [![Build Status](https://travis-ci.org/Devex/article_json.svg)](https://travis-ci.org/Devex/article_json)
7
- [![Code Climate](https://codeclimate.com/github/Devex/article_json/badges/gpa.svg)](https://codeclimate.com/github/Devex/article_json)
20
+ [![Check Google Doc](https://github.com/Devex/article_json/workflows/Check%20Google%20Doc/badge.svg)](https://github.com/Devex/article_json/actions/workflows/check-google-doc.yml)
21
+ [![RSpec](https://github.com/Devex/article_json/workflows/rspec/badge.svg)](https://github.com/Devex/article_json/actions/workflows/rspec.yml)
22
+ [![Code Climate](https://codeclimate.com/github/Devex/article_json/badges/gpa.svg)](https://codeclimate.com/github/Devex/article_json?event=push)
8
23
  [![Coverage Status](https://coveralls.io/repos/github/Devex/article_json/badge.svg?branch=master)](https://coveralls.io/github/Devex/article_json?branch=master)
9
24
 
10
25
  ## Usage
@@ -32,6 +47,9 @@ puts article.to_amp
32
47
  # get javascript libraries needed for the AMP article
33
48
  puts article.amp_exporter.amp_libraries
34
49
 
50
+ # export article as Apple News Format (ANF)
51
+ puts article.to_apple_news
52
+
35
53
  # export article as Facebook Instant Article HTML
36
54
  puts article.to_facebook_instant_article
37
55
 
@@ -43,20 +61,47 @@ puts article.to_json
43
61
  ```
44
62
 
45
63
  ### CLI
46
- To load, parse and html-export the latest version of the reference document,
47
- run the following:
64
+ To load, parse and export the latest (amp/ apple news/ facebook/ html) version of the reference document, run the following:
48
65
 
49
- ```
66
+ ```bash
50
67
  $ export DOC_ID=1E4lncZE2jDkbE34eDyYQmXKA9O26BHUiwguz4S9qyE8
51
68
  $ ./bin/article_json_export_google_doc.rb $DOC_ID \
52
69
  | ./bin/article_json_parse_google_doc.rb \
53
70
  | ./bin/article_json_export_html.rb
71
+ ## OR
72
+ # | ./bin/article_json_export_amp.rb
73
+ # | ./bin/article_json_export_apple_news.rb
74
+ # | ./bin/article_json_export_facebook.rb
75
+ # | ./bin/article_json_export_plain_text.rb
76
+ ```
77
+
78
+ Alternatively, you can concatenate your command line commands, like so:
79
+ ```bash
80
+ $ ./bin/article_json_export_google_doc.rb $DOC_ID > test_ref_doc.html
81
+ $ cat test_ref_doc.html | bin/article_json_parse_google_doc.rb > \
82
+ test_ref_doc_parsed_apple.json
83
+ $ cat test_ref_doc_parsed_apple.json | bin/article_json_export_apple_news.rb > \
84
+ test_ref_doc_exported_apple.json
85
+ ```
86
+
87
+ You can also update _all_ the different exported versions of the reference document _(amp, apple_news, facebook, google_doc, html and plain_text)_ by running the following command:
88
+
89
+ ```
90
+ $ ./bin/update_reference_document.sh
91
+ ```
92
+
93
+ When running the tests, we use some fixtures to mock the responses for oembed requests, but these may change over time.
94
+
95
+ To update them, run:
96
+
97
+ ```
98
+ $ ./bin/update_oembed_request-stubs.sh
54
99
  ```
55
100
 
56
101
  ### Configuration
57
- There are some configuration options that allow a more tailored usage of the
58
- `article_json` gem. The following code snippet gives an example for every
59
- available setting:
102
+ Some configuration options allow a more tailored usage of the `article_json` gem.
103
+
104
+ The following code snippet gives an example for every available setting:
60
105
 
61
106
  ```ruby
62
107
  ArticleJSON.configure do |config|
@@ -69,48 +114,63 @@ ArticleJSON.configure do |config|
69
114
  :html,
70
115
  advertisement: ArticleJSON::Export::HTML::Elements::Advertisement
71
116
  )
72
-
117
+
73
118
  # You can also overwrite existing exporters:
74
119
  config.register_element_exporters(
75
120
  :html,
76
121
  image: ArticleJSON::Export::HTML::Elements::ScaledImage
77
122
  )
78
-
123
+
79
124
  # And you can define multiple custom exporters:
80
125
  config.register_element_exporters(
81
126
  :html,
82
127
  advertisement: ArticleJSON::Export::HTML::Elements::Advertisement,
83
128
  image: ArticleJSON::Export::HTML::Elements::ScaledImage
84
129
  )
85
-
86
- # It works the same way for custom AMP, FacebookInstantArticle, or
87
- # PlainText exporters:
130
+
131
+ # It works the same way for custom AMP, FacebookInstantArticle, or PlainText
132
+ # exporters:
88
133
  config.register_element_exporters(
89
134
  :amp, # Or change this for `:facebook_instant_article` or `:plain_text`
90
135
  image: ArticleJSON::Export::AMP::Elements::ScaledImage
91
- )
136
+ )
137
+ end
138
+ ```
139
+
140
+ ### Facebook Oembed
141
+ Facebook deprecated its public endpoints for embeddable Facebook content in 2020 (See https://developers.facebook.com/docs/plugins/oembed-legacy for more info).
142
+
143
+ You now need to use a Facebook token to access the new oembed endpoints. You can configure the gem to use this token so:
144
+
145
+ ``` ruby
146
+ ArticleJSON.configure do |config|
147
+ # 'token' being the combination of the app-id and the access token joined
148
+ # with the pipe symbol (`|`)
149
+ config.facebook_token = 'token'
92
150
  end
93
- ```
151
+ ```
152
+
153
+ Find more info about the access token [here](https://developers.facebook.com/docs/plugins/oembed#access-tokens).
94
154
 
95
155
  ## Format
96
- A full example of the format can be found in the test fixtures:
97
- [Parsed Reference Document](https://github.com/Devex/article_json/blob/master/spec/fixtures/reference_document_parsed.json)
156
+ A [full example of the format](https://github.com/Devex/article_json/blob/master/spec/fixtures/reference_document_parsed.json) can be found in the test fixtures.
98
157
 
99
158
  ## Import
100
159
  ### Google Document Parser
101
- This [Reference Document](https://docs.google.com/document/d/1E4lncZE2jDkbE34eDyYQmXKA9O26BHUiwguz4S9qyE8/edit?usp=sharing)
102
- lists contains all supported formatting along with some descriptions.
160
+ This [reference document](https://docs.google.com/document/d/1E4lncZE2jDkbE34eDyYQmXKA9O26BHUiwguz4S9qyE8/editusp=sharing) contains all the supported formatting along with some descriptions.
103
161
 
104
162
  ## Add custom elements
105
- Sometimes you might want to place additional elements into the article, like e.g. advertisements.
106
- `article_json` supports this via `article.place_additional_elements` which accepts an array of elements that you can define in your own code.
107
- Each element that is added this way will directly get placed in between paragraphs of the article.
108
- The method ensures that an additional element is never added before or after any node other than paragraphs (e.g. an image).
109
- The elements are added in the order you pass them into the method.
110
- If the article should not have enough spaces to place all the provided elements, they will be placed after the last element in the article.
111
-
112
- You can pass any type of element into this method.
113
- If the objects you pass in are instances of elements defined within this gem (e.g. `ArticleJSON::Elements::Image`), you won't have to do anything else to get them rendered.
163
+ Sometimes you might want to place additional elements into the article, like e.g. advertisements. `article_json` supports this via `article.place_additional_elements`, which accepts an array of elements that you can define in your code.
164
+
165
+ Each element that is added this way will directly get placed in between paragraphs of the article. The method ensures that an additional element is never added before or after any node other than paragraphs (e.g. an image). The elements are added in the order you pass them into the method.
166
+
167
+ If the article does not have enough space to place all the provided elements, they will be placed after the last
168
+ element in the article.
169
+
170
+ You can pass any type of element into this method.
171
+
172
+ If the objects you pass in are instances of elements defined within this gem (e.g. `ArticleJSON::Elements::Image`), you won't have to do anything else to render them.
173
+
114
174
  If you pass in an instance of a custom class (e.g. `MyAdvertisement`), make sure to register an exporter for this type (check the _Configuration_ section for more details).
115
175
 
116
176
  Example using only existing elements:
@@ -119,45 +179,45 @@ Example using only existing elements:
119
179
  article = ArticleJSON::Article.from_hash(parsed_json)
120
180
 
121
181
  # Within your code, create additional elements you would like to add
122
- image_advertisement =
123
- ArticleJSON::Elements::Image.new(source_url: 'https://robohash.org/great-ad',
182
+ image_advertisement =
183
+ ArticleJSON::Elements::Image.new(source_url: 'https://robohash.org/great-ad',
124
184
  caption: ArticleJSON::Elements::Text.new(
125
185
  content: 'Buy more robots!',
126
186
  href: '/robot-sale'
127
187
  ))
128
- text_box_similar_articles =
188
+ text_box_similar_articles =
129
189
  ArticleJSON::Elements::TextBox.new(content: [
130
- ArticleJSON::Elements::Heading.new(level: 3, content: 'Read more...'),
190
+ ArticleJSON::Elements::Heading.new(level: 3, content: 'Read more...'),
131
191
  ArticleJSON::Elements::List.new(content: [
132
192
  ArticleJSON::Elements::Paragraph(content: [
133
- ArticleJSON::Elements::Text.new(content: 'Very similar article',
193
+ ArticleJSON::Elements::Text.new(content: 'Very similar article',
134
194
  href: '/news/123'),
135
195
  ]),
136
196
  ArticleJSON::Elements::Paragraph(content: [
137
- ArticleJSON::Elements::Text.new(content: 'Great article!',
197
+ ArticleJSON::Elements::Text.new(content: 'Great article!',
138
198
  href: '/news/42'),
139
199
  ]),
140
- ]),
200
+ ]),
141
201
  ])
142
202
 
143
203
  # Add these elements to the article
144
- article.place_additional_elements([image_advertisement,
204
+ article.place_additional_elements([image_advertisement,
145
205
  text_box_similar_articles])
146
-
147
- # Export the article to the different formats as you would normally do
206
+
207
+ # Export the article to the different formats as you would normally do
148
208
  article.to_html # this will now include the custom elements
149
- ```
209
+ ```
150
210
 
151
211
  Example with custom advertisement elements:
152
212
  ```ruby
153
213
  # Define your custom element class
154
214
  class MyAdvertisement
155
215
  attr_reader :url
156
-
216
+
157
217
  def initialize(url:)
158
218
  @url = url
159
219
  end
160
-
220
+
161
221
  def type
162
222
  :my_advertisement
163
223
  end
@@ -165,9 +225,9 @@ end
165
225
 
166
226
  # Define an exporter for your class, we only use HTML in this example but this
167
227
  # would work similarly for AMP or other formats
168
- class MyAdvertisementExporter <
169
- ArticleJSON::Export::HTML::Elements::Base
170
-
228
+ class MyAdvertisementExporter <
229
+ ArticleJSON::Export::HTML::Elements::Base
230
+
171
231
  # Needs to implement the `#export` method
172
232
  def export
173
233
  create_element(:iframe, src: @element.url)
@@ -194,35 +254,26 @@ article.to_html
194
254
 
195
255
  ## Export
196
256
  ### HTML
197
- The HTML exporter generates a HTML string for a list of elements. An example of
198
- the HTML export for the parsed reference document can be found
199
- [here](https://github.com/Devex/article_json/blob/master/spec/fixtures/reference_document_exported.html).
257
+ The HTML exporter generates an HTML string for a list of elements. An example of the HTML export for the parsed reference document can be found [here](https://github.com/Devex/article_json/blob/master/spec/fixtures/reference_document_exported.html).
200
258
 
201
259
  ### AMP
202
- The AMP exporter generates an AMP HTML representation of the elements.
260
+ The AMP exporter generates an AMP HTML representation of the elements.
203
261
 
204
262
  AMP uses [custom HTML tags](https://www.ampproject.org/docs/reference/components), some of which require additional Javascript libraries.
205
- If you have an `article` (see code example in _Usage_ section), you can get a list of the custom tags required by this article by calling `article.amp_exporter.custom_element_tags` and by calling `article.amp_exporter.amp_libraries` you get a list of `<script>` tags that can directly be included on your page to render the AMP article.
206
263
 
207
- An example of
208
- the AMP HTML export for the parsed reference document can be found
209
- [here](https://github.com/Devex/article_json/blob/master/spec/fixtures/reference_document_exported.amp.html).
264
+ If you have an `article` (see code example in _Usage_ section), you can get a list of the custom tags required by this article by calling `article.amp_exporter.custom_element_tags` and calling `article.amp_exporter.amp_libraries` gives a list of `<script>` tags that can directly be included on your page to render the AMP article.
265
+
266
+ An example of the AMP HTML export for the parsed reference document can be found [here](https://github.com/Devex/article_json/blob/master/spec/fixtures/reference_document_exported.amp.html).
210
267
 
211
268
  ### Facebook Instant Articles
212
- The `FacebookInstantArticle` exporter generates a custom HTML string for a list
213
- of elements. An example of the Facebook Instant Article export for the parsed
214
- reference document can be found
215
- [here](https://github.com/Devex/article_json/blob/master/spec/fixtures/reference_document_exported.html).
269
+ The `FacebookInstantArticle` exporter generates a custom HTML string for a list of elements. An example of the Facebook Instant Article export for the parsed reference document can be found [here](https://github.com/Devex/article_json/blob/master/spec/fixtures/reference_document_exported.html).
216
270
 
217
- To learn more about the Facebook Instant Article HTML format see have a look at
218
- the [Facebook Developer Documentation](https://developers.facebook.com/docs/instant-articles/guides/format-overview).
271
+ To learn more about the Facebook Instant Article HTML format see have a look at the [Facebook Developer Documentation](https://developers.facebook.com/docs/instant-articles/guides/format-overview).
219
272
 
220
273
  ### Plain Text
221
- As the name suggests, this exporter generates a plain text version of the article.
222
- Rich text elements like images, embeds or even text boxes are not being rendered.
274
+ As the name suggests, this exporter generates a plain text version of the article. Rich text elements like images, embeds or even text boxes are not being rendered.
223
275
 
224
- The reference document rendered as plain text can be found
225
- [here](https://github.com/Devex/article_json/blob/master/spec/fixtures/reference_document_exported.txt).
276
+ The reference document rendered as plain text can be found [here](https://github.com/Devex/article_json/blob/master/spec/fixtures/reference_document_exported.txt).
226
277
 
227
278
  Usage:
228
279
  ```ruby
@@ -230,22 +281,22 @@ Usage:
230
281
  article = ArticleJSON::Article.from_hash(parsed_json)
231
282
 
232
283
  # Then simply call `#to_plain_text` on it
233
- article.to_plain_text
284
+ article.to_plain_text
234
285
  ```
235
286
 
236
287
  ## Contributing
237
288
  - Fork this repository
238
- - Implement your feature or fix including Tests
289
+ - Implement your feature or fix including tests
239
290
  - Update the [change log](CHANGELOG.md)
240
291
  - Commit your changes with a meaningful commit message
241
292
  - Create a pull request
242
293
 
243
294
  Thank you!
244
295
 
245
- See the
296
+ See the
246
297
  [list of contributors](https://github.com/Devex/article_json/contributors).
247
298
 
248
- ### Tests
299
+ ## Tests
249
300
  For the whole test suite, run `bundle exec rspec`.
250
301
 
251
302
  For individual tests, run `bundle exec rspec spec/article_json/version_spec.rb`.
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4
+ #
5
+ # Simple script to read a JSON document and export it to AMP.
6
+ #
7
+ # Usage:
8
+ #
9
+ # ./bin/article_json_export_amp.rb < my_document.json
10
+ #
11
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
12
+
13
+ require 'bundler/setup'
14
+ require_relative '../lib/article_json'
15
+ puts ArticleJSON::Article.from_json(ARGF.read).to_amp
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4
+ #
5
+ # Simple script to read a JSON document and export it to Apple News.
6
+ #
7
+ # Usage:
8
+ #
9
+ # ./bin/article_json_export_apple_news.rb < my_document.json
10
+ #
11
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
12
+
13
+ require 'bundler/setup'
14
+ require_relative '../lib/article_json'
15
+ puts ArticleJSON::Article.from_json(ARGF.read).to_apple_news
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4
+ #
5
+ # Simple script to read a JSON document and export it to Facebook Instant
6
+ # Article.
7
+ #
8
+ # Usage:
9
+ #
10
+ # ./bin/article_json_export_facebook.rb < my_document.json
11
+ #
12
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
13
+
14
+ require 'bundler/setup'
15
+ require_relative '../lib/article_json'
16
+ puts ArticleJSON::Article.from_json(ARGF.read).to_facebook_instant_article
@@ -10,5 +10,6 @@
10
10
  #
11
11
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
12
12
 
13
+ require 'bundler/setup'
13
14
  require_relative '../lib/article_json'
14
15
  puts ArticleJSON::Article.from_json(ARGF.read).to_html
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4
+ #
5
+ # Simple script to read a JSON document and export it to plain text.
6
+ #
7
+ # Usage:
8
+ #
9
+ # ./bin/article_json_export_plain_text.rb < my_document.json
10
+ #
11
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
12
+
13
+ require 'bundler/setup'
14
+ require_relative '../lib/article_json'
15
+ puts ArticleJSON::Article.from_json(ARGF.read).to_plain_text
@@ -10,5 +10,6 @@
10
10
  #
11
11
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
12
12
 
13
+ require 'bundler/setup'
13
14
  require_relative '../lib/article_json'
14
15
  puts ArticleJSON::Article.from_google_doc_html((ARGF.read)).to_json
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4
+ #
5
+ # Script to check that google doc export works as expected.
6
+ #
7
+ # Usage:
8
+ #
9
+ # ./bin/check_google_doc_export.rb
10
+ #
11
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
12
+
13
+ require 'bundler/setup'
14
+ require 'net/http'
15
+ require 'uri'
16
+ require_relative '../lib/article_json'
17
+
18
+ doc_id = '1E4lncZE2jDkbE34eDyYQmXKA9O26BHUiwguz4S9qyE8'
19
+ url =
20
+ "https://docs.google.com/feeds/download/documents/export/Export?id=#{doc_id}&exportFormat=html"
21
+ parsed_exported_doc = JSON.parse(
22
+ ArticleJSON::Article
23
+ .from_google_doc_html(Net::HTTP.get(URI.parse(url)))
24
+ .to_json
25
+ )
26
+ parsed_expected_doc = JSON.parse(File.read('spec/fixtures/reference_document_parsed.json'))
27
+
28
+ # `source_url` (for hosted images) is dynamic, so we need to remove it from the comparison`
29
+ def nullify_source_url(hash)
30
+ hash['content'].each { |element| element['source_url'] = nil if element['source_url'] }
31
+ hash
32
+ end
33
+
34
+ parsed_exported_doc = nullify_source_url(parsed_exported_doc)
35
+ parsed_expected_doc = nullify_source_url(parsed_expected_doc)
36
+
37
+ if parsed_exported_doc != parsed_expected_doc
38
+ raise StandardError, "Google doc export doesn't work as expected"
39
+ end
40
+
41
+ puts 'Google doc export worked as expected'
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env sh
2
+
3
+ curl -X GET "https://vimeo.com/api/oembed.json?url=https://vimeo.com/42315417" | jq > spec/fixtures/vimeo_video_oembed.json
4
+
5
+ curl -X GET "https://www.youtube.com/oembed?format=json&url=https://www.youtube.com/watch?v=_ZG8HBuDjgc" | jq > spec/fixtures/youtube_video_oembed.json
6
+
7
+ curl -X GET "https://www.slideshare.net/api/oembed/2?format=json&url=https://www.slideshare.net/Devex/the-best-global-development-quotes-of-2012" | jq > spec/fixtures/slideshare_oembed.json
8
+
9
+ curl -X GET "https://api.twitter.com/1/statuses/oembed.json?align=center&url=https://twitter.com/d3v3x/status/554608639030599681" | jq > spec/fixtures/tweet_oembed.json
10
+
11
+ curl -X GET 'https://soundcloud.com/oembed?format=json&url=https://soundcloud.com/rich-the-kid/plug-walk-1' | jq > spec/fixtures/soundcloud_oembed.json
@@ -7,6 +7,10 @@ DOC_ID="1E4lncZE2jDkbE34eDyYQmXKA9O26BHUiwguz4S9qyE8"
7
7
  SOURCE_HTML_FILE="spec/fixtures/reference_document.html"
8
8
  JSON_FILE="spec/fixtures/reference_document_parsed.json"
9
9
  HTML_EXPORT_FILE="spec/fixtures/reference_document_exported.html"
10
+ AMP_EXPORT_FILE="spec/fixtures/reference_document_exported.amp.html"
11
+ FACEBOOK_EXPORT_FILE="spec/fixtures/reference_document_exported.facebook.html"
12
+ APPLE_NEWS_EXPORT_FILE="spec/fixtures/reference_document_exported.apple_news.json"
13
+ PLAIN_TEXT_EXPORT_FILE="spec/fixtures/reference_document_exported.txt"
10
14
 
11
15
  # export the google doc to HTML
12
16
  ./bin/article_json_export_google_doc.rb ${DOC_ID} > ${SOURCE_HTML_FILE}
@@ -16,3 +20,15 @@ HTML_EXPORT_FILE="spec/fixtures/reference_document_exported.html"
16
20
 
17
21
  # convert the JSON export to HTML
18
22
  ./bin/article_json_export_html.rb < ${JSON_FILE} > ${HTML_EXPORT_FILE}
23
+
24
+ # convert the JSON export to AMP
25
+ ./bin/article_json_export_amp.rb < ${JSON_FILE} > ${AMP_EXPORT_FILE}
26
+
27
+ # convert the JSON export to Facebook Instant Article
28
+ ./bin/article_json_export_facebook.rb < ${JSON_FILE} > ${FACEBOOK_EXPORT_FILE}
29
+
30
+ # convert the JSON export to Apple News
31
+ ./bin/article_json_export_apple_news.rb < ${JSON_FILE} > ${APPLE_NEWS_EXPORT_FILE}
32
+
33
+ # convert the JSON export to plain text
34
+ ./bin/article_json_export_plain_text.rb < ${JSON_FILE} > ${PLAIN_TEXT_EXPORT_FILE}
@@ -14,7 +14,7 @@ module ArticleJSON
14
14
  def elements
15
15
  @elements ||= begin
16
16
  if @additional_elements.any?
17
- ArticleJSON::Utils::AdditionalElementPlacer
17
+ @additional_element_placer_class
18
18
  .new(@article_elements, @additional_elements)
19
19
  .merge_elements
20
20
  else
@@ -62,6 +62,18 @@ module ArticleJSON
62
62
  amp_exporter.html
63
63
  end
64
64
 
65
+ # Exporter instance for AppleNews
66
+ # @return [ArticleJSON::Export::AppleNews::Exporter]
67
+ def apple_news_exporter
68
+ ArticleJSON::Export::AppleNews::Exporter.new(elements)
69
+ end
70
+
71
+ # AppleNews export of the article
72
+ # @return [String]
73
+ def to_apple_news
74
+ apple_news_exporter.to_json
75
+ end
76
+
65
77
  # Exporter instance for FacebookInstantArticle
66
78
  # @return [ArticleJSON::Export::FacebookInstantArticle::Exporter]
67
79
  def facebook_instant_article_exporter
@@ -91,10 +103,18 @@ module ArticleJSON
91
103
  # article. If the method is called multiple times, the order of additional
92
104
  # elements is maintained.
93
105
  # @param [Object] additional_elements
94
- def place_additional_elements(additional_elements)
106
+ # @param [Class<#merge_elements>] with - The passes class's `#initialize` method needs
107
+ # to accept two lists of elements. See
108
+ # `ArticleJSON::Utils::AdditionalElementPlacer`
109
+ # for reference.
110
+ def place_additional_elements(
111
+ additional_elements,
112
+ with: ArticleJSON::Utils::AdditionalElementPlacer
113
+ )
95
114
  # Reset the `#elements` method memoization
96
115
  @elements = nil
97
116
  @additional_elements.concat(additional_elements)
117
+ @additional_element_placer_class = with
98
118
  end
99
119
 
100
120
  class << self
@@ -14,10 +14,11 @@ module ArticleJSON
14
14
  end
15
15
 
16
16
  class Configuration
17
- attr_accessor :oembed_user_agent
17
+ attr_accessor :oembed_user_agent, :facebook_token
18
18
 
19
19
  def initialize
20
20
  @oembed_user_agent = nil
21
+ @facebook_token = nil
21
22
  @custom_element_exporters = {}
22
23
  end
23
24
 
@@ -37,4 +37,3 @@ module ArticleJSON
37
37
  end
38
38
  end
39
39
  end
40
-
@@ -1,18 +1,20 @@
1
1
  module ArticleJSON
2
2
  module Elements
3
3
  class Image < Base
4
- attr_reader :source_url, :caption, :float, :href
4
+ attr_reader :source_url, :caption, :float, :href, :alt
5
5
 
6
6
  # @param [String] source_url
7
7
  # @param [Array[ArticleJSON::Elements::Text]] caption
8
8
  # @param [Symbol] float
9
9
  # @param [String] href
10
- def initialize(source_url:, caption:, float: nil, href: nil)
10
+ # @param [String] alt
11
+ def initialize(source_url:, caption:, float: nil, href: nil, alt: nil)
11
12
  @type = :image
12
13
  @source_url = source_url
13
14
  @caption = caption
14
15
  @float = float
15
16
  @href = href
17
+ @alt = alt
16
18
  end
17
19
 
18
20
  # Hash representation of this image element
@@ -24,6 +26,7 @@ module ArticleJSON
24
26
  float: float,
25
27
  caption: caption.map(&:to_h),
26
28
  href: href,
29
+ alt: alt,
27
30
  }
28
31
  end
29
32
 
@@ -35,7 +38,8 @@ module ArticleJSON
35
38
  source_url: hash[:source_url],
36
39
  caption: parse_hash_list(hash[:caption]),
37
40
  float: hash[:float]&.to_sym,
38
- href: hash[:href]
41
+ href: hash[:href],
42
+ alt: hash[:alt]
39
43
  )
40
44
  end
41
45
  end
@@ -69,7 +69,7 @@ module ArticleJSON
69
69
 
70
70
  # @return [Nokogiri::XML::Element]
71
71
  def facebook_node
72
- url = "#{@element.oembed_data[:author_url]}videos/#{@element.embed_id}"
72
+ url = "#{@element.oembed_data[:author_url]}/videos/#{@element.embed_id}"
73
73
  create_element('amp-facebook',
74
74
  'data-embedded-as' => 'video',
75
75
  'data-href' => url,