junebug 0.0.17 → 0.0.18

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