junebug 0.0.17 → 0.0.18

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.
@@ -0,0 +1,2 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/junebug'
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/../lib/junebug/mosquito"
1
+ require File.dirname(__FILE__) + "/../lib/junebug/ext/mosquito"
2
2
  require File.dirname(__FILE__) + "/../lib/junebug"
3
3
 
4
4
  Junebug.create
metadata CHANGED
@@ -3,19 +3,19 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: junebug
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.17
7
- date: 2006-11-19 00:00:00 -08:00
8
- summary: Junebug is a minimalist ruby wiki.
6
+ version: 0.0.18
7
+ date: 2006-11-21 00:00:00 -08:00
8
+ summary: Junebug is a minimalist ruby wiki running on Camping.
9
9
  require_paths:
10
10
  - lib
11
11
  email: tim.myrtle@gmail.com
12
- homepage: http://www.junebugwiki.com/
13
- rubyforge_project:
12
+ homepage: http://www.junebugwiki.com
13
+ rubyforge_project: junebug
14
14
  description: Junebug is a minimalist ruby wiki running on Camping.
15
15
  autorequire:
16
16
  default_executable:
17
17
  bindir: bin
18
- has_rdoc: false
18
+ has_rdoc: true
19
19
  required_ruby_version: !ruby/object:Gem::Version::Requirement
20
20
  requirements:
21
21
  - - ">"
@@ -29,54 +29,44 @@ post_install_message:
29
29
  authors:
30
30
  - Tim Myrtle
31
31
  files:
32
- - README
33
- - LICENSE
34
- - CHANGELOG
35
- - RELEASE_NOTES
32
+ - History.txt
33
+ - Manifest.txt
34
+ - README.txt
35
+ - RELEASE_NOTES.txt
36
36
  - Rakefile
37
- - lib/junebug
37
+ - bin/junebug
38
+ - deploy/Rakefile
39
+ - deploy/config.yml
40
+ - deploy/console
41
+ - deploy/static/images/feed-icon-14x14.png
42
+ - deploy/static/style/base.css
43
+ - deploy/static/style/yui/fonts.css
44
+ - deploy/static/style/yui/grids.css
45
+ - deploy/static/style/yui/reset.css
46
+ - deploy/wiki
47
+ - dump/junebug_pages.yml
38
48
  - lib/junebug.rb
39
- - lib/junebug/acts_as_versioned.rb
40
49
  - lib/junebug/config.rb
41
50
  - lib/junebug/controllers.rb
42
- - lib/junebug/diff.rb
51
+ - lib/junebug/ext/acts_as_versioned.rb
52
+ - lib/junebug/ext/diff.rb
53
+ - lib/junebug/ext/mosquito.rb
43
54
  - lib/junebug/generator.rb
44
55
  - lib/junebug/helpers.rb
45
56
  - lib/junebug/models.rb
46
- - lib/junebug/mosquito.rb
47
- - lib/junebug/redcloth
48
- - lib/junebug/redcloth.rb
49
- - lib/junebug/tasks
50
57
  - lib/junebug/tasks.rb
51
- - lib/junebug/views.rb
52
- - lib/junebug/redcloth/all_formats.rb
53
- - lib/junebug/redcloth/base.rb
54
- - lib/junebug/redcloth/docbook.rb
55
- - lib/junebug/redcloth/markdown.rb
56
- - lib/junebug/redcloth/textile.rb
57
58
  - lib/junebug/tasks/dump.rake
58
59
  - lib/junebug/tasks/update.rake
59
- - deploy/config.yml
60
- - deploy/console
61
- - deploy/dump
62
- - deploy/Rakefile
63
- - deploy/static
64
- - deploy/wiki
65
- - deploy/static/images
66
- - deploy/static/style
67
- - deploy/static/images/feed-icon-14x14.png
68
- - deploy/static/style/base.css
69
- - deploy/static/style/yui
70
- - deploy/static/style/yui/fonts.css
71
- - deploy/static/style/yui/grids.css
72
- - deploy/static/style/yui/reset.css
73
- - dump/junebug_pages.yml
74
- test_files:
75
- - test/fixtures
76
- - test/wiki_test.rb
60
+ - lib/junebug/version.rb
61
+ - lib/junebug/views.rb
62
+ - setup.rb
77
63
  - test/fixtures/junebug_page_versions.yml
78
64
  - test/fixtures/junebug_pages.yml
79
65
  - test/fixtures/junebug_users.yml
66
+ - test/test_helper.rb
67
+ - test/wiki_test.rb
68
+ test_files:
69
+ - test/wiki_test.rb
80
70
  rdoc_options: []
81
71
 
82
72
  extra_rdoc_files: []
data/CHANGELOG DELETED
@@ -1,88 +0,0 @@
1
- v0.0.17 2006-11-19
2
-
3
- * Quick bugfix for login redirects behind proxy
4
-
5
- v0.0.16 2006-11-19
6
-
7
- * Style tweaks
8
- * Login/logout redirects you back to the page you were on
9
-
10
- v0.0.15 2006-11-17
11
-
12
- * Loosen up mongrel requirements for windows users -- thanks deejay
13
- * Bugfix for static file issue #6536. Thanks zimbatm
14
- * Added css for wrapping pre text
15
- * Changed wikiword syntax to [[link]]
16
- * Unit testing improvements
17
- * Command line help
18
-
19
- v0.0.14 2006-11-14
20
-
21
- * Page title cleanup
22
- * Rake task reorg
23
- * Dump task
24
- * Added error checking to generator
25
-
26
- v0.0.13 2006-11-14
27
-
28
- * Link style improvement/simplification
29
- * Autolinking urls
30
- * use user.role to determine admin rights
31
- * is_admin?, logged_in?
32
-
33
- v0.0.12 2006-11-13
34
-
35
- * content div bugfix
36
-
37
- v0.0.11 2006-11-13
38
-
39
- * Added revert
40
- * Versioning bugfix
41
- * Changed delete operation
42
- * Added 'role' user field
43
-
44
- v0.0.10 2006-11-12
45
-
46
- * Submit bugfix
47
- * More unit tests
48
-
49
- v0.0.9 2006-11-10
50
-
51
- * Mosquito unit tests
52
-
53
- v0.0.8 2006-11-08
54
-
55
- * Style work
56
- * Add rss link to head
57
- * Stylesheet update rake task
58
-
59
- v0.0.7 2006-11-07
60
-
61
- * Redirect bugfix for proxied sites
62
-
63
- v0.0.6 2006-11-07
64
-
65
- * Delete pages
66
- * More style work
67
-
68
- v0.0.5 2006-11-06
69
-
70
- * Style cleanups
71
- * Security fix
72
- * Format test page
73
-
74
- v0.0.4 2006-11-05
75
-
76
- * Readonly pages
77
- * Start page
78
- * Bugfixes
79
-
80
- v0.0.3 2006-10-30
81
-
82
- * User accounts
83
- * Daemonize
84
- * Default page fixtures
85
-
86
- v0.0.2 2006-10-22
87
-
88
- * Initial release
data/LICENSE DELETED
@@ -1,18 +0,0 @@
1
- Copyright (c) 2006 Tim Myrtle
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy
4
- of this software and associated documentation files (the "Software"), to
5
- deal in the Software without restriction, including without limitation the
6
- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
- sell copies of the Software, and to permit persons to whom the Software is
8
- furnished to do so, subject to the following conditions:
9
-
10
- The above copyright notice and this permission notice shall be included in
11
- all copies or substantial portions of the Software.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
- THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README DELETED
@@ -1,65 +0,0 @@
1
- = Junebug: Minimalist Ruby Wiki
2
-
3
- Junebug is a minimalist wiki, running on Camping.
4
-
5
-
6
- == Status
7
-
8
- This is an alpha release. Use at your own risk. Please do not use this for anything important.
9
-
10
-
11
- == Dependencies
12
-
13
- * Ruby and rubygems
14
-
15
- * Sqlite3
16
-
17
- _why has set up a page describing how to get sqlite3 set up on ruby for various platforms: http://code.whytheluckystiff.net/camping/wiki/BeAlertWhenOnSqlite3
18
-
19
- Please follow the instructions _why has provided. In particular, make sure that you have _why's latest sqlite3-ruby gem installed.
20
-
21
-
22
- == Quickstart
23
-
24
- Install junebug
25
-
26
- > gem install junebug --include-dependencies
27
-
28
- To create your Junebug wiki:
29
-
30
- > junebug testwiki
31
-
32
- This creates a directory 'testwiki' with the necessary files.
33
-
34
- > cd testwiki
35
- > ruby wiki run
36
-
37
- View your new wiki at: http://localhost:3301
38
-
39
- Once everything seems to be running fine, you can set the wiki to run in the background. Hit ctrl-C to kill the wiki, and then type
40
-
41
- > ruby wiki start
42
-
43
- You can change default configuration (host, port, startpage, etc.. ) by editing the config.yml file. For the changes to take effect, just restart the wiki:
44
-
45
- > ruby wiki restart
46
-
47
-
48
- == Notes
49
-
50
- Starting and stopping the wiki:
51
-
52
- > ruby wiki start
53
- > ruby wiki stop
54
- > ruby wiki restart
55
- > ruby wiki run
56
-
57
- == Credits
58
-
59
- Thans to _why for camping http://code.whytheluckystiff.net/camping/wiki and his tepee wiki example which was the starting point for Junebug, and also to Chris Wanstrath for cheat http://cheat.errtheblog.com/ .
60
-
61
-
62
- == Contact
63
-
64
- Tim Myrtle
65
- tim.myrtle@gmail.com
@@ -1,5 +0,0 @@
1
- $:.unshift(File.dirname(__FILE__))
2
-
3
- require 'redcloth/base'
4
- require 'redcloth/textile'
5
- require 'redcloth/markdown'
@@ -1,4 +0,0 @@
1
- $:.unshift(File.dirname(__FILE__) + "/../")
2
-
3
- require 'redcloth'
4
- require 'redcloth/docbook'
@@ -1,674 +0,0 @@
1
- class RedCloth < String
2
-
3
- VERSION = '3.0.4'
4
- DEFAULT_RULES = [] # let each class add to this array
5
- TEXTILE_RULES = [:refs_textile, :block_textile_table, :block_textile_lists, :block_textile_defs,
6
- :block_textile_prefix, :inline_textile_image, :inline_textile_link,
7
- :inline_textile_code, :inline_textile_span, :glyphs_textile,
8
- :inline_textile_autolink_urls, :inline_textile_autolink_emails]
9
- MARKDOWN_RULES = [:refs_markdown, :block_markdown_setext, :block_markdown_atx, :block_markdown_rule,
10
- :block_markdown_bq, :block_markdown_lists,
11
- :inline_markdown_reflink, :inline_markdown_link]
12
- DOCBOOK_RULES = [:refs_docbook, :block_docbook_table, :block_docbook_lists, :block_docbook_simple_lists,
13
- :block_docbook_defs, :block_docbook_prefix, :inline_docbook_image, :inline_docbook_link,
14
- :inline_docbook_code, :inline_docbook_glyphs, :inline_docbook_span,
15
- :inline_docbook_wiki_words, :inline_docbook_wiki_links, :inline_docbook_autolink_urls,
16
- :inline_docbook_autolink_emails]
17
- @@escape_keyword ||= "redcloth"
18
-
19
- #
20
- # Two accessor for setting security restrictions.
21
- #
22
- # This is a nice thing if you're using RedCloth for
23
- # formatting in public places (e.g. Wikis) where you
24
- # don't want users to abuse HTML for bad things.
25
- #
26
- # If +:filter_html+ is set, HTML which wasn't
27
- # created by the Textile processor will be escaped.
28
- #
29
- # If +:filter_styles+ is set, it will also disable
30
- # the style markup specifier. ('{color: red}')
31
- #
32
- # If +:filter_classes+ is set, it will also disable
33
- # class attributes. ('!(classname)image!')
34
- #
35
- # If +:filter_ids+ is set, it will also disable
36
- # id attributes. ('!(classname#id)image!')
37
- #
38
- attr_accessor :filter_html, :filter_styles, :filter_classes, :filter_ids
39
-
40
- #
41
- # Accessor for toggling hard breaks.
42
- #
43
- # If +:hard_breaks+ is set, single newlines will
44
- # be converted to HTML break tags. This is the
45
- # default behavior for traditional RedCloth.
46
- #
47
- attr_accessor :hard_breaks
48
-
49
- # Accessor for toggling lite mode.
50
- #
51
- # In lite mode, block-level rules are ignored. This means
52
- # that tables, paragraphs, lists, and such aren't available.
53
- # Only the inline markup for bold, italics, entities and so on.
54
- #
55
- # r = RedCloth.new( "And then? She *fell*!", [:lite_mode] )
56
- # r.to_html
57
- # #=> "And then? She <strong>fell</strong>!"
58
- #
59
- attr_accessor :lite_mode
60
-
61
- #
62
- # Accessor for toggling span caps.
63
- #
64
- # Textile places `span' tags around capitalized
65
- # words by default, but this wreaks havoc on Wikis.
66
- # If +:no_span_caps+ is set, this will be
67
- # suppressed.
68
- #
69
- attr_accessor :no_span_caps
70
-
71
- #
72
- # Establishes the markup predence.
73
- #
74
- attr_accessor :rules
75
-
76
- # Returns a new RedCloth object, based on _string_ and
77
- # enforcing all the included _restrictions_.
78
- #
79
- # r = RedCloth.new( "h1. A <b>bold</b> man", [:filter_html] )
80
- # r.to_html
81
- # #=>"<h1>A &lt;b&gt;bold&lt;/b&gt; man</h1>"
82
- #
83
- def initialize( string, restrictions = [] )
84
- restrictions.each { |r| method( "#{ r }=" ).call( true ) }
85
- super( string )
86
- end
87
-
88
- #
89
- # Generates HTML from the Textile contents.
90
- #
91
- # r = RedCloth.new( "And then? She *fell*!" )
92
- # r.to_html( true )
93
- # #=>"And then? She <strong>fell</strong>!"
94
- #
95
- def to_html( *rules )
96
- rules = DEFAULT_RULES if rules.empty?
97
- # make our working copy
98
- text = self.dup
99
-
100
- return "" if text == ""
101
-
102
- @urlrefs = {}
103
- @shelf = []
104
- @rules = rules.collect do |rule|
105
- case rule
106
- when :markdown
107
- MARKDOWN_RULES
108
- when :textile
109
- TEXTILE_RULES
110
- else
111
- rule
112
- end
113
- end.flatten
114
-
115
- # standard clean up
116
- @pre_list = []
117
- pre_process text
118
- DEFAULT_RULES.each {|ruleset| send("#{ruleset}_pre_process", text) if private_methods.include? "#{ruleset}_pre_process"}
119
- incoming_entities text
120
- clean_white_space text
121
-
122
- # start processor
123
- no_textile text
124
- rip_offtags text
125
- hard_break text
126
- unless @lite_mode
127
- refs text
128
- blocks text
129
- end
130
- inline text
131
- smooth_offtags text
132
- retrieve text
133
-
134
- post_process text
135
- DEFAULT_RULES.each {|ruleset| send("#{ruleset}_post_process", text) if private_methods.include? "#{ruleset}_post_process"}
136
-
137
- clean_html text if filter_html
138
-
139
- return text.strip
140
-
141
- end
142
-
143
- #######
144
- private
145
- #######
146
- #
147
- # Regular expressions to convert to HTML.
148
- #
149
- LB = "0docbook0line0break0"
150
- NB = "0docbook0no0break0\n\n"
151
- A_HLGN = /(?:(?:<>|<|>|\=|[()]+)+)/
152
- A_VLGN = /[\-^~]/
153
- C_CLAS = '(?:\([^)]+\))'
154
- C_LNGE = '(?:\[[^\]]+\])'
155
- C_STYL = '(?:\{[^}]+\})'
156
- S_CSPN = '(?:\\\\\d+)'
157
- S_RSPN = '(?:/\d+)'
158
- A = "(?:#{A_HLGN}?#{A_VLGN}?|#{A_VLGN}?#{A_HLGN}?)"
159
- S = "(?:#{S_CSPN}?#{S_RSPN}|#{S_RSPN}?#{S_CSPN}?)"
160
- C = "(?:#{C_CLAS}?#{C_STYL}?#{C_LNGE}?|#{C_STYL}?#{C_LNGE}?#{C_CLAS}?|#{C_LNGE}?#{C_STYL}?#{C_CLAS}?)"
161
- PUNCT = Regexp::quote( '!"#$%&\'*+,-./:;=?@\\^_`|~' )
162
- PUNCT_NOQ = Regexp::quote( '!"#$&\',./:;=?@\\`|' )
163
- PUNCT_Q = Regexp::quote( '*-_+^~%' )
164
- HYPERLINK = '(\S+?)([^\w\s/;=\?]*?)(?=\s|<|$)'
165
-
166
- TABLE_RE = /^(?:caption ?\{(.*?)\}\. ?\n)?^(?:id ?\{(.*?)\}\. ?\n)?^(?:table(_?#{S}#{A}#{C})\. ?\n)?^(#{A}#{C}\.? ?\|.*?\|)(\n\n|\Z)/m
167
- LISTS_RE = /^([#*_0-9]+?#{C} .*?)$(?![^#*])/m
168
- LISTS_CONTENT_RE = /^([#*]+)([_0-9]*)(#{A}#{C}) (.*)$/m
169
- DEFS_RE = /^(-#{C}\s.*?\:\=.*?)$(?![^-])/m
170
- DEFS_CONTENT_RE = /^(-)(#{A}#{C})\s+(.*?):=(.*)$/m
171
- BACKTICK_CODE_RE = /(.*?)
172
- ```
173
- (?:\|(\w+?)\|)?
174
- (.*?[^\\])
175
- ```
176
- (.*?)/mx
177
- CODE_RE = /(.*?)
178
- @@?
179
- (?:\|(\w+?)\|)?
180
- (.*?[^\\])
181
- @@?
182
- (.*?)/x
183
- BLOCKS_GROUP_RE = /\n{2,}(?! )/m
184
- BLOCK_RE = /^(([a-z]+)(\d*))(#{A}#{C})\.(?::(\S+))? (.*)$/
185
- SETEXT_RE = /\A(.+?)\n([=-])[=-]* *$/m
186
- ATX_RE = /\A(\#{1,6}) # $1 = string of #'s
187
- [ ]*
188
- (.+?) # $2 = Header text
189
- [ ]*
190
- \#* # optional closing #'s (not counted)
191
- $/x
192
- LINK_RE = /
193
- ([\s\[{(]|[#{PUNCT}])? # $pre
194
- " # start
195
- (#{C}) # $atts
196
- ([^"]+?) # $text
197
- \s?
198
- (?:\(([^)]+?)\)(?="))? # $title
199
- ":
200
- ([^\s<]+?) # $url
201
- (\/)? # $slash
202
- ([^\w\/;]*?) # $post
203
- (?=<|\s|$)
204
- /x
205
- IMAGE_RE = /
206
- (<p>|.|^) # start of line?
207
- \! # opening
208
- (\<|\=|\>)? # optional alignment atts
209
- (#{C}) # optional style,class atts
210
- (?:\. )? # optional dot-space
211
- ([^\s(!]+?) # presume this is the src
212
- \s? # optional space
213
- (?:\(((?:[^\(\)]|\([^\)]+\))+?)\))? # optional title
214
- \! # closing
215
- (?::#{ HYPERLINK })? # optional href
216
- /x
217
-
218
- # Text markup tags, don't conflict with block tags
219
- SIMPLE_HTML_TAGS = [
220
- 'tt', 'b', 'i', 'big', 'small', 'em', 'strong', 'dfn', 'code',
221
- 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'br',
222
- 'br', 'map', 'q', 'sub', 'sup', 'span', 'bdo'
223
- ]
224
-
225
- QTAGS = [
226
- ['**', 'b'],
227
- ['*', 'strong'],
228
- ['??', 'cite', :limit],
229
- ['-', 'del', :limit],
230
- ['__', 'i'],
231
- ['_', 'em', :limit],
232
- ['%', 'span', :limit],
233
- ['+', 'ins', :limit],
234
- ['^', 'sup'],
235
- ['~', 'sub']
236
- ]
237
- QTAGS.collect! do |rc, ht, rtype|
238
- rcq = Regexp::quote rc
239
- re =
240
- case rtype
241
- when :limit
242
- /(\W)
243
- (#{rcq})
244
- (#{C})
245
- (?::(\S+?))?
246
- (\S.*?\S|\S)
247
- #{rcq}
248
- (?=\W)/x
249
- else
250
- /(#{rcq})
251
- (#{C})
252
- (?::(\S+))?
253
- (\S.*?\S|\S)
254
- #{rcq}/xm
255
- end
256
- escaped_re =
257
- case rtype
258
- when :limit
259
- /(\W)
260
- (#{@@escape_keyword}#{rcq})
261
- (#{C})
262
- (?::(\S+?))?
263
- (\S.*?\S|\S)
264
- #{rcq}#{@@escape_keyword}
265
- (?=\W)/x
266
- else
267
- /(#{@@escape_keyword}#{rcq})
268
- (#{C})
269
- (?::(\S+))?
270
- (\S.*?\S|\S)
271
- #{rcq}#{@@escape_keyword}/xm
272
- end
273
- [rc, ht, re, rtype, escaped_re]
274
- end
275
-
276
- # Elements to handle
277
- GLYPHS = [
278
- # [ /([^\s\[{(>])?\'([dmst]\b|ll\b|ve\b|\s|:|$)/, '\1&#8217;\2' ], # single closing
279
- [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)\'/, '\1&#8217;' ], # single closing
280
- [ /\'(?=[#{PUNCT_Q}]*(s\b|[\s#{PUNCT_NOQ}]))/, '&#8217;' ], # single closing
281
- [ /\'/, '&#8216;' ], # single opening
282
- # [ /([^\s\[{(])?"(\s|:|$)/, '\1&#8221;\2' ], # double closing
283
- [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)"/, '\1&#8221;' ], # double closing
284
- [ /"(?=[#{PUNCT_Q}]*[\s#{PUNCT_NOQ}])/, '&#8221;' ], # double closing
285
- [ /"/, '&#8220;' ], # double opening
286
- [ /\b( )?\.{3}/, '\1&#8230;' ], # ellipsis
287
- [ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '<acronym title="\2">\1</acronym>' ], # 3+ uppercase acronym
288
- [ /(^|[^"][>\s])([A-Z][A-Z0-9 ]+[A-Z0-9])([^<A-Za-z0-9]|$)/, '\1<span class="caps">\2</span>\3', :no_span_caps ], # 3+ uppercase caps
289
- [ /(\.\s)?\s?--\s?/, '\1&#8212;' ], # em dash
290
- [ /(^|\s)->(\s|$)/, ' &rarr; ' ], # right arrow
291
- [ /(^|\s)-(\s|$)/, ' &#8211; ' ], # en dash
292
- [ /(\d+) ?x ?(\d+)/, '\1&#215;\2' ], # dimension sign
293
- [ /\b ?[(\[]TM[\])]/i, '&#8482;' ], # trademark
294
- [ /\b ?[(\[]R[\])]/i, '&#174;' ], # registered
295
- [ /\b ?[(\[]C[\])]/i, '&#169;' ] # copyright
296
- ]
297
-
298
- H_ALGN_VALS = {
299
- '<' => 'left',
300
- '=' => 'center',
301
- '>' => 'right',
302
- '<>' => 'justify'
303
- }
304
-
305
- V_ALGN_VALS = {
306
- '^' => 'top',
307
- '-' => 'middle',
308
- '~' => 'bottom'
309
- }
310
-
311
- OFFTAGS = /(code|pre|kbd|notextile)/i
312
- OFFTAG_MATCH = /(?:(<\/#{ OFFTAGS }>)|(<#{ OFFTAGS }[^>]*>))(.*?)(?=<\/?#{ OFFTAGS }|\Z)/mi
313
- OFFTAG_OPEN = /<#{ OFFTAGS }/
314
- OFFTAG_CLOSE = /<\/?#{ OFFTAGS }/
315
-
316
- HASTAG_MATCH = /(<\/?\w[^\n]*?>)/m
317
- ALLTAG_MATCH = /(<\/?\w[^\n]*?>)|.*?(?=<\/?\w[^\n]*?>|$)/m
318
-
319
- def pre_process( text )
320
- text.gsub!( /={2}\`\`\`={2}/, "XXXpreformatted_backticksXXX" )
321
- end
322
-
323
- def post_process( text )
324
- text.gsub!( /XXXpreformatted_backticksXXX/, '```' )
325
- text.gsub!( LB, "\n" )
326
- text.gsub!( NB, "" )
327
- text.gsub!( /<\/?notextile>/, '' )
328
- text.gsub!( /x%x%/, '&#38;' )
329
- text << "</div>" if @div_atts
330
- end
331
-
332
- # Search and replace for glyphs (quotes, dashes, other symbols)
333
- def pgl( text )
334
- GLYPHS.each do |re, resub, tog|
335
- next if tog and method( tog ).call
336
- text.gsub! re, resub
337
- end
338
- end
339
-
340
- # Parses attribute lists and builds an HTML attribute string
341
- def pba( text_in, element = "" )
342
-
343
- return '' unless text_in
344
-
345
- style = []
346
- text = text_in.dup
347
- if element == 'td'
348
- colspan = $1 if text =~ /\\(\d+)/
349
- rowspan = $1 if text =~ /\/(\d+)/
350
- style << "vertical-align:#{ v_align( $& ) };" if text =~ A_VLGN
351
- end
352
-
353
- style << "#{ $1 };" if not filter_styles and
354
- text.sub!( /\{([^}]*)\}/, '' )
355
-
356
- lang = $1 if
357
- text.sub!( /\[([^)]+?)\]/, '' )
358
-
359
- cls = $1 if
360
- text.sub!( /\(([^()]+?)\)/, '' )
361
-
362
- style << "padding-left:#{ $1.length }em;" if
363
- text.sub!( /([(]+)/, '' )
364
-
365
- style << "padding-right:#{ $1.length }em;" if text.sub!( /([)]+)/, '' )
366
-
367
- style << "text-align:#{ h_align( $& ) };" if text =~ A_HLGN
368
-
369
- cls, id = $1, $2 if cls =~ /^(.*?)#(.*)$/
370
-
371
- atts = ''
372
- atts << " style=\"#{ style.join }\"" unless style.empty?
373
- atts << " class=\"#{ cls }\"" unless cls.to_s.empty? or filter_classes
374
- atts << " lang=\"#{ lang }\"" if lang
375
- atts << " id=\"#{ id }\"" if id and not filter_ids
376
- atts << " colspan=\"#{ colspan }\"" if colspan
377
- atts << " rowspan=\"#{ rowspan }\"" if rowspan
378
-
379
- atts
380
- end
381
-
382
- #
383
- # Flexible HTML escaping
384
- #
385
- def htmlesc( str, mode )
386
- str.gsub!( '&', '&amp;' )
387
- str.gsub!( '"', '&quot;' ) if mode != :NoQuotes
388
- str.gsub!( "'", '&#039;' ) if mode == :Quotes
389
- str.gsub!( '<', '&lt;')
390
- str.gsub!( '>', '&gt;')
391
- end
392
-
393
- def hard_break( text )
394
- text.gsub!( /(.)\n(?!\n|\Z| *([#*=]+(\s|$)|[{|]))/, "\\1<br />" ) if hard_breaks
395
- end
396
-
397
- def lT( text )
398
- text =~ /\#$/ ? 'o' : 'u'
399
- end
400
-
401
- BLOCK_GROUP_SPLITTER = "XXX_BLOCK_GROUP_XXX\n\n"
402
- def blocks( text, deep_code = false )
403
- @current_class ||= nil
404
-
405
- # Find all occurences of div(class). and process them as blocks
406
- text.gsub!( /^div\((.*?)\)\.\s*(.*?)(?=div\([^\)]+\)\.\s*)/m ) do |blk|
407
- block_class = (@current_class == $1) ? nil : %{ class=#{$1.inspect}}
408
- @current_class = $1
409
- BLOCK_GROUP_SPLITTER + ( ($2.strip.empty? || block_class.nil?) ? $2 : textile_p('div', block_class, nil, "\n\n#{$2.strip}\n\n") )
410
- end
411
-
412
- # Take care of the very last div
413
- text.sub!( /div\((.*?)\)\.\s*(.*)/m ) do |blk|
414
- block_class = (@current_class == $1) ? nil : %{ class=#{$1.inspect}}
415
- @current_class = $1
416
- BLOCK_GROUP_SPLITTER + ( ($2.strip.empty? || block_class.nil?) ? $2 : textile_p('div', block_class, nil, "\n\n#{$2.strip}\n\n") )
417
- end
418
-
419
- # Handle the text now that the placeholders for divs are set, splitting at BLOCK_GROUP_SPLITTER
420
- text.replace(text.strip.split(BLOCK_GROUP_SPLITTER.strip).map do |chunk|
421
- block_groups(chunk, deep_code)
422
- end.join)
423
- end
424
-
425
- def block_groups( text, deep_code = false )
426
- text.replace text.split( BLOCKS_GROUP_RE ).collect { |blk| blk(blk, deep_code) }.join("\n")
427
- end
428
-
429
- # Surrounds blocks with paragraphs and shelves them when necessary
430
- def blk( text, deep_code = false )
431
- return text if text =~ /<[0-9]+>/
432
-
433
- plain = text !~ /\A[#*> ]/
434
-
435
- # skip blocks that are complex HTML
436
- if text =~ /^<\/?(\w+).*>/ and not SIMPLE_HTML_TAGS.include? $1
437
- text
438
- else
439
- # search for indentation levels
440
- text.strip!
441
- if text.empty?
442
- text
443
- else
444
- code_blk = nil
445
- text.gsub!( /((?:\n(?:\n^ +[^\n]*)+)+)/m ) do |iblk|
446
- flush_left iblk
447
- blocks iblk, plain
448
- iblk.gsub( /^(\S)/, "\\1" )
449
- if plain
450
- code_blk = iblk; ""
451
- else
452
- iblk
453
- end
454
- end
455
- block_applied = 0
456
- @rules.each do |rule_name|
457
- block_applied += 1 if ( rule_name.to_s.match /^block_/ and method( rule_name ).call( text ) )
458
- end
459
- if block_applied.zero?
460
- if deep_code
461
- text = "\t<pre><code>#{ text }</code></pre>\n"
462
- else
463
- text = "\t<p>#{ text }</p>\n"
464
- end
465
- end
466
- # hard_break text
467
- text << "\n#{ code_blk }"
468
- end
469
- return text
470
- end
471
-
472
- end
473
-
474
- def refs( text )
475
- @rules.each do |rule_name|
476
- method( rule_name ).call( text ) if rule_name.to_s.match /^refs_/
477
- end
478
- end
479
-
480
- def check_refs( text )
481
- ret = @urlrefs[text.downcase] if text
482
- ret || [text, nil]
483
- end
484
-
485
- # Puts text in storage and returns is placeholder
486
- # e.g. shelve("some text") => <1>
487
- def shelve( val )
488
- @shelf << val
489
- " <#{ @shelf.length }>"
490
- end
491
-
492
- # Retrieves text from storage using its placeholder
493
- # e.g. retrieve("<1>") => "some text"
494
- def retrieve( text )
495
- @shelf.each_with_index do |r, i|
496
- text.gsub!( " <#{ i + 1 }>" ){|m| r }
497
- end
498
- end
499
-
500
- def incoming_entities( text )
501
- ## turn any incoming ampersands into a dummy character for now.
502
- ## This uses a negative lookahead for alphanumerics followed by a semicolon,
503
- ## implying an incoming html entity, to be skipped
504
-
505
- text.gsub!( /&(?![#a-z0-9]+;)/i, "x%x%" )
506
- end
507
-
508
- def clean_white_space( text )
509
- # normalize line breaks
510
- text.gsub!( /\r\n/, "\n" )
511
- text.gsub!( /\r/, "\n" )
512
- text.gsub!( /\t/, ' ' )
513
- text.gsub!( /^ +$/, '' )
514
- text.gsub!( /\n{3,}/, "\n\n" )
515
- text.gsub!( /"$/, "\" " )
516
-
517
- # if entire document is indented, flush
518
- # to the left side
519
- flush_left text
520
- end
521
-
522
- def flush_left( text )
523
- indt = 0
524
- if text =~ /^ /
525
- while text !~ /^ {#{indt}}\S/
526
- indt += 1
527
- end unless text.empty?
528
- if indt.nonzero?
529
- text.gsub!( /^ {#{indt}}/, '' )
530
- end
531
- end
532
- end
533
-
534
- def footnote_ref( text )
535
- text.gsub!( /\b\[([0-9]+?)\](\s)?/,
536
- '<sup><a href="#fn\1">\1</a></sup>\2' )
537
- end
538
-
539
- def rip_offtags( text )
540
- if text =~ /<.*>/
541
- ## strip and encode <pre> content
542
- codepre, used_offtags = 0, {}
543
- text.gsub!( OFFTAG_MATCH ) do |line|
544
- if $3
545
- offtag, aftertag = $4, $5
546
- codepre += 1
547
- used_offtags[offtag] = true
548
- if codepre - used_offtags.length > 0
549
- htmlesc( line, :NoQuotes ) unless used_offtags['notextile']
550
- @pre_list.last << line
551
- line = ""
552
- else
553
- htmlesc( aftertag, :NoQuotes ) if aftertag and not used_offtags['notextile']
554
- line = "<redpre##{ @pre_list.length }>"
555
- @pre_list << "#{ $3 }#{ aftertag }"
556
- end
557
- elsif $1 and codepre > 0
558
- if codepre - used_offtags.length > 0
559
- htmlesc( line, :NoQuotes ) unless used_offtags['notextile']
560
- @pre_list.last << line
561
- line = ""
562
- end
563
- codepre -= 1 unless codepre.zero?
564
- used_offtags = {} if codepre.zero?
565
- end
566
- line
567
- end
568
- end
569
- text
570
- end
571
-
572
- def smooth_offtags( text )
573
- unless @pre_list.empty?
574
- ## replace <pre> content
575
- text.gsub!( /<redpre#(\d+)>/ ) { @pre_list[$1.to_i] }
576
- end
577
- end
578
-
579
- def inline( text )
580
- [/^inline_/, /^glyphs_/].each do |meth_re|
581
- @rules.each do |rule_name|
582
- method( rule_name ).call( text ) if rule_name.to_s.match( meth_re )
583
- end
584
- end
585
- end
586
-
587
- def h_align( text )
588
- H_ALGN_VALS[text]
589
- end
590
-
591
- def v_align( text )
592
- V_ALGN_VALS[text]
593
- end
594
-
595
- # HTML cleansing stuff
596
- BASIC_TAGS = {
597
- 'a' => ['href', 'title'],
598
- 'img' => ['src', 'alt', 'title'],
599
- 'br' => [],
600
- 'i' => nil,
601
- 'u' => nil,
602
- 'b' => nil,
603
- 'pre' => nil,
604
- 'kbd' => nil,
605
- 'code' => ['lang'],
606
- 'cite' => nil,
607
- 'strong' => nil,
608
- 'em' => nil,
609
- 'ins' => nil,
610
- 'sup' => nil,
611
- 'sub' => nil,
612
- 'del' => nil,
613
- 'table' => nil,
614
- 'tr' => nil,
615
- 'td' => ['colspan', 'rowspan'],
616
- 'th' => nil,
617
- 'ol' => ['start'],
618
- 'ul' => nil,
619
- 'li' => nil,
620
- 'p' => nil,
621
- 'h1' => nil,
622
- 'h2' => nil,
623
- 'h3' => nil,
624
- 'h4' => nil,
625
- 'h5' => nil,
626
- 'h6' => nil,
627
- 'blockquote' => ['cite']
628
- }
629
-
630
- def clean_html( text, tags = BASIC_TAGS )
631
- text.gsub!( /<!\[CDATA\[/, '' )
632
- text.gsub!( /<(\/*)(\w+)([^>]*)>/ ) do
633
- raw = $~
634
- tag = raw[2].downcase
635
- if tags.has_key? tag
636
- pcs = [tag]
637
- tags[tag].each do |prop|
638
- ['"', "'", ''].each do |q|
639
- q2 = ( q != '' ? q : '\s' )
640
- if raw[3] =~ /#{prop}\s*=\s*#{q}([^#{q2}]+)#{q}/i
641
- attrv = $1
642
- next if (prop == 'src' or prop == 'href') and not attrv =~ %r{^(http|https|ftp):}
643
- pcs << "#{prop}=\"#{attrv.gsub('"', '\\"')}\""
644
- break
645
- end
646
- end
647
- end if tags[tag]
648
- "<#{raw[1]}#{pcs.join " "}>"
649
- else
650
- " "
651
- end
652
- end
653
- end
654
-
655
- AUTO_LINK_RE = /
656
- ( # leading text
657
- <\w+.*?>| # leading HTML tag, or
658
- [^=!:'"\/]| # leading punctuation, or
659
- ^ # beginning of line
660
- )
661
- (
662
- (?:http[s]?:\/\/)| # protocol spec, or
663
- (?:www\.) # www.*
664
- )
665
- (
666
- ([\w]+[=?&:%\/\.\~\-]*)* # url segment
667
- \w+[\/]? # url tail
668
- (?:\#\w*)? # trailing anchor
669
- )
670
- ([[:punct:]]|\s|<|$) # trailing text
671
- /x
672
-
673
- end
674
-