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 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,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'wordpress_formatting/wpautop'
4
+
5
+ module WordpressFormatting
6
+ end
@@ -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: []