ghostwriter 1.0.1 → 1.1.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.
- checksums.yaml +4 -4
- data/README.md +84 -9
- data/RELEASE_NOTES.md +18 -0
- data/lib/ghostwriter/version.rb +1 -1
- data/lib/ghostwriter/writer.rb +54 -27
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b87477fb4de8fc196eda6ea049eb3f1355ae583f0622c11b98543a67cfe71c8b
|
4
|
+
data.tar.gz: fa4e66701a3326ccceef69b3eb8f8591f8eea337f6f4f37c5b18a820bd120d42
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b5c545e83c7073b3c5923efc3ffcb6ecfd78650c472a482b5ec16fd7ef5533859ce6fb24d32378aafd20c83e35acd558c136856b46f0c7e0373beb7e3191be34
|
7
|
+
data.tar.gz: 8b259323e6653c112885ddf6fe4ee99b31c01e5625ee2fcf22d0259330dc090df11a1b7ee2dc1507c222b5f79c8322717aba9455b9bdbdca04334c0becc5959a
|
data/README.md
CHANGED
@@ -172,9 +172,9 @@ This meal we enjoy together would be improved by one.
|
|
172
172
|
|
173
173
|
```
|
174
174
|
|
175
|
-
###
|
175
|
+
### Headings
|
176
176
|
|
177
|
-
|
177
|
+
Headings are wrapped with a marker per heading level:
|
178
178
|
|
179
179
|
```html
|
180
180
|
<h1>Dog Maintenance and Repair</h1>
|
@@ -186,10 +186,12 @@ Becomes:
|
|
186
186
|
|
187
187
|
```
|
188
188
|
-- Dog Maintenance and Repair --
|
189
|
-
|
190
|
-
|
189
|
+
---- Food Input Port ----
|
190
|
+
------ Exhaust Port Considerations ------
|
191
191
|
```
|
192
192
|
|
193
|
+
The `<header>` tag is treated like an `<h1>` tag.
|
194
|
+
|
193
195
|
### Lists
|
194
196
|
|
195
197
|
Lists are converted, too. They are padded with newlines and are given simple markers:
|
@@ -211,7 +213,6 @@ Lists are converted, too. They are padded with newlines and are given simple mar
|
|
211
213
|
Becomes:
|
212
214
|
|
213
215
|
```
|
214
|
-
|
215
216
|
- Planes
|
216
217
|
- Trains
|
217
218
|
- Automobiles
|
@@ -219,7 +220,6 @@ Becomes:
|
|
219
220
|
1. I get knocked down
|
220
221
|
2. I get up again
|
221
222
|
3. Never gonna keep me down
|
222
|
-
|
223
223
|
```
|
224
224
|
|
225
225
|
### Tables
|
@@ -265,10 +265,85 @@ Becomes:
|
|
265
265
|
| Planet Express Ship | Turanga Leela |
|
266
266
|
```
|
267
267
|
|
268
|
-
###
|
268
|
+
### Customizing Output
|
269
|
+
|
270
|
+
Ghostwriter has some constructor options to customize output.
|
271
|
+
|
272
|
+
You can set heading markers.
|
273
|
+
|
274
|
+
```ruby
|
275
|
+
html = <<~HTML
|
276
|
+
<h1>Emergency Cat Procedures</h1>
|
277
|
+
HTML
|
278
|
+
|
279
|
+
writer = Ghostwriter::Writer.new(heading_marker: '#')
|
280
|
+
|
281
|
+
puts writer.textify(html)
|
282
|
+
```
|
283
|
+
|
284
|
+
Produces:
|
285
|
+
|
286
|
+
```
|
287
|
+
# Emergency Cat Procedures #
|
288
|
+
```
|
289
|
+
|
290
|
+
You can also set list item markers. Ordered markers can be anything that responds to `#next` (eg. any `Enumerator`)
|
291
|
+
|
292
|
+
```ruby
|
293
|
+
html = <<~HTML
|
294
|
+
<ol><li>Mercury</li><li>Venus</li><li>Mars</li></ol>
|
295
|
+
<ul><li>Teapot</li><li>Kettle</li></ul>
|
296
|
+
HTML
|
297
|
+
|
298
|
+
writer = Ghostwriter::Writer.new(ul_marker: '*', ol_marker: 'a')
|
299
|
+
|
300
|
+
puts writer.textify(html)
|
301
|
+
```
|
302
|
+
|
303
|
+
Produces:
|
304
|
+
|
305
|
+
```
|
306
|
+
a. Mercury
|
307
|
+
b. Venus
|
308
|
+
c. Mars
|
309
|
+
|
310
|
+
* Teapot
|
311
|
+
* Kettle
|
312
|
+
```
|
313
|
+
|
314
|
+
And tables can be customized:
|
315
|
+
|
316
|
+
```ruby
|
317
|
+
writer = Ghostwriter::Writer.new(table_row: '.',
|
318
|
+
table_column: '#',
|
319
|
+
table_corner: '+')
|
320
|
+
|
321
|
+
puts writer.textify <<~HTML
|
322
|
+
<table>
|
323
|
+
<thead>
|
324
|
+
<tr><th>Moon</th><th>Portfolio</th></tr>
|
325
|
+
</thead>
|
326
|
+
<tbody>
|
327
|
+
<tr><td>Phobos</td><td>Fear & Panic</td></tr>
|
328
|
+
<tr><td>Deimos</td><td>Dread and Terror</td></tr>
|
329
|
+
</tbody>
|
330
|
+
</table>
|
331
|
+
HTML
|
332
|
+
```
|
333
|
+
|
334
|
+
Produces:
|
335
|
+
|
336
|
+
```
|
337
|
+
# Moon # Portfolio #
|
338
|
+
+........+..................+
|
339
|
+
# Phobos # Fear & Panic #
|
340
|
+
# Deimos # Dread and Terror #
|
341
|
+
|
342
|
+
```
|
343
|
+
|
344
|
+
#### Presentation ARIA Role
|
269
345
|
|
270
|
-
|
271
|
-
suppressed.
|
346
|
+
Tags with `role="presentation"` will be treated as a simple container and the normal behaviour will be suppressed.
|
272
347
|
|
273
348
|
```html
|
274
349
|
|
data/RELEASE_NOTES.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
# Release Notes
|
2
2
|
|
3
|
+
## 1.1.0 (2021-03-23)
|
4
|
+
|
5
|
+
### Major
|
6
|
+
|
7
|
+
* none
|
8
|
+
|
9
|
+
### Minor
|
10
|
+
|
11
|
+
* Added customization for headings
|
12
|
+
* Headings now marked more for higher order headings
|
13
|
+
* Added customization for list markers
|
14
|
+
* Added customization for table markers
|
15
|
+
* Writer is now immutable
|
16
|
+
|
17
|
+
### Bugfixes
|
18
|
+
|
19
|
+
* none
|
20
|
+
|
3
21
|
## 1.0.1 (2021-03-22)
|
4
22
|
|
5
23
|
### Major
|
data/lib/ghostwriter/version.rb
CHANGED
data/lib/ghostwriter/writer.rb
CHANGED
@@ -3,12 +3,22 @@
|
|
3
3
|
module Ghostwriter
|
4
4
|
# Main Ghostwriter converter object.
|
5
5
|
class Writer
|
6
|
+
attr_reader :link_base, :heading_marker, :ul_marker, :ol_marker, :table_row, :table_column, :table_corner
|
7
|
+
|
6
8
|
# Creates a new ghostwriter
|
7
9
|
#
|
8
10
|
# @param [String] link_base the url to prefix relative links with
|
9
|
-
def initialize(link_base: ''
|
10
|
-
|
11
|
-
@
|
11
|
+
def initialize(link_base: '', heading_marker: '--', ul_marker: '-', ol_marker: '1',
|
12
|
+
table_column: '|', table_row: '-', table_corner: '|')
|
13
|
+
@link_base = link_base
|
14
|
+
@heading_marker = heading_marker
|
15
|
+
@ul_marker = ul_marker
|
16
|
+
@ol_marker = ol_marker
|
17
|
+
@table_column = table_column
|
18
|
+
@table_row = table_row
|
19
|
+
@table_corner = table_corner
|
20
|
+
|
21
|
+
freeze
|
12
22
|
end
|
13
23
|
|
14
24
|
# Strips HTML down to plain text.
|
@@ -34,13 +44,13 @@ module Ghostwriter
|
|
34
44
|
simple_replace(doc, 'br', "\n")
|
35
45
|
simple_replace(doc, 'p', "\n\n")
|
36
46
|
|
37
|
-
doc
|
47
|
+
normalize_lines(doc)
|
38
48
|
end
|
39
49
|
|
40
50
|
private
|
41
51
|
|
42
|
-
def
|
43
|
-
|
52
|
+
def normalize_lines(doc)
|
53
|
+
doc.text.strip.split("\n").collect(&:strip).join("\n").concat("\n")
|
44
54
|
end
|
45
55
|
|
46
56
|
def replace_anchors(doc)
|
@@ -78,8 +88,16 @@ module Ghostwriter
|
|
78
88
|
end
|
79
89
|
|
80
90
|
def replace_headers(doc)
|
81
|
-
doc.search('header, h1
|
82
|
-
node.
|
91
|
+
doc.search('header, h1').each do |node|
|
92
|
+
node.replace("#{ @heading_marker } #{ node.inner_html } #{ @heading_marker }\n"
|
93
|
+
.squeeze(' '))
|
94
|
+
end
|
95
|
+
|
96
|
+
(2..6).each do |n|
|
97
|
+
doc.search("h#{ n }").each do |node|
|
98
|
+
node.replace("#{ @heading_marker * n } #{ node.inner_html } #{ @heading_marker * n }\n"
|
99
|
+
.squeeze(' '))
|
100
|
+
end
|
83
101
|
end
|
84
102
|
end
|
85
103
|
|
@@ -97,41 +115,50 @@ module Ghostwriter
|
|
97
115
|
end
|
98
116
|
|
99
117
|
def replace_lists(doc)
|
100
|
-
doc.search('
|
101
|
-
list_node.
|
102
|
-
|
103
|
-
"#{ i + 1 }."
|
104
|
-
else
|
105
|
-
@list_marker
|
106
|
-
end
|
107
|
-
|
108
|
-
list_item.inner_html = "#{ marker } #{ list_item.inner_html }\n".squeeze(' ')
|
109
|
-
end
|
118
|
+
doc.search('ol').each do |list_node|
|
119
|
+
replace_list_items(list_node, @ol_marker, after_marker: '.', increment: true)
|
120
|
+
end
|
110
121
|
|
122
|
+
doc.search('ul').each do |list_node|
|
123
|
+
replace_list_items(list_node, @ul_marker)
|
124
|
+
end
|
125
|
+
|
126
|
+
doc.search('ul, ol').each do |list_node|
|
111
127
|
list_node.replace("#{ list_node.inner_html }\n")
|
112
128
|
end
|
113
129
|
end
|
114
130
|
|
131
|
+
def replace_list_items(list_node, marker, after_marker: '', increment: false)
|
132
|
+
list_node.search('./li').each do |list_item|
|
133
|
+
list_item.replace("#{ marker }#{ after_marker } #{ list_item.inner_html }\n")
|
134
|
+
|
135
|
+
marker = marker.next if increment
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
115
139
|
def replace_tables(doc)
|
116
140
|
doc.css('table').each do |table|
|
141
|
+
# remove whitespace between nodes
|
142
|
+
table.search('//text()[normalize-space()=""]').remove
|
143
|
+
|
117
144
|
column_sizes = calculate_column_sizes(table)
|
118
145
|
|
119
146
|
table.search('./thead/tr', './tbody/tr', './tr').each do |row|
|
120
147
|
replace_table_nodes(row, column_sizes)
|
121
148
|
|
122
|
-
row.
|
149
|
+
row.replace("#{ row.inner_html }#{ @table_column }\n")
|
123
150
|
end
|
124
151
|
|
125
152
|
add_table_header_underline(table, column_sizes)
|
126
153
|
|
127
|
-
table.
|
154
|
+
table.replace("\n#{ table.inner_html }\n")
|
128
155
|
end
|
129
156
|
end
|
130
157
|
|
131
158
|
def calculate_column_sizes(table)
|
132
159
|
column_sizes = table.search('tr').collect do |row|
|
133
160
|
row.search('th', 'td').collect do |node|
|
134
|
-
node.
|
161
|
+
node.text.length
|
135
162
|
end
|
136
163
|
end
|
137
164
|
|
@@ -139,19 +166,19 @@ module Ghostwriter
|
|
139
166
|
end
|
140
167
|
|
141
168
|
def add_table_header_underline(table, column_sizes)
|
142
|
-
table.search('./thead').each do |
|
143
|
-
|
169
|
+
table.search('./thead').each do |thead|
|
170
|
+
lines = column_sizes.collect { |len| @table_row * (len + 2) }
|
171
|
+
underline_row = "#{ table_corner }#{ lines.join(@table_corner) }#{ @table_corner }"
|
144
172
|
|
145
|
-
|
173
|
+
thead.replace("#{ thead.inner_html }#{ underline_row }\n")
|
146
174
|
end
|
147
175
|
end
|
148
176
|
|
149
177
|
def replace_table_nodes(row, column_sizes)
|
150
178
|
row.search('th', 'td').each_with_index do |node, i|
|
151
|
-
new_content =
|
179
|
+
new_content = node.text.ljust(column_sizes[i] + 1)
|
152
180
|
|
153
|
-
#
|
154
|
-
node.inner_html = new_content.ljust(column_sizes[i] + 2)
|
181
|
+
node.replace("#{ @table_column } #{ new_content }")
|
155
182
|
end
|
156
183
|
end
|
157
184
|
|