wordpress-formatting 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []