wordpress-formatting 0.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 +7 -0
- data/README.md +78 -0
- data/lib/wordpress_formatting.rb +6 -0
- data/lib/wordpress_formatting/wpautop.rb +193 -0
- metadata +87 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 212f408685f81941f48154fdf71253c18c7c16f64e9c3de5cde8c9238ef279f9
|
4
|
+
data.tar.gz: 3d2590195083cc28d25e93e79ae7a000ae69c6650c50f6cd9e271fc1f900d22e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1a2ee0c3087abdcd854e8fa6efa1144cca9a4540077806c6d09e4781d6414299042f8605c2a8acdee8c835c83104f4c2027852392bb51d92085d17d2d25334bf
|
7
|
+
data.tar.gz: 051ed4c23c4012b7ccb7021dd5cb5dc393dc97824b251b4cf76c04da6d2f77b613ae7f1a676046a1216eeb2bbecc03724e7306b9f862bc4545b5319741aa8e9e
|
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# Wordpress Formatting
|
2
|
+
|
3
|
+
Ruby port for WP's formatting functions.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'wordpress-formatting'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install wordpress-formatting
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
### wpautop
|
24
|
+
|
25
|
+
WordPress posts are formatted with the `wpautop` function. To obtain
|
26
|
+
the same results in Ruby, run:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
require 'wordpress_formatting/wpautop'
|
30
|
+
|
31
|
+
WordpressFormatting.wpautop 'A string'
|
32
|
+
=> "<p>A string</p>"
|
33
|
+
```
|
34
|
+
|
35
|
+
You can also extend a class:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
class String
|
39
|
+
include WordpressFormatting::Wpautop
|
40
|
+
end
|
41
|
+
|
42
|
+
"A string".wpautop
|
43
|
+
=> "<p>A string</p>"
|
44
|
+
```
|
45
|
+
|
46
|
+
It `fast_blank` is available, it will try to use it.
|
47
|
+
|
48
|
+
## Development
|
49
|
+
|
50
|
+
After checking out the repo, run `bin/setup` to install dependencies.
|
51
|
+
Then, run `rake test` to run the tests. You can also run `bin/console`
|
52
|
+
for an interactive prompt that will allow you to experiment.
|
53
|
+
|
54
|
+
To install this gem onto your local machine, run `bundle exec rake
|
55
|
+
install`. To release a new version, update the version number in
|
56
|
+
`version.rb`, and then run `bundle exec rake release`, which will create
|
57
|
+
a git tag for the version, push git commits and tags, and push the
|
58
|
+
`.gem` file to [rubygems.org](https://rubygems.org).
|
59
|
+
|
60
|
+
## Contributing
|
61
|
+
|
62
|
+
Bug reports and pull requests are welcome on 0xacab.org at
|
63
|
+
<https://0xacab.org/sutty/wordpress-formatting>. This
|
64
|
+
project is intended to be a safe, welcoming space for collaboration, and
|
65
|
+
contributors are expected to adhere to the [Sutty code of
|
66
|
+
conduct](https://sutty.nl/en/code-of-conduct/).
|
67
|
+
|
68
|
+
## License
|
69
|
+
|
70
|
+
The gem is available as free software under the terms of the GPL2
|
71
|
+
License.
|
72
|
+
|
73
|
+
## Code of Conduct
|
74
|
+
|
75
|
+
Everyone interacting in the wordpress-formatting project’s codebases,
|
76
|
+
issue trackers, chat rooms and mailing lists is expected to follow the
|
77
|
+
[code of conduct](https://sutty.nl/en/code-of-conduct/).
|
78
|
+
|
@@ -0,0 +1,193 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Use fast_blank if available
|
4
|
+
begin
|
5
|
+
require 'fast_blank'
|
6
|
+
rescue LoadError
|
7
|
+
end
|
8
|
+
|
9
|
+
module WordpressFormatting
|
10
|
+
module Wpautop
|
11
|
+
# This class is a Ruby port of Wordpress' wpautop() function, as
|
12
|
+
# included in wp-includes/formatting.php.
|
13
|
+
#
|
14
|
+
# Some adjustments were made but it tries to follow the same code
|
15
|
+
# structure, so updating it when it changes wouldn't need much work.
|
16
|
+
# Some Rubyisms were applied when they made sense. Comments are
|
17
|
+
# kept from the original.
|
18
|
+
#
|
19
|
+
# Regular expressions were converted to constants for performance.
|
20
|
+
class << self
|
21
|
+
MULTIPLE_BR = %r{<br\s*/?>\s*<br\s*/?>}
|
22
|
+
ALLBLOCKS_OPEN = %r{(?<block><(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)[\s/>])}
|
23
|
+
ALLBLOCKS_CLOSE = %r{(?<block></(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)>)}
|
24
|
+
HR = %r{(?<hr><hr\s*?/?>)}
|
25
|
+
CRLF = %r{(\r\n|\r)}
|
26
|
+
MANY_NL = %r{\n\n+}
|
27
|
+
SPLIT_NL = %r{\n\s*\n}
|
28
|
+
EMPTY_P = %r{<p>\s*</p>}
|
29
|
+
CLOSE_P = %r{<p>(?<content>[^<]+)</(?<tag>div|address|form)>}
|
30
|
+
UNWRAP_P = %r{<p>\s*(?<unwrap></?(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)[^>]*>)\s*</p>}
|
31
|
+
UNWRAP_LI = %r{<p>(?<unwrap><li.+?)</p>}
|
32
|
+
UNWRAP_BLOCKQUOTE = %r{<p><blockquote(?<unwrap>[^>]*)>}i
|
33
|
+
REMOVE_BLOCK_OPENING = %r{<p>\s*(?<remove></?(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)[^>]*>)}
|
34
|
+
REMOVE_BLOCK_CLOSING = %r{(?<remove></?(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)[^>]*>)\s*</p>}
|
35
|
+
NLBR = %r{(?<!<br />)\s*\n}
|
36
|
+
REMOVE_BR = %r{(?<remove></?(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)[^>]*>)\s*<br />}
|
37
|
+
REMOVE_BR_SUBSET = %r{<br />(?<remove>\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)}
|
38
|
+
PRESERVE_NL = %r{<(script|style|svg).*?<\/\1>}
|
39
|
+
|
40
|
+
# XXX: Simplified because the RegExp with comments and CDATA
|
41
|
+
# doesn't compile
|
42
|
+
HTML_SPLIT = %r{(<[^>]*>?)}
|
43
|
+
|
44
|
+
# Allows to extend a class (like String) to perform WP formatting.
|
45
|
+
def included(base)
|
46
|
+
base.class_eval do
|
47
|
+
def wpautop(br = true)
|
48
|
+
WordpressFormatting::Wpautop.wpautop(to_s, br)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Replaces double line breaks with paragraph elements.
|
54
|
+
#
|
55
|
+
# A group of regex replaces used to identify text formatted with
|
56
|
+
# newlines and replace double line breaks with HTML paragraph
|
57
|
+
# tags. The remaining line breaks after conversion become <<br />>
|
58
|
+
# tags, unless $br is set to '0' or 'false'.
|
59
|
+
#
|
60
|
+
# @param [String] The text which has to be formatted.
|
61
|
+
# @param [Boolean] Optional. If set, this will convert all
|
62
|
+
# remaining line breaks after paragraphing. Line breaks within
|
63
|
+
# `<script>`, `<style>`, and `<svg>` tags are not
|
64
|
+
# affected. Default true.
|
65
|
+
# @return [String] Text which has been converted into correct
|
66
|
+
# paragraph tags.
|
67
|
+
def wpautop(pee, br = true)
|
68
|
+
return '' if pee.blank?
|
69
|
+
pee = pee.dup
|
70
|
+
pre_tags = {}
|
71
|
+
|
72
|
+
# Just to make things a little easier, pad the end.
|
73
|
+
pee << "\n"
|
74
|
+
|
75
|
+
if pee.include? '<pre'
|
76
|
+
pee_parts = pee.split '</pre>'
|
77
|
+
last_pee = pee_parts.pop
|
78
|
+
pee = ''.dup
|
79
|
+
|
80
|
+
pee_parts.each_with_index do |pee_part, i|
|
81
|
+
start = pee_part.index('<pre')
|
82
|
+
|
83
|
+
# Malformed HTML?
|
84
|
+
unless start
|
85
|
+
pee << pee_part
|
86
|
+
next
|
87
|
+
end
|
88
|
+
|
89
|
+
name = "<pre wp-pre-tag-#{i}></pre>"
|
90
|
+
|
91
|
+
pre_tags[name] = "#{pee_part[start..]}</pre>"
|
92
|
+
pee << pee_part[0..start-1]
|
93
|
+
pee << name
|
94
|
+
end
|
95
|
+
|
96
|
+
pee << last_pee
|
97
|
+
end
|
98
|
+
|
99
|
+
# Change multiple <br>'s into two line breaks, which will turn into paragraphs.
|
100
|
+
pee.gsub! MULTIPLE_BR, "\n\n"
|
101
|
+
|
102
|
+
# Add a double line break above block-level opening tags.
|
103
|
+
pee.gsub! ALLBLOCKS_OPEN, "\n\n\\k<block>"
|
104
|
+
|
105
|
+
# Add a double line break below block-level closing tags.
|
106
|
+
pee.gsub! ALLBLOCKS_CLOSE, "\\k<block>\n\n"
|
107
|
+
|
108
|
+
# Add a double line break after hr tags, which are self closing.
|
109
|
+
pee.gsub! HR, "\\k<hr>\n\n"
|
110
|
+
|
111
|
+
# Standardize newline characters to "\n".
|
112
|
+
pee.gsub! CRLF, "\n"
|
113
|
+
|
114
|
+
# Find newlines in all elements and add placeholders.
|
115
|
+
pee = pee.split(HTML_SPLIT).reduce(''.dup) do |new_pee, part|
|
116
|
+
new_pee << (part == "\n" ? ' <!-- wpnl --> ' : part)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Remove more than two contiguous line breaks.
|
120
|
+
pee.gsub! MANY_NL, "\n\n"
|
121
|
+
|
122
|
+
# Split up the contents into an array of strings, separated by double line breaks.
|
123
|
+
pees = pee.split(SPLIT_NL).reject(&:empty?)
|
124
|
+
|
125
|
+
# Reset pee prior to rebuilding.
|
126
|
+
pee = ''.dup
|
127
|
+
|
128
|
+
# Rebuild the content as a string, wrapping every bit with a <p>.
|
129
|
+
pees.each do |tinkle|
|
130
|
+
pee << "<p>#{tinkle.strip}</p>"
|
131
|
+
end
|
132
|
+
|
133
|
+
# Under certain strange conditions it could create a P of entirely whitespace.
|
134
|
+
pee.gsub! EMPTY_P, ''
|
135
|
+
|
136
|
+
# Add a closing <p> inside <div>, <address>, or <form> tag if missing.
|
137
|
+
pee.gsub! CLOSE_P, '<p>\\k<content></p></\\k<tag>>'
|
138
|
+
|
139
|
+
# If an opening or closing block element tag is wrapped in a <p>, unwrap it.
|
140
|
+
pee.gsub! UNWRAP_P, '\\k<unwrap>'
|
141
|
+
|
142
|
+
# In some cases <li> may get wrapped in <p>, fix them.
|
143
|
+
pee.gsub! UNWRAP_LI, '\\k<unwrap>'
|
144
|
+
|
145
|
+
# If a <blockquote> is wrapped with a <p>, move it inside the <blockquote>.
|
146
|
+
pee.gsub! UNWRAP_BLOCKQUOTE, '<blockquote\\k<unwrap>><p>'
|
147
|
+
pee.gsub! '</blockquote></p>', '</p></blockquote>'
|
148
|
+
|
149
|
+
# If an opening or closing block element tag is preceded by an opening <p> tag, remove it.
|
150
|
+
pee.gsub! REMOVE_BLOCK_OPENING, '\\k<remove>'
|
151
|
+
|
152
|
+
# If an opening or closing block element tag is followed by a closing <p> tag, remove it.
|
153
|
+
pee.gsub! REMOVE_BLOCK_CLOSING, '\\k<remove>'
|
154
|
+
|
155
|
+
# Optionally insert line breaks.
|
156
|
+
if br
|
157
|
+
# Replace newlines that shouldn't be touched with a placeholder.
|
158
|
+
pee.scan(PRESERVE_NL).each do |match|
|
159
|
+
pee.gsub! match, match.gsub("\n", '<WPPreserveNewline />')
|
160
|
+
end
|
161
|
+
|
162
|
+
# Normalize <br>
|
163
|
+
pee.gsub! '<br>', '<br />'
|
164
|
+
pee.gsub! '<br/>', '<br />'
|
165
|
+
|
166
|
+
# Replace any new line characters that aren't preceded by a <br /> with a <br />.
|
167
|
+
pee.gsub! NLBR, "<br />\n"
|
168
|
+
|
169
|
+
# Replace newline placeholders with newlines.
|
170
|
+
pee.gsub! '<WPPreserveNewline />', "\n"
|
171
|
+
end
|
172
|
+
|
173
|
+
# If a <br /> tag is after an opening or closing block tag, remove it.
|
174
|
+
pee.gsub! REMOVE_BR, '\\k<remove>'
|
175
|
+
|
176
|
+
# If a <br /> tag is before a subset of opening or closing block tags, remove it.
|
177
|
+
pee.gsub! REMOVE_BR_SUBSET, '\\k<remove>'
|
178
|
+
pee.gsub! "\n</p>$", '</p>'
|
179
|
+
|
180
|
+
# Replace placeholder <pre> tags with their original content.
|
181
|
+
pre_tags.each_pair do |key, value|
|
182
|
+
pee.gsub! key, value
|
183
|
+
end
|
184
|
+
|
185
|
+
# Restore newlines in all elements.
|
186
|
+
pee.gsub! ' <!-- wpnl --> ', "<br />"
|
187
|
+
pee.gsub! '<!-- wpnl -->', "<br />"
|
188
|
+
|
189
|
+
pee
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wordpress-formatting
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- f
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-07-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
description: Implements WordPress formatting functions in Ruby
|
42
|
+
email:
|
43
|
+
- f@sutty.nl
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files:
|
47
|
+
- README.md
|
48
|
+
files:
|
49
|
+
- README.md
|
50
|
+
- lib/wordpress_formatting.rb
|
51
|
+
- lib/wordpress_formatting/wpautop.rb
|
52
|
+
homepage: https://0xacab.org/sutty/wordpress-formatting
|
53
|
+
licenses:
|
54
|
+
- GPL-2.0
|
55
|
+
metadata:
|
56
|
+
bug_tracker_uri: https://0xacab.org/sutty/wordpress-formatting/issues
|
57
|
+
homepage_uri: https://0xacab.org/sutty/wordpress-formatting
|
58
|
+
source_code_uri: https://0xacab.org/sutty/wordpress-formatting
|
59
|
+
changelog_uri: https://0xacab.org/sutty/wordpress-formatting/-/blob/master/CHANGELOG.md
|
60
|
+
documentation_uri: https://rubydoc.info/gems/wordpress-formatting
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options:
|
63
|
+
- "--title"
|
64
|
+
- wordpress-formatting - Port of WordPress formatting functions
|
65
|
+
- "--main"
|
66
|
+
- README.md
|
67
|
+
- "--line-numbers"
|
68
|
+
- "--inline-source"
|
69
|
+
- "--quiet"
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 2.6.0
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubygems_version: 3.1.2
|
84
|
+
signing_key:
|
85
|
+
specification_version: 4
|
86
|
+
summary: Port of WordPress formatting functions
|
87
|
+
test_files: []
|