instiki 0.9.2 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. data/CHANGELOG +165 -0
  2. data/README +68 -172
  3. data/app/controllers/admin_controller.rb +94 -0
  4. data/app/controllers/application.rb +131 -0
  5. data/app/controllers/file_controller.rb +129 -0
  6. data/app/controllers/wiki_controller.rb +354 -0
  7. data/{libraries/view_helper.rb → app/helpers/application_helper.rb} +68 -33
  8. data/app/models/author.rb +3 -3
  9. data/app/models/chunks/category.rb +33 -31
  10. data/app/models/chunks/chunk.rb +86 -20
  11. data/app/models/chunks/engines.rb +54 -38
  12. data/app/models/chunks/include.rb +41 -29
  13. data/app/models/chunks/literal.rb +31 -19
  14. data/app/models/chunks/nowiki.rb +28 -31
  15. data/app/models/chunks/test.rb +18 -18
  16. data/app/models/chunks/uri.rb +182 -97
  17. data/app/models/chunks/wiki.rb +141 -82
  18. data/app/models/file_yard.rb +58 -0
  19. data/app/models/page.rb +112 -86
  20. data/app/models/page_lock.rb +22 -23
  21. data/app/models/page_set.rb +89 -64
  22. data/app/models/revision.rb +123 -90
  23. data/app/models/web.rb +176 -89
  24. data/app/models/wiki_content.rb +207 -105
  25. data/app/models/wiki_service.rb +233 -83
  26. data/app/models/wiki_words.rb +23 -25
  27. data/app/views/{wiki/new_system.rhtml → admin/create_system.rhtml} +83 -78
  28. data/app/views/{wiki/new_web.rhtml → admin/create_web.rhtml} +69 -64
  29. data/app/views/admin/edit_web.rhtml +136 -0
  30. data/app/views/file/file.rhtml +19 -0
  31. data/app/views/file/import.rhtml +23 -0
  32. data/app/views/layouts/default.rhtml +85 -0
  33. data/app/views/markdown_help.rhtml +12 -16
  34. data/app/views/mixed_help.rhtml +7 -0
  35. data/app/views/navigation.rhtml +30 -19
  36. data/app/views/rdoc_help.rhtml +12 -16
  37. data/app/views/textile_help.rhtml +24 -28
  38. data/app/views/wiki/authors.rhtml +11 -13
  39. data/app/views/wiki/edit.rhtml +39 -31
  40. data/app/views/wiki/export.rhtml +12 -14
  41. data/app/views/wiki/feeds.rhtml +14 -10
  42. data/app/views/wiki/list.rhtml +64 -57
  43. data/app/views/wiki/locked.rhtml +23 -14
  44. data/app/views/wiki/login.rhtml +14 -11
  45. data/app/views/wiki/new.rhtml +31 -27
  46. data/app/views/wiki/page.rhtml +115 -81
  47. data/app/views/wiki/print.rhtml +14 -16
  48. data/app/views/wiki/published.rhtml +9 -10
  49. data/app/views/wiki/recently_revised.rhtml +27 -30
  50. data/app/views/wiki/revision.rhtml +103 -81
  51. data/app/views/wiki/rollback.rhtml +14 -9
  52. data/app/views/wiki/rss_feed.rhtml +22 -22
  53. data/app/views/wiki/search.rhtml +38 -15
  54. data/app/views/wiki/tex.rhtml +22 -22
  55. data/app/views/wiki/tex_web.rhtml +34 -34
  56. data/app/views/wiki/web_list.rhtml +18 -13
  57. data/app/views/wiki_words_help.rhtml +9 -8
  58. data/config/environment.rb +82 -0
  59. data/config/environments/development.rb +5 -0
  60. data/config/environments/production.rb +4 -0
  61. data/config/environments/test.rb +17 -0
  62. data/config/routes.rb +18 -0
  63. data/instiki +6 -67
  64. data/instiki.rb +3 -0
  65. data/lib/active_record_stub.rb +31 -0
  66. data/{libraries/diff → lib}/diff.rb +444 -475
  67. data/lib/instiki_errors.rb +15 -0
  68. data/{libraries → lib}/rdocsupport.rb +151 -155
  69. data/lib/redcloth_for_tex.rb +736 -0
  70. data/natives/osx/desktop_launcher/AppDelegate.h +18 -0
  71. data/natives/osx/desktop_launcher/AppDelegate.mm +109 -0
  72. data/natives/osx/desktop_launcher/Credits.html +16 -0
  73. data/natives/osx/desktop_launcher/English.lproj/InfoPlist.strings +0 -0
  74. data/natives/osx/desktop_launcher/English.lproj/MainMenu.nib/classes.nib +13 -0
  75. data/natives/osx/desktop_launcher/English.lproj/MainMenu.nib/info.nib +24 -0
  76. data/natives/osx/desktop_launcher/English.lproj/MainMenu.nib/objects.nib +0 -0
  77. data/natives/osx/desktop_launcher/Info.plist +13 -0
  78. data/natives/osx/desktop_launcher/Instiki.xcode/project.pbxproj +592 -0
  79. data/natives/osx/desktop_launcher/Instiki_Prefix.pch +7 -0
  80. data/natives/osx/desktop_launcher/MakeDMG.sh +9 -0
  81. data/natives/osx/desktop_launcher/main.mm +14 -0
  82. data/natives/osx/desktop_launcher/version.plist +16 -0
  83. data/public/404.html +6 -0
  84. data/public/500.html +6 -0
  85. data/public/dispatch.rb +10 -0
  86. data/public/favicon.ico +0 -0
  87. data/public/javascripts/edit_web.js +52 -0
  88. data/public/javascripts/prototype.js +336 -0
  89. data/{app/views/static_style_sheet.rhtml → public/stylesheets/instiki.css} +221 -198
  90. data/script/breakpointer +4 -0
  91. data/script/server +93 -0
  92. metadata +59 -32
  93. data/app/controllers/wiki.rb +0 -389
  94. data/app/models/chunks/match.rb +0 -19
  95. data/app/views/bottom.rhtml +0 -4
  96. data/app/views/top.rhtml +0 -49
  97. data/app/views/wiki/edit_web.rhtml +0 -138
  98. data/libraries/action_controller_servlet.rb +0 -177
  99. data/libraries/erb.rb +0 -490
  100. data/libraries/madeleine_service.rb +0 -68
  101. data/libraries/redcloth_for_tex.rb +0 -869
  102. data/libraries/web_controller_server.rb +0 -81
@@ -1,68 +0,0 @@
1
- require 'madeleine'
2
- require 'madeleine/automatic'
3
- require 'madeleine/zmarshal'
4
- require 'singleton'
5
- require 'yaml'
6
-
7
- class MadeleineService
8
- include Madeleine::Automatic::Interceptor
9
-
10
- @@storage_path = self.name.downcase + "_storage"
11
-
12
- class << self
13
- def storage_path
14
- @@storage_path
15
- end
16
-
17
- def storage_path=(storage_path)
18
- @@storage_path = storage_path
19
- end
20
-
21
- def instance
22
- @system = MadeleineServer.new(self).system if @system.nil?
23
- @system
24
- end
25
-
26
- def restart
27
- MadeleineServer.clean_storage(self)
28
- @system = MadeleineServer.new(self).system
29
- end
30
- end
31
- end
32
-
33
- class MadeleineServer
34
- SNAPSHOT_INTERVAL = 30 * 60 * 24 # Each day
35
- AUTOMATIC_SNAPSHOTS = true
36
-
37
- # Clears all the command_log and snapshot files located in the storage directory, so the
38
- # database is essentially dropped and recreated as blank. Used in tests.
39
- def self.clean_storage(service)
40
- require 'fileutils'
41
- if (File.directory?(service.storage_path))
42
- FileUtils.rm_rf(Dir[service.storage_path + '/*.command_log'])
43
- FileUtils.rm_rf(Dir[service.storage_path + '/*.snapshot'])
44
- else
45
- FileUtils.mkdir_p(service.storage_path)
46
- end
47
- end
48
-
49
- def initialize(service)
50
- marshaller = Madeleine::ZMarshal.new()
51
- @server = Madeleine::Automatic::AutomaticSnapshotMadeleine.new(service.storage_path,
52
- marshaller) { service.new }
53
- start_snapshot_thread if AUTOMATIC_SNAPSHOTS
54
- end
55
-
56
- def system
57
- @server.system
58
- end
59
-
60
- def start_snapshot_thread
61
- Thread.new(@server) {
62
- while true
63
- sleep(SNAPSHOT_INTERVAL)
64
- @server.take_snapshot
65
- end
66
- }
67
- end
68
- end
@@ -1,869 +0,0 @@
1
- # vim:ts=4:sw=4:
2
- # = RedCloth - Textile for Ruby
3
- #
4
- # (c) 2003 why the lucky stiff (and his puppet organizations.)
5
- #
6
- # (see http://www.textism.com/tools/textile/ for Textile)
7
- #
8
- # Based on (and also inspired by) both:
9
- #
10
- # PyTextile: http://diveintomark.org/projects/textile/textile.py.txt
11
- # Textism for PHP: http://www.textism.com/tools/textile/
12
- #
13
- #
14
- # == What is Textile?
15
- #
16
- # Textile is a simple formatting style for text
17
- # documents, loosely based on some HTML conventions.
18
- #
19
- # === Sample Textile Text
20
- #
21
- # h2. This is a title
22
- #
23
- # h3. This is a subhead
24
- #
25
- # This is a bit of paragraph.
26
- #
27
- # bq. This is a blockquote.
28
- #
29
- # === Writing Textile
30
- #
31
- # A Textile document consists of paragraphs. Paragraphs
32
- # can be specially formatted by adding a small instruction
33
- # to the beginning of the paragraph.
34
- #
35
- # h[n]. Header of size [n].
36
- # bq. Blockquote.
37
- # # Numeric list.
38
- # * Bulleted list.
39
- #
40
- # === Quick Phrase Modifiers
41
- #
42
- # Quick phrase modifiers are also included, to allow formatting
43
- # of small portions of text within a paragraph.
44
- #
45
- # _emphasis_
46
- # __italicized__
47
- # *strong*
48
- # **bold**
49
- # ??citation??
50
- # -deleted text-
51
- # +inserted text+
52
- # ^superscript^
53
- # ~subscript~
54
- # @code@
55
- # %(classname)span%
56
- #
57
- # ==notextile== (leave text alone)
58
- #
59
- # === Links
60
- #
61
- # To make a hypertext link, put the link text in "quotation
62
- # marks" followed immediately by a colon and the URL of the link.
63
- #
64
- # Optional: text in (parentheses) following the link text,
65
- # but before the closing quotation mark, will become a Title
66
- # attribute for the link, visible as a tool tip when a cursor is above it.
67
- #
68
- # Example:
69
- #
70
- # "This is a link (This is a title) ":http://www.textism.com
71
- #
72
- # Will become:
73
- #
74
- # <a href="http://www.textism.com" title="This is a title">This is a link</a>
75
- #
76
- # === Images
77
- #
78
- # To insert an image, put the URL for the image inside exclamation marks.
79
- #
80
- # Optional: text that immediately follows the URL in (parentheses) will
81
- # be used as the Alt text for the image. Images on the web should always
82
- # have descriptive Alt text for the benefit of readers using non-graphical
83
- # browsers.
84
- #
85
- # Optional: place a colon followed by a URL immediately after the
86
- # closing ! to make the image into a link.
87
- #
88
- # Example:
89
- #
90
- # !http://www.textism.com/common/textist.gif(Textist)!
91
- #
92
- # Will become:
93
- #
94
- # <img src="http://www.textism.com/common/textist.gif" alt="Textist" />
95
- #
96
- # With a link:
97
- #
98
- # !/common/textist.gif(Textist)!:http://textism.com
99
- #
100
- # Will become:
101
- #
102
- # <a href="http://textism.com"><img src="/common/textist.gif" alt="Textist" /></a>
103
- #
104
- # === Defining Acronyms
105
- #
106
- # HTML allows authors to define acronyms via the tag. The definition appears as a
107
- # tool tip when a cursor hovers over the acronym. A crucial aid to clear writing,
108
- # this should be used at least once for each acronym in documents where they appear.
109
- #
110
- # To quickly define an acronym in Textile, place the full text in (parentheses)
111
- # immediately following the acronym.
112
- #
113
- # Example:
114
- #
115
- # ACLU(American Civil Liberties Union)
116
- #
117
- # Will become:
118
- #
119
- # <acronym title="American Civil Liberties Union">ACLU</acronym>
120
- #
121
- # === Adding Tables
122
- #
123
- # In Textile, simple tables can be added by seperating each column by
124
- # a pipe.
125
- #
126
- # |a|simple|table|row|
127
- # |And|Another|table|row|
128
- #
129
- # Attributes are defined by style definitions in parentheses.
130
- #
131
- # table(border:1px solid black).
132
- # (background:#ddd;color:red). |{}| | | |
133
- #
134
- # === Using RedCloth
135
- #
136
- # RedCloth is simply an extension of the String class, which can handle
137
- # Textile formatting. Use it like a String and output HTML with its
138
- # RedCloth#to_html method.
139
- #
140
- # doc = RedCloth.new "
141
- #
142
- # h2. Test document
143
- #
144
- # Just a simple test."
145
- #
146
- # puts doc.to_html
147
-
148
- class String
149
- #
150
- # Flexible HTML escaping
151
- #
152
- def texesc!( mode )
153
- gsub!( '&', '\\\\&' )
154
- gsub!( '%', '\%' )
155
- gsub!( '$', '\$' )
156
- end
157
- end
158
-
159
-
160
- def table_of_contents(text, pages)
161
- text.gsub!( /^([#*]+? .*?)$(?![^#*])/m ) do |match|
162
- lines = match.split( /\n/ )
163
- last_line = -1
164
- depth = []
165
- lines.each_with_index do |line, line_id|
166
- if line =~ /^([#*]+) (.*)$/m
167
- tl,content = $~[1..2]
168
- content.gsub! /[\[\]]/, ""
169
- content.strip!
170
-
171
- if depth.last
172
- if depth.last.length > tl.length
173
- (depth.length - 1).downto(0) do |i|
174
- break if depth[i].length == tl.length
175
- lines[line_id - 1] << "" # "\n\t\\end{#{ lT( depth[i] ) }}\n\t"
176
- depth.pop
177
- end
178
- end
179
- if !depth.last.nil? && !tl.length.nil? && depth.last.length == tl.length
180
- lines[line_id - 1] << ''
181
- end
182
- end
183
-
184
- depth << tl unless depth.last == tl
185
-
186
- subsection_depth = [depth.length - 1, 2].min
187
-
188
- lines[line_id] = "\n\\#{ "sub" * subsection_depth }section{#{ content }}"
189
- lines[line_id] += "\n#{pages[content]}" if pages.keys.include?(content)
190
-
191
- lines[line_id] = "\\pagebreak\n#{lines[line_id]}" if subsection_depth == 0
192
-
193
- last_line = line_id
194
-
195
- elsif line =~ /^\s+\S/
196
- last_line = line_id
197
- elsif line_id - last_line < 2 and line =~ /^\S/
198
- last_line = line_id
199
- end
200
- if line_id - last_line > 1 or line_id == lines.length - 1
201
- depth.delete_if do |v|
202
- lines[last_line] << "" # "\n\t\\end{#{ lT( v ) }}"
203
- end
204
- end
205
- end
206
- lines.join( "\n" )
207
- end
208
- end
209
-
210
- class RedClothForTex < String
211
-
212
- VERSION = '2.0.7'
213
-
214
- #
215
- # Mapping of 8-bit ASCII codes to HTML numerical entity equivalents.
216
- # (from PyTextile)
217
- #
218
- TEXTILE_TAGS =
219
-
220
- [[128, 8364], [129, 0], [130, 8218], [131, 402], [132, 8222], [133, 8230],
221
- [134, 8224], [135, 8225], [136, 710], [137, 8240], [138, 352], [139, 8249],
222
- [140, 338], [141, 0], [142, 0], [143, 0], [144, 0], [145, 8216], [146, 8217],
223
- [147, 8220], [148, 8221], [149, 8226], [150, 8211], [151, 8212], [152, 732],
224
- [153, 8482], [154, 353], [155, 8250], [156, 339], [157, 0], [158, 0], [159, 376]].
225
-
226
- collect! do |a, b|
227
- [a.chr, ( b.zero? and "" or "&#{ b };" )]
228
- end
229
-
230
- #
231
- # Regular expressions to convert to HTML.
232
- #
233
- A_HLGN = /(?:(?:<>|<|>|\=|[()]+)+)/
234
- A_VLGN = /[\-^~]/
235
- C_CLAS = '(?:\([^)]+\))'
236
- C_LNGE = '(?:\[[^\]]+\])'
237
- C_STYL = '(?:\{[^}]+\})'
238
- S_CSPN = '(?:\\\\\d+)'
239
- S_RSPN = '(?:/\d+)'
240
- A = "(?:#{A_HLGN}?#{A_VLGN}?|#{A_VLGN}?#{A_HLGN}?)"
241
- S = "(?:#{S_CSPN}?#{S_RSPN}|#{S_RSPN}?#{S_CSPN}?)"
242
- C = "(?:#{C_CLAS}?#{C_STYL}?#{C_LNGE}?|#{C_STYL}?#{C_LNGE}?#{C_CLAS}?|#{C_LNGE}?#{C_STYL}?#{C_CLAS}?)"
243
- # PUNCT = Regexp::quote( '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' )
244
- PUNCT = Regexp::quote( '!"#$%&\'*+,-./:;=?@\\^_`|~' )
245
- HYPERLINK = '(\S+?)([^\w\s/;=\?]*?)(\s|$)'
246
-
247
- GLYPHS = [
248
- # [ /([^\s\[{(>])?\'([dmst]\b|ll\b|ve\b|\s|:|$)/, '\1&#8217;\2' ], # single closing
249
- [ /([^\s\[{(>])\'/, '\1&#8217;' ], # single closing
250
- [ /\'(?=\s|s\b|[#{PUNCT}])/, '&#8217;' ], # single closing
251
- [ /\'/, '&#8216;' ], # single opening
252
- # [ /([^\s\[{(])?"(\s|:|$)/, '\1&#8221;\2' ], # double closing
253
- [ /([^\s\[{(>])"/, '\1&#8221;' ], # double closing
254
- [ /"(?=\s|[#{PUNCT}])/, '&#8221;' ], # double closing
255
- [ /"/, '&#8220;' ], # double opening
256
- [ /\b( )?\.{3}/, '\1&#8230;' ], # ellipsis
257
- [ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '<acronym title="\2">\1</acronym>' ], # 3+ uppercase acronym
258
- [ /(^|[^"][>\s])([A-Z][A-Z0-9 ]{2,})([^<a-z0-9]|$)/, '\1<span class="caps">\2</span>\3' ], # 3+ uppercase caps
259
- [ /(\.\s)?\s?--\s?/, '\1&#8212;' ], # em dash
260
- [ /\s->\s/, ' &rarr; ' ], # en dash
261
- [ /\s-\s/, ' &#8211; ' ], # en dash
262
- [ /(\d+) ?x ?(\d+)/, '\1&#215;\2' ], # dimension sign
263
- [ /\b ?[(\[]TM[\])]/i, '&#8482;' ], # trademark
264
- [ /\b ?[(\[]R[\])]/i, '&#174;' ], # registered
265
- [ /\b ?[(\[]C[\])]/i, '&#169;' ] # copyright
266
- ]
267
-
268
- I_ALGN_VALS = {
269
- '<' => 'left',
270
- '=' => 'center',
271
- '>' => 'right'
272
- }
273
-
274
- H_ALGN_VALS = {
275
- '<' => 'left',
276
- '=' => 'center',
277
- '>' => 'right',
278
- '<>' => 'justify'
279
- }
280
-
281
- V_ALGN_VALS = {
282
- '^' => 'top',
283
- '-' => 'middle',
284
- '~' => 'bottom'
285
- }
286
-
287
- QTAGS = [
288
- ['**', 'bf'],
289
- ['*', 'bf'],
290
- ['??', 'cite'],
291
- ['-', 'del'],
292
- ['__', 'underline'],
293
- ['_', 'em'],
294
- ['%', 'span'],
295
- ['+', 'ins'],
296
- ['^', 'sup'],
297
- ['~', 'sub']
298
- ]
299
-
300
- #
301
- # Two accessor for setting security restrictions.
302
- #
303
- # This is a nice thing if you're using RedCloth for
304
- # formatting in public places (e.g. Wikis) where you
305
- # don't want users to abuse HTML for bad things.
306
- #
307
- # If +:filter_html+ is set, HTML which wasn't
308
- # created by the Textile processor will be escaped.
309
- #
310
- # If +:filter_styles+ is set, it will also disable
311
- # the style markup specifier. ('{color: red}')
312
- #
313
- attr_accessor :filter_html, :filter_styles
314
-
315
- #
316
- # Accessor for toggling line folding.
317
- #
318
- # If +:fold_lines+ is set, single newlines will
319
- # not be converted to break tags.
320
- #
321
- attr_accessor :fold_lines
322
-
323
- def initialize( string, restrictions = [] )
324
- restrictions.each { |r| method( "#{ r }=" ).call( true ) }
325
- super( string )
326
- end
327
-
328
- #
329
- # Generate tex.
330
- #
331
- def to_tex( lite = false )
332
-
333
- # make our working copy
334
- text = self.dup
335
-
336
- @urlrefs = {}
337
- @shelf = []
338
-
339
- # incoming_entities text
340
- fix_entities text
341
- clean_white_space text
342
-
343
- get_refs text
344
-
345
- no_textile text
346
-
347
- unless lite
348
- lists text
349
- table text
350
- end
351
-
352
- glyphs text
353
-
354
- unless lite
355
- fold text
356
- block text
357
- end
358
-
359
- retrieve text
360
- encode_entities text
361
-
362
- text.gsub!(/\[\[(.*?)\]\]/, "\\1")
363
- text.gsub!(/_/, "\\_")
364
- text.gsub!( /<\/?notextile>/, '' )
365
- # text.gsub!( /x%x%/, '&#38;' )
366
- # text.gsub!( /<br \/>/, "<br />\n" )
367
- text.strip!
368
- text
369
-
370
- end
371
-
372
- def pgl( text )
373
- GLYPHS.each do |re, resub|
374
- text.gsub! re, resub
375
- end
376
- end
377
-
378
- def pba( text_in, element = "" )
379
-
380
- return '' unless text_in
381
-
382
- style = []
383
- text = text_in.dup
384
- if element == 'td'
385
- colspan = $1 if text =~ /\\(\d+)/
386
- rowspan = $1 if text =~ /\/(\d+)/
387
- style << "vertical-align:#{ v_align( $& ) };" if text =~ A_VLGN
388
- end
389
-
390
- style << "#{ $1 };" if not @filter_styles and
391
- text.sub!( /\{([^}]*)\}/, '' )
392
-
393
- lang = $1 if
394
- text.sub!( /\[([^)]+?)\]/, '' )
395
-
396
- cls = $1 if
397
- text.sub!( /\(([^()]+?)\)/, '' )
398
-
399
- style << "padding-left:#{ $1.length }em;" if
400
- text.sub!( /([(]+)/, '' )
401
-
402
- style << "padding-right:#{ $1.length }em;" if text.sub!( /([)]+)/, '' )
403
-
404
- style << "text-align:#{ h_align( $& ) };" if text =~ A_HLGN
405
-
406
- cls, id = $1, $2 if cls =~ /^(.*?)#(.*)$/
407
-
408
- atts = ''
409
- atts << " style=\"#{ style.join }\"" unless style.empty?
410
- atts << " class=\"#{ cls }\"" unless cls.to_s.empty?
411
- atts << " lang=\"#{ lang }\"" if lang
412
- atts << " id=\"#{ id }\"" if id
413
- atts << " colspan=\"#{ colspan }\"" if colspan
414
- atts << " rowspan=\"#{ rowspan }\"" if rowspan
415
-
416
- atts
417
- end
418
-
419
- def table( text )
420
- text << "\n\n"
421
- text.gsub!( /^(?:table(_?#{S}#{A}#{C})\. ?\n)?^(#{A}#{C}\.? ?\|.*?\|)\n\n/m ) do |matches|
422
-
423
- tatts, fullrow = $~[1..2]
424
- tatts = pba( tatts, 'table' )
425
- rows = []
426
-
427
- fullrow.
428
- split( /\|$/m ).
429
- delete_if { |x| x.empty? }.
430
- each do |row|
431
-
432
- ratts, row = pba( $1, 'tr' ), $2 if row =~ /^(#{A}#{C}\. )(.*)/m
433
-
434
- cells = []
435
- row.split( '|' ).each do |cell|
436
- ctyp = 'd'
437
- ctyp = 'h' if cell =~ /^_/
438
-
439
- catts = ''
440
- catts, cell = pba( $1, 'td' ), $2 if cell =~ /^(_?#{S}#{A}#{C}\. )(.*)/
441
-
442
- unless cell.strip.empty?
443
- cells << "\t\t\t<t#{ ctyp }#{ catts }>#{ cell }</t#{ ctyp }>"
444
- end
445
- end
446
- rows << "\t\t<tr#{ ratts }>\n#{ cells.join( "\n" ) }\n\t\t</tr>"
447
- end
448
- "\t<table#{ tatts }>\n#{ rows.join( "\n" ) }\n\t</table>\n\n"
449
- end
450
- end
451
-
452
- def lists( text )
453
- text.gsub!( /^([#*]+?#{C} .*?)$(?![^#*])/m ) do |match|
454
- lines = match.split( /\n/ )
455
- last_line = -1
456
- depth = []
457
- lines.each_with_index do |line, line_id|
458
- if line =~ /^([#*]+)(#{A}#{C}) (.*)$/m
459
- tl,atts,content = $~[1..3]
460
- if depth.last
461
- if depth.last.length > tl.length
462
- (depth.length - 1).downto(0) do |i|
463
- break if depth[i].length == tl.length
464
- lines[line_id - 1] << "\n\t\\end{#{ lT( depth[i] ) }}\n\t"
465
- depth.pop
466
- end
467
- end
468
- if !depth.last.nil? && !tl.length.nil? && depth.last.length == tl.length
469
- lines[line_id - 1] << ''
470
- end
471
- end
472
- unless depth.last == tl
473
- depth << tl
474
- atts = pba( atts )
475
- lines[line_id] = "\t\\begin{#{ lT(tl) }}\n\t\\item #{ content }"
476
- else
477
- lines[line_id] = "\t\t\\item #{ content }"
478
- end
479
- last_line = line_id
480
-
481
- elsif line =~ /^\s+\S/
482
- last_line = line_id
483
- elsif line_id - last_line < 2 and line =~ /^\S/
484
- last_line = line_id
485
- end
486
- if line_id - last_line > 1 or line_id == lines.length - 1
487
- depth.delete_if do |v|
488
- lines[last_line] << "\n\t\\end{#{ lT( v ) }}"
489
- end
490
- end
491
- end
492
- lines.join( "\n" )
493
- end
494
- end
495
-
496
- def lT( text )
497
- text =~ /\#$/ ? 'enumerate' : 'itemize'
498
- end
499
-
500
- def fold( text )
501
- text.gsub!( /(.+)\n(?![#*\s|])/, "\\1\\\\\\\\" )
502
- # text.gsub!( /(.+)\n(?![#*\s|])/, "\\1#{ @fold_lines ? ' ' : '<br />' }" )
503
- end
504
-
505
- def block( text )
506
- pre = false
507
- find = ['bq','h[1-6]','fn\d+']
508
-
509
- regexp_cue = []
510
-
511
- lines = text.split( /\n/ ) + [' ']
512
- new_text =
513
- lines.collect do |line|
514
- pre = true if line =~ /<(pre|notextile)>/i
515
- find.each do |tag|
516
- line.gsub!( /^(#{ tag })(#{A}#{C})\.(?::(\S+))? (.*)$/ ) do |m|
517
- tag,atts,cite,content = $~[1..4]
518
-
519
- atts = pba( atts )
520
-
521
- if tag =~ /fn(\d+)/
522
- # tag = 'p';
523
- # atts << " id=\"fn#{ $1 }\""
524
- regexp_cue << [ /footnote\{#{$1}}/, "footnote{#{content}}" ]
525
- content = ""
526
- end
527
-
528
- if tag =~ /h([1-6])/
529
- section_type = "sub" * [$1.to_i - 1, 2].min
530
- start = "\t\\#{section_type}section*{"
531
- tend = "}"
532
- end
533
-
534
- if tag == "bq"
535
- cite = check_refs( cite )
536
- cite = " cite=\"#{ cite }\"" if cite
537
- start = "\t\\begin{quotation}\n\\noindent {\\em ";
538
- tend = "}\n\t\\end{quotation}";
539
- end
540
-
541
- "#{ start }#{ content }#{ tend }"
542
- end unless pre
543
- end
544
-
545
- #line.gsub!( /^(?!\t|<\/?pre|<\/?notextile|<\/?code|$| )(.*)/, "\t<p>\\1</p>" )
546
-
547
- #line.gsub!( "<br />", "\n" ) if pre
548
- # pre = false if line =~ /<\/(pre|notextile)>/i
549
-
550
- line
551
- end.join( "\n" )
552
- text.replace( new_text )
553
- regexp_cue.each { |pair| text.gsub!(pair.first, pair.last) }
554
- end
555
-
556
- def span( text )
557
- QTAGS.each do |tt, ht|
558
- ttr = Regexp::quote( tt )
559
- text.gsub!(
560
-
561
- /(^|\s|\>|[#{PUNCT}{(\[])
562
- #{ttr}
563
- (#{C})
564
- (?::(\S+?))?
565
- ([^\s#{ttr}]+?(?:[^\n]|\n(?!\n))*?)
566
- ([#{PUNCT}]*?)
567
- #{ttr}
568
- (?=[\])}]|[#{PUNCT}]+?|<|\s|$)/xm
569
-
570
- ) do |m|
571
-
572
- start,atts,cite,content,tend = $~[1..5]
573
- atts = pba( atts )
574
- atts << " cite=\"#{ cite }\"" if cite
575
-
576
- "#{ start }{\\#{ ht } #{ content }#{ tend }}"
577
-
578
- end
579
- end
580
- end
581
-
582
- def links( text )
583
- text.gsub!( /
584
- ([\s\[{(]|[#{PUNCT}])? # $pre
585
- " # start
586
- (#{C}) # $atts
587
- ([^"]+?) # $text
588
- \s?
589
- (?:\(([^)]+?)\)(?="))? # $title
590
- ":
591
- (\S+?) # $url
592
- (\/)? # $slash
593
- ([^\w\/;]*?) # $post
594
- (?=\s|$)
595
- /x ) do |m|
596
- pre,atts,text,title,url,slash,post = $~[1..7]
597
-
598
- url = check_refs( url )
599
-
600
- atts = pba( atts )
601
- atts << " title=\"#{ title }\"" if title
602
- atts = shelve( atts ) if atts
603
-
604
- "#{ pre }<a href=\"#{ url }#{ slash }\"#{ atts }>#{ text }</a>#{ post }"
605
- end
606
- end
607
-
608
- def get_refs( text )
609
- text.gsub!( /(^|\s)\[(.+?)\]((?:http:\/\/|javascript:|ftp:\/\/|\/)\S+?)(?=\s|$)/ ) do |m|
610
- flag, url = $~[1..2]
611
- @urlrefs[flag] = url
612
- end
613
- end
614
-
615
- def check_refs( text )
616
- @urlrefs[text] || text
617
- end
618
-
619
- def image( text )
620
- text.gsub!( /
621
- \! # opening
622
- (\<|\=|\>)? # optional alignment atts
623
- (#{C}) # optional style,class atts
624
- (?:\. )? # optional dot-space
625
- ([^\s(!]+?) # presume this is the src
626
- \s? # optional space
627
- (?:\(((?:[^\(\)]|\([^\)]+\))+?)\))? # optional title
628
- \! # closing
629
- (?::#{ HYPERLINK })? # optional href
630
- /x ) do |m|
631
- algn,atts,url,title,href,href_a1,href_a2 = $~[1..7]
632
- atts = pba( atts )
633
- atts << " align=\"#{ i_align( algn ) }\"" if algn
634
- atts << " title=\"#{ title }\"" if title
635
- atts << " alt=\"#{ title }\""
636
- # size = @getimagesize($url);
637
- # if($size) $atts.= " $size[3]";
638
-
639
- href = check_refs( href ) if href
640
- url = check_refs( url )
641
-
642
- out = ''
643
- out << "<a href=\"#{ href }\">" if href
644
- out << "<img src=\"#{ url }\"#{ atts } />"
645
- out << "</a>#{ href_a1 }#{ href_a2 }" if href
646
-
647
- out
648
- end
649
- end
650
-
651
- def code( text )
652
- text.gsub!( /
653
- (?:^|([\s\(\[{])) # 1 open bracket?
654
- @ # opening
655
- (?:\|(\w+?)\|)? # 2 language
656
- (\S(?:[^\n]|\n(?!\n))*?) # 3 code
657
- @ # closing
658
- (?:$|([\]})])|
659
- (?=[#{PUNCT}]{1,2}|
660
- \s)) # 4 closing bracket?
661
- /x ) do |m|
662
- before,lang,code,after = $~[1..4]
663
- lang = " language=\"#{ lang }\"" if lang
664
- "#{ before }<code#{ lang }>#{ code }</code>#{ after }"
665
- end
666
- end
667
-
668
- def shelve( val )
669
- @shelf << val
670
- " <#{ @shelf.length }>"
671
- end
672
-
673
- def retrieve( text )
674
- @shelf.each_with_index do |r, i|
675
- text.gsub!( " <#{ i + 1 }>", r )
676
- end
677
- end
678
-
679
- def incoming_entities( text )
680
- ## turn any incoming ampersands into a dummy character for now.
681
- ## This uses a negative lookahead for alphanumerics followed by a semicolon,
682
- ## implying an incoming html entity, to be skipped
683
-
684
- text.gsub!( /&(?![#a-z0-9]+;)/i, "x%x%" )
685
- end
686
-
687
- def encode_entities( text )
688
- ## Convert high and low ascii to entities.
689
- # if $-K == "UTF-8"
690
- # encode_high( text )
691
- # else
692
- text.texesc!( :NoQuotes )
693
- # end
694
- end
695
-
696
- def fix_entities( text )
697
- ## de-entify any remaining angle brackets or ampersands
698
- text.gsub!( "\&", "&" )
699
- text.gsub!( "\%", "%" )
700
- end
701
-
702
- def clean_white_space( text )
703
- text.gsub!( /\r\n/, "\n" )
704
- text.gsub!( /\t/, '' )
705
- text.gsub!( /\n{3,}/, "\n\n" )
706
- text.gsub!( /\n *\n/, "\n\n" )
707
- text.gsub!( /"$/, "\" " )
708
- end
709
-
710
- def no_textile( text )
711
- text.gsub!( /(^|\s)==(.*?)==(\s|$)?/,
712
- '\1<notextile>\2</notextile>\3' )
713
- end
714
-
715
- def footnote_ref( text )
716
- text.gsub!( /\[([0-9]+?)\](\s)?/,
717
- '\footnote{\1}\2')
718
- #'<sup><a href="#fn\1">\1</a></sup>\2' )
719
- end
720
-
721
- def inline( text )
722
- image text
723
- links text
724
- code text
725
- span text
726
- end
727
-
728
- def glyphs_deep( text )
729
- codepre = 0
730
- offtags = /(?:code|pre|kbd|notextile)/
731
- if text !~ /<.*>/
732
- # pgl text
733
- footnote_ref text
734
- else
735
- used_offtags = {}
736
- text.gsub!( /(?:[^<].*?(?=<[^\n]*?>|$)|<[^\n]*?>+)/m ) do |line|
737
- tagline = ( line =~ /^<.*>/ )
738
-
739
- ## matches are off if we're between <code>, <pre> etc.
740
- if tagline
741
- if line =~ /<(#{ offtags })>/i
742
- codepre += 1
743
- used_offtags[$1] = true
744
- line.texesc!( :NoQuotes ) if codepre - used_offtags.length > 0
745
- elsif line =~ /<\/(#{ offtags })>/i
746
- line.texesc!( :NoQuotes ) if codepre - used_offtags.length > 0
747
- codepre -= 1 unless codepre.zero?
748
- used_offtags = {} if codepre.zero?
749
- elsif @filter_html or codepre > 0
750
- line.texesc!( :NoQuotes )
751
- ## line.gsub!( /&lt;(\/?#{ offtags })&gt;/, '<\1>' )
752
- end
753
- ## do htmlspecial if between <code>
754
- elsif codepre > 0
755
- line.texesc!( :NoQuotes )
756
- ## line.gsub!( /&lt;(\/?#{ offtags })&gt;/, '<\1>' )
757
- elsif not tagline
758
- inline line
759
- glyphs_deep line
760
- end
761
-
762
- line
763
- end
764
- end
765
- end
766
-
767
- def glyphs( text )
768
- text.gsub!( /"\z/, "\" " )
769
- ## if no html, do a simple search and replace...
770
- if text !~ /<.*>/
771
- inline text
772
- end
773
- glyphs_deep text
774
- end
775
-
776
- def i_align( text )
777
- I_ALGN_VALS[text]
778
- end
779
-
780
- def h_align( text )
781
- H_ALGN_VALS[text]
782
- end
783
-
784
- def v_align( text )
785
- V_ALGN_VALS[text]
786
- end
787
-
788
- def encode_high( text )
789
- ## mb_encode_numericentity($text, $cmap, $charset);
790
- end
791
-
792
- def decode_high( text )
793
- ## mb_decode_numericentity($text, $cmap, $charset);
794
- end
795
-
796
- def textile_popup_help( name, helpvar, windowW, windowH )
797
- ' <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 />'
798
- end
799
-
800
- CMAP = [
801
- 160, 255, 0, 0xffff,
802
- 402, 402, 0, 0xffff,
803
- 913, 929, 0, 0xffff,
804
- 931, 937, 0, 0xffff,
805
- 945, 969, 0, 0xffff,
806
- 977, 978, 0, 0xffff,
807
- 982, 982, 0, 0xffff,
808
- 8226, 8226, 0, 0xffff,
809
- 8230, 8230, 0, 0xffff,
810
- 8242, 8243, 0, 0xffff,
811
- 8254, 8254, 0, 0xffff,
812
- 8260, 8260, 0, 0xffff,
813
- 8465, 8465, 0, 0xffff,
814
- 8472, 8472, 0, 0xffff,
815
- 8476, 8476, 0, 0xffff,
816
- 8482, 8482, 0, 0xffff,
817
- 8501, 8501, 0, 0xffff,
818
- 8592, 8596, 0, 0xffff,
819
- 8629, 8629, 0, 0xffff,
820
- 8656, 8660, 0, 0xffff,
821
- 8704, 8704, 0, 0xffff,
822
- 8706, 8707, 0, 0xffff,
823
- 8709, 8709, 0, 0xffff,
824
- 8711, 8713, 0, 0xffff,
825
- 8715, 8715, 0, 0xffff,
826
- 8719, 8719, 0, 0xffff,
827
- 8721, 8722, 0, 0xffff,
828
- 8727, 8727, 0, 0xffff,
829
- 8730, 8730, 0, 0xffff,
830
- 8733, 8734, 0, 0xffff,
831
- 8736, 8736, 0, 0xffff,
832
- 8743, 8747, 0, 0xffff,
833
- 8756, 8756, 0, 0xffff,
834
- 8764, 8764, 0, 0xffff,
835
- 8773, 8773, 0, 0xffff,
836
- 8776, 8776, 0, 0xffff,
837
- 8800, 8801, 0, 0xffff,
838
- 8804, 8805, 0, 0xffff,
839
- 8834, 8836, 0, 0xffff,
840
- 8838, 8839, 0, 0xffff,
841
- 8853, 8853, 0, 0xffff,
842
- 8855, 8855, 0, 0xffff,
843
- 8869, 8869, 0, 0xffff,
844
- 8901, 8901, 0, 0xffff,
845
- 8968, 8971, 0, 0xffff,
846
- 9001, 9002, 0, 0xffff,
847
- 9674, 9674, 0, 0xffff,
848
- 9824, 9824, 0, 0xffff,
849
- 9827, 9827, 0, 0xffff,
850
- 9829, 9830, 0, 0xffff,
851
- 338, 339, 0, 0xffff,
852
- 352, 353, 0, 0xffff,
853
- 376, 376, 0, 0xffff,
854
- 710, 710, 0, 0xffff,
855
- 732, 732, 0, 0xffff,
856
- 8194, 8195, 0, 0xffff,
857
- 8201, 8201, 0, 0xffff,
858
- 8204, 8207, 0, 0xffff,
859
- 8211, 8212, 0, 0xffff,
860
- 8216, 8218, 0, 0xffff,
861
- 8218, 8218, 0, 0xffff,
862
- 8220, 8222, 0, 0xffff,
863
- 8224, 8225, 0, 0xffff,
864
- 8240, 8240, 0, 0xffff,
865
- 8249, 8250, 0, 0xffff,
866
- 8364, 8364, 0, 0xffff
867
- ]
868
- end
869
-