Soks 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/LICENSE.txt +60 -0
  2. data/README.txt +65 -0
  3. data/bin/soks-create-wiki.rb +41 -0
  4. data/contrib/diff/lcs.rb +1105 -0
  5. data/contrib/diff/lcs/array.rb +21 -0
  6. data/contrib/diff/lcs/block.rb +51 -0
  7. data/contrib/diff/lcs/callbacks.rb +322 -0
  8. data/contrib/diff/lcs/change.rb +169 -0
  9. data/contrib/diff/lcs/hunk.rb +257 -0
  10. data/contrib/diff/lcs/ldiff.rb +226 -0
  11. data/contrib/diff/lcs/string.rb +19 -0
  12. data/contrib/diff_licence.txt +76 -0
  13. data/contrib/redcloth-2.0.11.rb +894 -0
  14. data/contrib/redcloth-3.0.1.rb +1019 -0
  15. data/contrib/redcloth_license.txt +27 -0
  16. data/lib/authenticators.rb +79 -0
  17. data/lib/soks-helpers.rb +321 -0
  18. data/lib/soks-model.rb +208 -0
  19. data/lib/soks-servlet.rb +125 -0
  20. data/lib/soks-utils.rb +80 -0
  21. data/lib/soks-view.rb +424 -0
  22. data/lib/soks.rb +19 -0
  23. data/template/attachment/logo.png +0 -0
  24. data/template/attachment/stylesheet.css +63 -0
  25. data/template/content/How%20to%20export%20a%20site%20from%20this%20wiki.textile +5 -0
  26. data/template/content/How%20to%20hack%20soks.textile +60 -0
  27. data/template/content/How%20to%20import%20a%20site%20from%20instiki.textile +13 -0
  28. data/template/content/Improving%20the%20style%20of%20this%20wiki.textile +30 -0
  29. data/template/content/Picture%20of%20a%20pair%20of%20soks.textile +1 -0
  30. data/template/content/Pointers%20on%20adjusting%20the%20settings.textile +39 -0
  31. data/template/content/Pointers%20on%20how%20to%20use%20this%20wiki.textile +21 -0
  32. data/template/content/Recent%20Changes%20to%20This%20Site.textile +203 -0
  33. data/template/content/Soks%20Licence.textile +64 -0
  34. data/template/content/home%20page.textile +18 -0
  35. data/template/start.rb +74 -0
  36. data/template/views/AttachmentPage_edit.rhtml +36 -0
  37. data/template/views/ImagePage_edit.rhtml +36 -0
  38. data/template/views/Page_content.rhtml +1 -0
  39. data/template/views/Page_edit.rhtml +34 -0
  40. data/template/views/Page_print.rhtml +5 -0
  41. data/template/views/Page_revisions.rhtml +18 -0
  42. data/template/views/Page_rss.rhtml +34 -0
  43. data/template/views/Page_search_results.rhtml +19 -0
  44. data/template/views/Page_view.rhtml +3 -0
  45. data/template/views/frame.rhtml +34 -0
  46. metadata +88 -0
@@ -0,0 +1,19 @@
1
+ #! /usr/env/bin ruby
2
+ #--
3
+ # Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
4
+ # adapted from:
5
+ # Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
6
+ # Smalltalk by Mario I. Wolczko <mario@wolczko.com>
7
+ # implements McIlroy-Hunt diff algorithm
8
+ #
9
+ # This program is free software. It may be redistributed and/or modified under
10
+ # the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
11
+ # Ruby licence.
12
+ #
13
+ # $Id: string.rb,v 1.2 2004/12/15 22:07:19 tamc Exp $
14
+ #++
15
+ # Includes Diff::LCS into String.
16
+
17
+ class String
18
+ include Diff::LCS
19
+ end
@@ -0,0 +1,76 @@
1
+ Diff::LCS README
2
+ ================
3
+ Diff::LCS is a port of Algorithm::Diff[1] that uses the McIlroy-Hunt
4
+ longest common subsequence (LCS) algorithm to compute intelligent
5
+ differences between two sequenced enumerable containers[2]. The
6
+ implementation is based on Mario I. Wolczko's[3] Smalltalk version (1.2,
7
+ 1993)[4] and Ned Konz's[5] Perl version (Algorithm::Diff)[6].
8
+
9
+ This release is version 1.1.2, fixing an htmldiff bug in 1.1.1. Version 1.1.0
10
+ added new features, including the ability to #patch and #unpatch changes as
11
+ well as a new contextual diff callback, Diff::LCS::ContextDiffCallbacks, that
12
+ should improve the context sensitivity of patching.
13
+
14
+ Using this module is quite simple. By default, Diff::LCS does not extend
15
+ objects with the Diff::LCS interface, but will be called as if it were a
16
+ function:
17
+
18
+ require 'diff/lcs'
19
+
20
+ seq1 = %w(a b c e h j l m n p)
21
+ seq2 = %w(b c d e f j k l m r s t)
22
+
23
+ lcs = Diff::LCS.LCS(seq1, seq2)
24
+ diffs = Diff::LCS.diff(seq1, seq2)
25
+ sdiff = Diff::LCS.sdiff(seq1, seq2)
26
+ seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
27
+ bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
28
+ seq2 == Diff::LCS.patch!(seq1, diffs)
29
+ seq1 == Diff::LCS.unpatch!(seq2, diffs)
30
+ seq2 == Diff::LCS.patch!(seq1, sdiff)
31
+ seq1 == Diff::LCS.unpatch!(seq2, sdiff)
32
+
33
+ Objects can be extended with Diff::LCS:
34
+
35
+ seq1.extend(Diff::LCS)
36
+ lcs = seq1.lcs(seq2)
37
+ diffs = seq1.diff(seq2)
38
+ sdiff = seq1.sdiff(seq2)
39
+ seq = seq1.traverse_sequences(seq2, callback_obj)
40
+ bal = seq1.traverse_balanced(seq2, callback_obj)
41
+ seq2 == seq1.patch!(diffs)
42
+ seq1 == seq2.unpatch!(diffs)
43
+ seq2 == seq1.patch!(sdiff)
44
+ seq1 == seq2.unpatch!(sdiff)
45
+
46
+ By requiring 'diff/lcs/array' or 'diff/lcs/string', Array or String will
47
+ be extended for use this way.
48
+
49
+ Copyright
50
+ =========
51
+ # Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
52
+ # adapted from:
53
+ # Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
54
+ # Smalltalk by Mario I. Wolczko <mario@wolczko.com>
55
+ # implements McIlroy-Hunt diff algorithm
56
+ #
57
+ # This program is free software. It may be redistributed and/or modified
58
+ # under the terms of the GPL version 2 (or later), the Perl Artistic
59
+ # licence, or the Ruby licence.
60
+ #
61
+ # $Id: diff_licence.txt,v 1.1.1.1 2004/12/15 17:50:25 tamc Exp $
62
+
63
+ Footnotes
64
+ =========
65
+ [1] This library is called Diff::LCS because there are multiple
66
+ Ruby libraries called Algorithm::Diff maintained by other authors.
67
+ [2] By sequenced enumerable, I mean that the order of enumeration is
68
+ predictable and consistent for the same set of data. While it is
69
+ theoretically possible to generate a diff for unordereded hash, it
70
+ will only be meaningful if the enumeration of the hashes is
71
+ consistent. In general, this will mean that containers that behave
72
+ like String or Array will perform best.
73
+ [3] mario@wolczko.com
74
+ [4] ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
75
+ [5] perl@bike-nomad.com
76
+ [6] http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/
@@ -0,0 +1,894 @@
1
+ # vim:ts=4:sw=4:
2
+ # = RedCloth - Textile for Ruby
3
+ #
4
+ # Homepage:: http://whytheluckystiff.net/ruby/redcloth/
5
+ # Author:: why the lucky stiff (http://whytheluckystiff.net/)
6
+ # Copyright:: (c) 2004 why the lucky stiff (and his puppet organizations.)
7
+ # License:: BSD
8
+ #
9
+ # (see http://hobix.com/textile/ for a Textile Reference.)
10
+ #
11
+ # Based on (and also inspired by) both:
12
+ #
13
+ # PyTextile: http://diveintomark.org/projects/textile/textile.py.txt
14
+ # Textism for PHP: http://www.textism.com/tools/textile/
15
+ #
16
+ #
17
+
18
+ class String
19
+ #
20
+ # Flexible HTML escaping
21
+ #
22
+ def htmlesc!( mode )
23
+ gsub!( '&', '&amp;' )
24
+ gsub!( '"', '&quot;' ) if mode != :NoQuotes
25
+ gsub!( "'", '&#039;' ) if mode == :Quotes
26
+ gsub!('<', '&lt;')
27
+ gsub!('>', '&gt;')
28
+ end
29
+ end
30
+
31
+ # = RedCloth
32
+ #
33
+ # RedCloth is a Ruby library for converting Textile
34
+ # into HTML.
35
+ #
36
+ # == What is Textile?
37
+ #
38
+ # Textile is a simple formatting style for text
39
+ # documents, loosely based on some HTML conventions.
40
+ #
41
+ # == Sample Textile Text
42
+ #
43
+ # h2. This is a title
44
+ #
45
+ # h3. This is a subhead
46
+ #
47
+ # This is a bit of paragraph.
48
+ #
49
+ # bq. This is a blockquote.
50
+ #
51
+ # = Writing Textile
52
+ #
53
+ # A Textile document consists of paragraphs. Paragraphs
54
+ # can be specially formatted by adding a small instruction
55
+ # to the beginning of the paragraph.
56
+ #
57
+ # h[n]. Header of size [n].
58
+ # bq. Blockquote.
59
+ # # Numeric list.
60
+ # * Bulleted list.
61
+ #
62
+ # == Quick Phrase Modifiers
63
+ #
64
+ # Quick phrase modifiers are also included, to allow formatting
65
+ # of small portions of text within a paragraph.
66
+ #
67
+ # \_emphasis\_
68
+ # \_\_italicized\_\_
69
+ # \*strong\*
70
+ # \*\*bold\*\*
71
+ # ??citation??
72
+ # -deleted text-
73
+ # +inserted text+
74
+ # ^superscript^
75
+ # ~subscript~
76
+ # @code@
77
+ # %(classname)span%
78
+ #
79
+ # ==notextile== (leave text alone)
80
+ #
81
+ # == Links
82
+ #
83
+ # To make a hypertext link, put the link text in "quotation
84
+ # marks" followed immediately by a colon and the URL of the link.
85
+ #
86
+ # Optional: text in (parentheses) following the link text,
87
+ # but before the closing quotation mark, will become a Title
88
+ # attribute for the link, visible as a tool tip when a cursor is above it.
89
+ #
90
+ # Example:
91
+ #
92
+ # "This is a link (This is a title) ":http://www.textism.com
93
+ #
94
+ # Will become:
95
+ #
96
+ # <a href="http://www.textism.com" title="This is a title">This is a link</a>
97
+ #
98
+ # == Images
99
+ #
100
+ # To insert an image, put the URL for the image inside exclamation marks.
101
+ #
102
+ # Optional: text that immediately follows the URL in (parentheses) will
103
+ # be used as the Alt text for the image. Images on the web should always
104
+ # have descriptive Alt text for the benefit of readers using non-graphical
105
+ # browsers.
106
+ #
107
+ # Optional: place a colon followed by a URL immediately after the
108
+ # closing ! to make the image into a link.
109
+ #
110
+ # Example:
111
+ #
112
+ # !http://www.textism.com/common/textist.gif(Textist)!
113
+ #
114
+ # Will become:
115
+ #
116
+ # <img src="http://www.textism.com/common/textist.gif" alt="Textist" />
117
+ #
118
+ # With a link:
119
+ #
120
+ # !/common/textist.gif(Textist)!:http://textism.com
121
+ #
122
+ # Will become:
123
+ #
124
+ # <a href="http://textism.com"><img src="/common/textist.gif" alt="Textist" /></a>
125
+ #
126
+ # == Defining Acronyms
127
+ #
128
+ # HTML allows authors to define acronyms via the tag. The definition appears as a
129
+ # tool tip when a cursor hovers over the acronym. A crucial aid to clear writing,
130
+ # this should be used at least once for each acronym in documents where they appear.
131
+ #
132
+ # To quickly define an acronym in Textile, place the full text in (parentheses)
133
+ # immediately following the acronym.
134
+ #
135
+ # Example:
136
+ #
137
+ # ACLU(American Civil Liberties Union)
138
+ #
139
+ # Will become:
140
+ #
141
+ # <acronym title="American Civil Liberties Union">ACLU</acronym>
142
+ #
143
+ # == Adding Tables
144
+ #
145
+ # In Textile, simple tables can be added by seperating each column by
146
+ # a pipe.
147
+ #
148
+ # |a|simple|table|row|
149
+ # |And|Another|table|row|
150
+ #
151
+ # Attributes are defined by style definitions in parentheses.
152
+ #
153
+ # table(border:1px solid black).
154
+ # (background:#ddd;color:red). |{}| | | |
155
+ #
156
+ # == Using RedCloth
157
+ #
158
+ # RedCloth is simply an extension of the String class, which can handle
159
+ # Textile formatting. Use it like a String and output HTML with its
160
+ # RedCloth#to_html method.
161
+ #
162
+ # doc = RedCloth.new "
163
+ #
164
+ # h2. Test document
165
+ #
166
+ # Just a simple test."
167
+ #
168
+ # puts doc.to_html
169
+
170
+ class RedCloth < String
171
+
172
+ VERSION = '2.0.11'
173
+
174
+ #
175
+ # Two accessor for setting security restrictions.
176
+ #
177
+ # This is a nice thing if you're using RedCloth for
178
+ # formatting in public places (e.g. Wikis) where you
179
+ # don't want users to abuse HTML for bad things.
180
+ #
181
+ # If +:filter_html+ is set, HTML which wasn't
182
+ # created by the Textile processor will be escaped.
183
+ #
184
+ # If +:filter_styles+ is set, it will also disable
185
+ # the style markup specifier. ('{color: red}')
186
+ #
187
+ attr_accessor :filter_html, :filter_styles
188
+
189
+ #
190
+ # Accessor for toggling line folding.
191
+ #
192
+ # If +:fold_lines+ is set, single newlines will
193
+ # not be converted to break tags.
194
+ #
195
+ attr_accessor :fold_lines
196
+
197
+ #
198
+ # Returns a new RedCloth object, based on _string_ and
199
+ # enforcing all the included _restrictions_.
200
+ #
201
+ # r = RedCloth.new( "h1. A <b>bold</b> man", [:filter_html] )
202
+ # r.to_html
203
+ # #=>"<h1>A &lt;b&gt;bold&lt;/b&gt; man</h1>"
204
+ #
205
+ def initialize( string, restrictions = [] )
206
+ @lite = false
207
+ restrictions.each { |r| method( "#{ r }=" ).call( true ) }
208
+ super( string )
209
+ end
210
+
211
+ #
212
+ # Generates HTML from the Textile contents. The _lite_ flag
213
+ # may be used to honor only inline markup, ignoring lists, tables,
214
+ # and block formatting.
215
+ #
216
+ # r = RedCloth.new( "And then? She *fell*!" )
217
+ # r.to_html( true )
218
+ # #=>"And then? She <strong>fell</strong>!"
219
+ #
220
+ def to_html( lite = nil )
221
+
222
+ @lite = lite unless lite.nil?
223
+
224
+ # make our working copy
225
+ text = self.dup
226
+
227
+ @urlrefs = {}
228
+ @shelf = []
229
+
230
+ incoming_entities text
231
+ ## encode_entities text
232
+ ## fix_entities text
233
+ clean_white_space text
234
+
235
+ get_refs text
236
+
237
+ no_textile text
238
+
239
+ inline text
240
+
241
+ unless @lite
242
+ fold text
243
+ block text
244
+ end
245
+
246
+ retrieve text
247
+
248
+ text.gsub!( /<\/?notextile>/, '' )
249
+ text.gsub!( /x%x%/, '&#38;' )
250
+ text.gsub!( /<br \/>/, "<br />\n" )
251
+ text.strip!
252
+ text
253
+
254
+ end
255
+
256
+ #######
257
+ private
258
+ #######
259
+ #
260
+ # Mapping of 8-bit ASCII codes to HTML numerical entity equivalents.
261
+ # (from PyTextile)
262
+ #
263
+ TEXTILE_TAGS =
264
+
265
+ [[128, 8364], [129, 0], [130, 8218], [131, 402], [132, 8222], [133, 8230],
266
+ [134, 8224], [135, 8225], [136, 710], [137, 8240], [138, 352], [139, 8249],
267
+ [140, 338], [141, 0], [142, 0], [143, 0], [144, 0], [145, 8216], [146, 8217],
268
+ [147, 8220], [148, 8221], [149, 8226], [150, 8211], [151, 8212], [152, 732],
269
+ [153, 8482], [154, 353], [155, 8250], [156, 339], [157, 0], [158, 0], [159, 376]].
270
+
271
+ collect! do |a, b|
272
+ [a.chr, ( b.zero? and "" or "&#{ b };" )]
273
+ end
274
+
275
+ #
276
+ # Regular expressions to convert to HTML.
277
+ #
278
+ A_HLGN = /(?:(?:<>|<|>|\=|[()]+)+)/
279
+ A_VLGN = /[\-^~]/
280
+ C_CLAS = '(?:\([^)]+\))'
281
+ C_LNGE = '(?:\[[^\]]+\])'
282
+ C_STYL = '(?:\{[^}]+\})'
283
+ S_CSPN = '(?:\\\\\d+)'
284
+ S_RSPN = '(?:/\d+)'
285
+ A = "(?:#{A_HLGN}?#{A_VLGN}?|#{A_VLGN}?#{A_HLGN}?)"
286
+ S = "(?:#{S_CSPN}?#{S_RSPN}|#{S_RSPN}?#{S_CSPN}?)"
287
+ C = "(?:#{C_CLAS}?#{C_STYL}?#{C_LNGE}?|#{C_STYL}?#{C_LNGE}?#{C_CLAS}?|#{C_LNGE}?#{C_STYL}?#{C_CLAS}?)"
288
+ # PUNCT = Regexp::quote( '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' )
289
+ PUNCT = Regexp::quote( '!"#$%&\'*+,-./:;=?@\\^_`|~' )
290
+ HYPERLINK = '(\S+?)([^\w\s/;=\?]*?)(\s|$)'
291
+
292
+ GLYPHS = [
293
+ # [ /([^\s\[{(>])?\'([dmst]\b|ll\b|ve\b|\s|:|$)/, '\1&#8217;\2' ], # single closing
294
+ [ /([^\s\[{(>])\'/, '\1&#8217;' ], # single closing
295
+ [ /\'(?=\s|s\b|[#{PUNCT}])/, '&#8217;' ], # single closing
296
+ [ /\'/, '&#8216;' ], # single opening
297
+ # [ /([^\s\[{(])?"(\s|:|$)/, '\1&#8221;\2' ], # double closing
298
+ [ /([^\s\[{(>])"/, '\1&#8221;' ], # double closing
299
+ [ /"(?=\s|[#{PUNCT}])/, '&#8221;' ], # double closing
300
+ [ /"/, '&#8220;' ], # double opening
301
+ [ /\b( )?\.{3}/, '\1&#8230;' ], # ellipsis
302
+ [ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '<acronym title="\2">\1</acronym>' ], # 3+ uppercase acronym
303
+ [ /(^|[^"][>\s])([A-Z][A-Z0-9 ]{2,})([^<a-z0-9]|$)/, '\1<span class="caps">\2</span>\3' ], # 3+ uppercase caps
304
+ [ /(\.\s)?\s?--\s?/, '\1&#8212;' ], # em dash
305
+ [ /\s->\s/, ' &rarr; ' ], # en dash
306
+ [ /\s-\s/, ' &#8211; ' ], # en dash
307
+ [ /(\d+) ?x ?(\d+)/, '\1&#215;\2' ], # dimension sign
308
+ [ /\b ?[(\[]TM[\])]/i, '&#8482;' ], # trademark
309
+ [ /\b ?[(\[]R[\])]/i, '&#174;' ], # registered
310
+ [ /\b ?[(\[]C[\])]/i, '&#169;' ] # copyright
311
+ ]
312
+
313
+ I_ALGN_VALS = {
314
+ '<' => 'left',
315
+ '=' => 'center',
316
+ '>' => 'right'
317
+ }
318
+
319
+ H_ALGN_VALS = {
320
+ '<' => 'left',
321
+ '=' => 'center',
322
+ '>' => 'right',
323
+ '<>' => 'justify'
324
+ }
325
+
326
+ V_ALGN_VALS = {
327
+ '^' => 'top',
328
+ '-' => 'middle',
329
+ '~' => 'bottom'
330
+ }
331
+
332
+ QTAGS = [
333
+ ['**', 'b'],
334
+ ['*', 'strong'],
335
+ ['??', 'cite'],
336
+ ['-', 'del'],
337
+ ['__', 'i'],
338
+ ['_', 'em'],
339
+ ['%', 'span'],
340
+ ['+', 'ins'],
341
+ ['^', 'sup'],
342
+ ['~', 'sub']
343
+ ].collect do |rc, ht|
344
+ ttr = Regexp.quote(rc)
345
+ punct = PUNCT.sub( Regexp::quote(rc), '' )
346
+ re = /(^|[\s\>#{punct}{(\[])
347
+ #{ttr}
348
+ (#{C})
349
+ (?::(\S+?))?
350
+ ([^\s#{ttr}]+?(?:[^\n]|\n(?!\n))*?)
351
+ ([#{punct}]*?)
352
+ #{ttr}
353
+ (?=[\s\])}<#{punct}]|$)/xm
354
+ [re, ht]
355
+ end
356
+
357
+ def pgl( text )
358
+ GLYPHS.each do |re, resub|
359
+ text.gsub! re, resub
360
+ end
361
+ end
362
+
363
+ def pba( text_in, element = "" )
364
+
365
+ return '' unless text_in
366
+
367
+ style = []
368
+ text = text_in.dup
369
+ if element == 'td'
370
+ colspan = $1 if text =~ /\\(\d+)/
371
+ rowspan = $1 if text =~ /\/(\d+)/
372
+ style << "vertical-align:#{ v_align( $& ) };" if text =~ A_VLGN
373
+ end
374
+
375
+ style << "#{ $1 };" if not @filter_styles and
376
+ text.sub!( /\{([^}]*)\}/, '' )
377
+
378
+ lang = $1 if
379
+ text.sub!( /\[([^)]+?)\]/, '' )
380
+
381
+ cls = $1 if
382
+ text.sub!( /\(([^()]+?)\)/, '' )
383
+
384
+ style << "padding-left:#{ $1.length }em;" if
385
+ text.sub!( /([(]+)/, '' )
386
+
387
+ style << "padding-right:#{ $1.length }em;" if text.sub!( /([)]+)/, '' )
388
+
389
+ style << "text-align:#{ h_align( $& ) };" if text =~ A_HLGN
390
+
391
+ cls, id = $1, $2 if cls =~ /^(.*?)#(.*)$/
392
+
393
+ atts = ''
394
+ atts << " style=\"#{ style.join }\"" unless style.empty?
395
+ atts << " class=\"#{ cls }\"" unless cls.to_s.empty?
396
+ atts << " lang=\"#{ lang }\"" if lang
397
+ atts << " id=\"#{ id }\"" if id
398
+ atts << " colspan=\"#{ colspan }\"" if colspan
399
+ atts << " rowspan=\"#{ rowspan }\"" if rowspan
400
+
401
+ atts
402
+ end
403
+
404
+ TABLE_RE = /^(?:table(_?#{S}#{A}#{C})\. ?\n)?^(#{A}#{C}\.? ?\|.*?\|)(\n\n|\Z)/m
405
+
406
+ def table( text )
407
+ text.gsub!( TABLE_RE ) do |matches|
408
+
409
+ tatts, fullrow = $~[1..2]
410
+ tatts = pba( tatts, 'table' )
411
+ rows = []
412
+
413
+ fullrow.
414
+ split( /\|$/m ).
415
+ delete_if { |x| x.empty? }.
416
+ each do |row|
417
+
418
+ ratts, row = pba( $1, 'tr' ), $2 if row =~ /^(#{A}#{C}\. )(.*)/m
419
+
420
+ cells = []
421
+ row.split( '|' ).each do |cell|
422
+ ctyp = 'd'
423
+ ctyp = 'h' if cell =~ /^_/
424
+
425
+ catts = ''
426
+ catts, cell = pba( $1, 'td' ), $2 if cell =~ /^(_?#{S}#{A}#{C}\. )(.*)/
427
+
428
+ unless cell.strip.empty?
429
+ cells << "\t\t\t<t#{ ctyp }#{ catts }>#{ cell }</t#{ ctyp }>"
430
+ end
431
+ end
432
+ rows << "\t\t<tr#{ ratts }>\n#{ cells.join( "\n" ) }\n\t\t</tr>"
433
+ end
434
+ "\t<table#{ tatts }>\n#{ rows.join( "\n" ) }\n\t</table>\n\n"
435
+ end
436
+ end
437
+
438
+ LISTS_RE = /^([#*]+?#{C} .*?)$(?![^#*])/m
439
+ LISTS_CONTENT_RE = /^([#*]+)(#{A}#{C}) (.*)$/m
440
+
441
+ def lists( text )
442
+ text.gsub!( LISTS_RE ) do |match|
443
+ lines = match.split( /\n/ )
444
+ last_line = -1
445
+ depth = []
446
+ lines.each_with_index do |line, line_id|
447
+ if line =~ LISTS_CONTENT_RE
448
+ tl,atts,content = $~[1..3]
449
+ if depth.last
450
+ if depth.last.length > tl.length
451
+ (depth.length - 1).downto(0) do |i|
452
+ break if depth[i].length == tl.length
453
+ lines[line_id - 1] << "</li>\n\t</#{ lT( depth[i] ) }l>\n\t"
454
+ depth.pop
455
+ end
456
+ end
457
+ if depth.last.length == tl.length
458
+ lines[line_id - 1] << '</li>'
459
+ end
460
+ end
461
+ unless depth.last == tl
462
+ depth << tl
463
+ atts = pba( atts )
464
+ lines[line_id] = "\t<#{ lT(tl) }l#{ atts }>\n\t<li>#{ content }"
465
+ else
466
+ lines[line_id] = "\t\t<li>#{ content }"
467
+ end
468
+ last_line = line_id
469
+
470
+ elsif line =~ /^\s+\S/
471
+ last_line = line_id
472
+ elsif line_id - last_line < 2 and line =~ /^\S/
473
+ last_line = line_id
474
+ end
475
+ if line_id - last_line > 1 or line_id == lines.length - 1
476
+ depth.delete_if do |v|
477
+ lines[last_line] << "</li>\n\t</#{ lT( v ) }l>"
478
+ end
479
+ end
480
+ end
481
+ lines.join( "\n" )
482
+ end
483
+ end
484
+
485
+ def lT( text )
486
+ text =~ /\#$/ ? 'o' : 'u'
487
+ end
488
+
489
+ def fold( text )
490
+ text.gsub!( /(.+)\n(?![#*\s|])/, "\\1#{ @fold_lines ? ' ' : '<br />' }" )
491
+ end
492
+
493
+ BLOCK_RE = ['bq','h[1-6]','fn\d+','p'].collect!{|stag|
494
+ [stag,
495
+ /^(#{ stag })(#{A}#{C})\.(?::(\S+))? (.*)$/]
496
+ }
497
+
498
+ def block( text )
499
+ pre = false
500
+ find = ['bq','h[1-6]','fn\d+','p']
501
+
502
+ lines = text.split( /\n/ ) + [' ']
503
+ new_text =
504
+ lines.collect do |line|
505
+ pre = true if line =~ /<(pre|notextile)[^>]*>/i
506
+ BLOCK_RE.each do |stag, ctag|
507
+ line.gsub!( ctag ) do |m|
508
+ tag,atts,cite,content = $~[1..4]
509
+
510
+ atts = pba( atts )
511
+
512
+ if tag =~ /fn(\d+)/
513
+ tag = 'p';
514
+ atts << " id=\"fn#{ $1 }\""
515
+ content = "<sup>#{ $1 }</sup> #{ content }"
516
+ end
517
+
518
+ start = "\t<#{ tag }"
519
+ tend = "</#{ tag }>"
520
+
521
+ if tag == "bq"
522
+ cite = check_refs( cite )
523
+ cite = " cite=\"#{ cite }\"" if cite
524
+ start = "\t<blockquote#{ cite }>\n\t\t<p";
525
+ tend = "</p>\n\t</blockquote>";
526
+ end
527
+
528
+ "#{ start }#{ atts }>#{ content }#{ tend }"
529
+ end unless pre
530
+ end
531
+
532
+ line.gsub!( /^(?!\t|<\/?div|<\/?pre|<\/?notextile|<\/?code|$| )(.*)/, "\t<p>\\1</p>" ) unless pre
533
+
534
+ line.gsub!( "<br />", "\n" ) if pre
535
+ pre = false if line =~ /<\/(pre|notextile)>/i
536
+
537
+ line
538
+ end.join( "\n" )
539
+ text.replace( new_text )
540
+ end
541
+
542
+ def span( text )
543
+ QTAGS.each do |ttr, ht|
544
+ text.gsub!(ttr) do |m|
545
+
546
+ start,atts,cite,content,tend = $~[1..5]
547
+ atts = pba( atts )
548
+ atts << " cite=\"#{ cite }\"" if cite
549
+
550
+ "#{ start }<#{ ht }#{ atts }>#{ content }#{ tend }</#{ ht }>"
551
+
552
+ end
553
+ end
554
+ end
555
+
556
+ LINK_RE = /
557
+ ([\s\[{(]|[#{PUNCT}])? # $pre
558
+ " # start
559
+ (#{C}) # $atts
560
+ ([^"]+?) # $text
561
+ \s?
562
+ (?:\(([^)]+?)\)(?="))? # $title
563
+ ":
564
+ (\S+?) # $url
565
+ (\/)? # $slash
566
+ ([^\w\/;]*?) # $post
567
+ (?=<|\s|$)
568
+ /x
569
+
570
+ def links( text )
571
+ text.gsub!( LINK_RE ) do |m|
572
+ pre,atts,text,title,url,slash,post = $~[1..7]
573
+
574
+ url = check_refs( url )
575
+
576
+ atts = pba( atts )
577
+ atts << " title=\"#{ title }\"" if title
578
+ atts = shelve( atts ) if atts
579
+
580
+ "#{ pre }<a href=\"#{ url }#{ slash }\"#{ atts }>#{ text }</a>#{ post }"
581
+ end
582
+ end
583
+
584
+ REFS_RE = /(^|\s)\[(.+?)\]((?:http:\/\/|javascript:|ftp:\/\/|\/)\S+?)(?=\s|$)/
585
+
586
+ def get_refs( text )
587
+ text.gsub!( REFS_RE ) do |m|
588
+ flag, url = $~[2..3]
589
+ @urlrefs[flag] = url
590
+ nil
591
+ end
592
+ end
593
+
594
+ def check_refs( text )
595
+ @urlrefs[text] || text
596
+ end
597
+
598
+ IMAGE_RE = /
599
+ \! # opening
600
+ (\<|\=|\>)? # optional alignment atts
601
+ (#{C}) # optional style,class atts
602
+ (?:\. )? # optional dot-space
603
+ ([^\s(!]+?) # presume this is the src
604
+ \s? # optional space
605
+ (?:\(((?:[^\(\)]|\([^\)]+\))+?)\))? # optional title
606
+ \! # closing
607
+ (?::#{ HYPERLINK })? # optional href
608
+ /x
609
+
610
+ def image( text )
611
+ text.gsub!( IMAGE_RE ) do |m|
612
+ algn,atts,url,title,href,href_a1,href_a2 = $~[1..7]
613
+ atts = pba( atts )
614
+ atts << " align=\"#{ i_align( algn ) }\"" if algn
615
+ atts << " title=\"#{ title }\"" if title
616
+ atts << " alt=\"#{ title }\""
617
+ # size = @getimagesize($url);
618
+ # if($size) $atts.= " $size[3]";
619
+
620
+ href = check_refs( href ) if href
621
+ url = check_refs( url )
622
+ atts << " border=\"0\"" if href
623
+
624
+ out = ''
625
+ out << "<a href=\"#{ href }\">" if href
626
+ out << "<img src=\"#{ url }\"#{ atts } />"
627
+ out << "</a>#{ href_a1 }#{ href_a2 }" if href
628
+
629
+ out
630
+ end
631
+ end
632
+
633
+ CODE_RE = /
634
+ (^|[\s>#{PUNCT}{(\[]) # 1 open bracket?
635
+ @ # opening
636
+ (?:\|(\w+?)\|)? # 2 language
637
+ (\S(?:[^\n]|\n(?!\n))*?) # 3 code
638
+ @ # closing
639
+ (?=[\s\]}\)<#{PUNCT}]|$) # 4 closing bracket?
640
+ /x
641
+
642
+ def code( text )
643
+ text.gsub!( CODE_RE ) do |m|
644
+ before,lang,code,after = $~[1..4]
645
+ lang = " language=\"#{ lang }\"" if lang
646
+ "#{ before }<code#{ lang }>#{ code }</code>#{ after }"
647
+ end
648
+ end
649
+
650
+ def shelve( val )
651
+ @shelf << val
652
+ " <#{ @shelf.length }>"
653
+ end
654
+
655
+ def retrieve( text )
656
+ @shelf.each_with_index do |r, i|
657
+ text.gsub!( " <#{ i + 1 }>", r )
658
+ end
659
+ end
660
+
661
+ def incoming_entities( text )
662
+ ## turn any incoming ampersands into a dummy character for now.
663
+ ## This uses a negative lookahead for alphanumerics followed by a semicolon,
664
+ ## implying an incoming html entity, to be skipped
665
+
666
+ text.gsub!( /&(?![#a-z0-9]+;)/i, "x%x%" )
667
+ end
668
+
669
+ def encode_entities( text )
670
+ ## Convert high and low ascii to entities.
671
+ # if $-K == "UTF-8"
672
+ # encode_high( text )
673
+ # else
674
+ text.htmlesc!( :NoQuotes )
675
+ # end
676
+ end
677
+
678
+ def fix_entities( text )
679
+ ## de-entify any remaining angle brackets or ampersands
680
+ text.gsub!( "&gt;", ">" )
681
+ text.gsub!( "&lt;", "<" )
682
+ text.gsub!( "&amp;", "&" )
683
+ end
684
+
685
+ def clean_white_space( text )
686
+ text.gsub!( /\r\n/, "\n" )
687
+ text.gsub!( /\t/, '' )
688
+ text.gsub!( /\n{3,}/, "\n\n" )
689
+ text.gsub!( /\n *\n/, "\n\n" )
690
+ text.gsub!( /"$/, "\" " )
691
+ end
692
+
693
+ def no_textile( text )
694
+ text.gsub!( /(^|\s)==(.*?)==(\s|$)?/,
695
+ '\1<notextile>\2</notextile>\3' )
696
+ end
697
+
698
+ def footnote_ref( text )
699
+ text.gsub!( /\b\[([0-9]+?)\](\s)?/,
700
+ '<sup><a href="#fn\1">\1</a></sup>\2' )
701
+ end
702
+
703
+ OFFTAGS = /(code|pre|kbd|notextile)/
704
+ OFFTAG_MATCH = /(?:(<\/#{ OFFTAGS }>)|(<#{ OFFTAGS }[^>]*>))(.*?)(?=<\/?#{ OFFTAGS }>|\Z)/mi
705
+ OFFTAG_OPEN = /<#{ OFFTAGS }/
706
+ OFFTAG_CLOSE = /<\/?#{ OFFTAGS }/
707
+ HASTAG_MATCH = /(<\/?\w[^\n]*?>)/m
708
+ ALLTAG_MATCH = /(<\/?\w[^\n]*?>)|.*?(?=<\/?\w[^\n]*?>|$)/m
709
+
710
+ def glyphs( text, level = 0 )
711
+ if text !~ HASTAG_MATCH
712
+ pgl text
713
+ footnote_ref text
714
+ else
715
+ codepre = 0
716
+ text.gsub!( ALLTAG_MATCH ) do |line|
717
+ ## matches are off if we're between <code>, <pre> etc.
718
+ if $1
719
+ if @filter_html
720
+ line.htmlesc!( :NoQuotes )
721
+ elsif line =~ OFFTAG_OPEN
722
+ codepre += 1
723
+ elsif line =~ OFFTAG_CLOSE
724
+ codepre -= 1
725
+ codepre = 0 if codepre < 0
726
+ end
727
+ ## do htmlspecial if between <code>
728
+ elsif codepre.zero?
729
+ glyphs( line, level + 1 )
730
+ else
731
+ line.htmlesc!( :NoQuotes )
732
+ end
733
+ ## p [level, codepre, orig_line, line]
734
+
735
+ line
736
+ end
737
+ end
738
+ end
739
+
740
+ def rip_offtags( text )
741
+ pre_list = []
742
+ if text =~ /<.*>/
743
+ ## strip and encode <pre> content
744
+ codepre, used_offtags = 0, {}
745
+ text.gsub!( OFFTAG_MATCH ) do |line|
746
+ if $3
747
+ offtag, aftertag = $4, $5
748
+ codepre += 1
749
+ used_offtags[offtag] = true
750
+ if codepre - used_offtags.length > 0
751
+ line.htmlesc!( :NoQuotes )
752
+ pre_list.last << line
753
+ line = ""
754
+ else
755
+ aftertag.htmlesc!( :NoQuotes ) if aftertag
756
+ line = "<redpre##{ pre_list.length }>"
757
+ pre_list << "#{ $3 }#{ aftertag }"
758
+ end
759
+ elsif $1 and codepre > 0
760
+ if codepre - used_offtags.length > 0
761
+ line.htmlesc!( :NoQuotes )
762
+ pre_list.last << line
763
+ line = ""
764
+ end
765
+ codepre -= 1 unless codepre.zero?
766
+ used_offtags = {} if codepre.zero?
767
+ end
768
+ line
769
+ end
770
+ end
771
+ pre_list
772
+ end
773
+
774
+ def smooth_offtags( text, pre_list )
775
+ unless pre_list.empty?
776
+ ## replace <pre> content
777
+ text.gsub!( /<redpre#(\d+)>/ ) { pre_list[$1.to_i] }
778
+ end
779
+ end
780
+
781
+ def inline( text )
782
+ text.gsub!( /"\z/, "\" " )
783
+ pre_list = rip_offtags text
784
+
785
+ ## apply inline markup
786
+ unless @lite
787
+ lists text
788
+ table text
789
+ end
790
+
791
+ image text
792
+ links text
793
+ code text
794
+ span text
795
+
796
+ ## replace entities
797
+ glyphs text
798
+ smooth_offtags text, pre_list
799
+ end
800
+
801
+ def i_align( text )
802
+ I_ALGN_VALS[text]
803
+ end
804
+
805
+ def h_align( text )
806
+ H_ALGN_VALS[text]
807
+ end
808
+
809
+ def v_align( text )
810
+ V_ALGN_VALS[text]
811
+ end
812
+
813
+ def encode_high( text )
814
+ ## mb_encode_numericentity($text, $cmap, $charset);
815
+ end
816
+
817
+ def decode_high( text )
818
+ ## mb_decode_numericentity($text, $cmap, $charset);
819
+ end
820
+
821
+ def textile_popup_help( name, helpvar, windowW, windowH )
822
+ ' <a target="_blank" href="http://www.textpattern.com/help/?item=' + helpvar + '" onclick="window.open(this.href, \'popupwindow\', \'width=' + windowW + ',height=' + windowH + ',scrollbars,resizable\'); return false;">' + name + '</a><br />'
823
+ end
824
+
825
+ CMAP = [
826
+ 160, 255, 0, 0xffff,
827
+ 402, 402, 0, 0xffff,
828
+ 913, 929, 0, 0xffff,
829
+ 931, 937, 0, 0xffff,
830
+ 945, 969, 0, 0xffff,
831
+ 977, 978, 0, 0xffff,
832
+ 982, 982, 0, 0xffff,
833
+ 8226, 8226, 0, 0xffff,
834
+ 8230, 8230, 0, 0xffff,
835
+ 8242, 8243, 0, 0xffff,
836
+ 8254, 8254, 0, 0xffff,
837
+ 8260, 8260, 0, 0xffff,
838
+ 8465, 8465, 0, 0xffff,
839
+ 8472, 8472, 0, 0xffff,
840
+ 8476, 8476, 0, 0xffff,
841
+ 8482, 8482, 0, 0xffff,
842
+ 8501, 8501, 0, 0xffff,
843
+ 8592, 8596, 0, 0xffff,
844
+ 8629, 8629, 0, 0xffff,
845
+ 8656, 8660, 0, 0xffff,
846
+ 8704, 8704, 0, 0xffff,
847
+ 8706, 8707, 0, 0xffff,
848
+ 8709, 8709, 0, 0xffff,
849
+ 8711, 8713, 0, 0xffff,
850
+ 8715, 8715, 0, 0xffff,
851
+ 8719, 8719, 0, 0xffff,
852
+ 8721, 8722, 0, 0xffff,
853
+ 8727, 8727, 0, 0xffff,
854
+ 8730, 8730, 0, 0xffff,
855
+ 8733, 8734, 0, 0xffff,
856
+ 8736, 8736, 0, 0xffff,
857
+ 8743, 8747, 0, 0xffff,
858
+ 8756, 8756, 0, 0xffff,
859
+ 8764, 8764, 0, 0xffff,
860
+ 8773, 8773, 0, 0xffff,
861
+ 8776, 8776, 0, 0xffff,
862
+ 8800, 8801, 0, 0xffff,
863
+ 8804, 8805, 0, 0xffff,
864
+ 8834, 8836, 0, 0xffff,
865
+ 8838, 8839, 0, 0xffff,
866
+ 8853, 8853, 0, 0xffff,
867
+ 8855, 8855, 0, 0xffff,
868
+ 8869, 8869, 0, 0xffff,
869
+ 8901, 8901, 0, 0xffff,
870
+ 8968, 8971, 0, 0xffff,
871
+ 9001, 9002, 0, 0xffff,
872
+ 9674, 9674, 0, 0xffff,
873
+ 9824, 9824, 0, 0xffff,
874
+ 9827, 9827, 0, 0xffff,
875
+ 9829, 9830, 0, 0xffff,
876
+ 338, 339, 0, 0xffff,
877
+ 352, 353, 0, 0xffff,
878
+ 376, 376, 0, 0xffff,
879
+ 710, 710, 0, 0xffff,
880
+ 732, 732, 0, 0xffff,
881
+ 8194, 8195, 0, 0xffff,
882
+ 8201, 8201, 0, 0xffff,
883
+ 8204, 8207, 0, 0xffff,
884
+ 8211, 8212, 0, 0xffff,
885
+ 8216, 8218, 0, 0xffff,
886
+ 8218, 8218, 0, 0xffff,
887
+ 8220, 8222, 0, 0xffff,
888
+ 8224, 8225, 0, 0xffff,
889
+ 8240, 8240, 0, 0xffff,
890
+ 8249, 8250, 0, 0xffff,
891
+ 8364, 8364, 0, 0xffff
892
+ ]
893
+ end
894
+