cortex-reaver 0.0.1

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 (128) hide show
  1. data/LICENSE +25 -0
  2. data/README +48 -0
  3. data/bin/console +11 -0
  4. data/bin/cortex_reaver +110 -0
  5. data/bin/import.rb +78 -0
  6. data/lib/cortex_reaver.rb +114 -0
  7. data/lib/cortex_reaver/config.rb +21 -0
  8. data/lib/cortex_reaver/controller/comment.rb +113 -0
  9. data/lib/cortex_reaver/controller/config.rb +14 -0
  10. data/lib/cortex_reaver/controller/journal.rb +40 -0
  11. data/lib/cortex_reaver/controller/main.rb +56 -0
  12. data/lib/cortex_reaver/controller/page.rb +34 -0
  13. data/lib/cortex_reaver/controller/photograph.rb +45 -0
  14. data/lib/cortex_reaver/controller/project.rb +40 -0
  15. data/lib/cortex_reaver/controller/tag.rb +67 -0
  16. data/lib/cortex_reaver/controller/user.rb +71 -0
  17. data/lib/cortex_reaver/helper/activity.rb +9 -0
  18. data/lib/cortex_reaver/helper/attachments.rb +139 -0
  19. data/lib/cortex_reaver/helper/auth.rb +45 -0
  20. data/lib/cortex_reaver/helper/canonical.rb +55 -0
  21. data/lib/cortex_reaver/helper/crud.rb +317 -0
  22. data/lib/cortex_reaver/helper/date.rb +29 -0
  23. data/lib/cortex_reaver/helper/error.rb +14 -0
  24. data/lib/cortex_reaver/helper/feeds.rb +88 -0
  25. data/lib/cortex_reaver/helper/form.rb +114 -0
  26. data/lib/cortex_reaver/helper/navigation.rb +142 -0
  27. data/lib/cortex_reaver/helper/photographs.rb +25 -0
  28. data/lib/cortex_reaver/helper/tags.rb +47 -0
  29. data/lib/cortex_reaver/helper/workflow.rb +27 -0
  30. data/lib/cortex_reaver/migrations/001_users.rb +24 -0
  31. data/lib/cortex_reaver/migrations/002_pages.rb +29 -0
  32. data/lib/cortex_reaver/migrations/003_journals.rb +26 -0
  33. data/lib/cortex_reaver/migrations/004_photographs.rb +24 -0
  34. data/lib/cortex_reaver/migrations/005_projects.rb +27 -0
  35. data/lib/cortex_reaver/migrations/006_tags.rb +64 -0
  36. data/lib/cortex_reaver/migrations/007_comments.rb +40 -0
  37. data/lib/cortex_reaver/migrations/008_config.rb +23 -0
  38. data/lib/cortex_reaver/model/comment.rb +109 -0
  39. data/lib/cortex_reaver/model/journal.rb +53 -0
  40. data/lib/cortex_reaver/model/page.rb +87 -0
  41. data/lib/cortex_reaver/model/photograph.rb +133 -0
  42. data/lib/cortex_reaver/model/project.rb +49 -0
  43. data/lib/cortex_reaver/model/tag.rb +72 -0
  44. data/lib/cortex_reaver/model/user.rb +147 -0
  45. data/lib/cortex_reaver/public/css/admin.css +45 -0
  46. data/lib/cortex_reaver/public/css/custom.css +0 -0
  47. data/lib/cortex_reaver/public/css/form.css +51 -0
  48. data/lib/cortex_reaver/public/css/main.css +325 -0
  49. data/lib/cortex_reaver/public/css/photo.css +113 -0
  50. data/lib/cortex_reaver/public/css/ramaze_error.css +90 -0
  51. data/lib/cortex_reaver/public/css/text.css +25 -0
  52. data/lib/cortex_reaver/public/dispatch.fcgi +11 -0
  53. data/lib/cortex_reaver/public/images/CortexReaver.gif +0 -0
  54. data/lib/cortex_reaver/public/images/atom-xml-icon.png +0 -0
  55. data/lib/cortex_reaver/public/images/body.png +0 -0
  56. data/lib/cortex_reaver/public/images/border_bottom.png +0 -0
  57. data/lib/cortex_reaver/public/images/border_bottom_left.png +0 -0
  58. data/lib/cortex_reaver/public/images/border_bottom_right.png +0 -0
  59. data/lib/cortex_reaver/public/images/border_left.png +0 -0
  60. data/lib/cortex_reaver/public/images/border_right.png +0 -0
  61. data/lib/cortex_reaver/public/images/border_top.png +0 -0
  62. data/lib/cortex_reaver/public/images/border_top_left.png +0 -0
  63. data/lib/cortex_reaver/public/images/border_top_right.png +0 -0
  64. data/lib/cortex_reaver/public/images/comment.gif +0 -0
  65. data/lib/cortex_reaver/public/images/dark_trans.png +0 -0
  66. data/lib/cortex_reaver/public/images/delete.gif +0 -0
  67. data/lib/cortex_reaver/public/images/edit.gif +0 -0
  68. data/lib/cortex_reaver/public/images/header.png +0 -0
  69. data/lib/cortex_reaver/public/images/header.xcf +0 -0
  70. data/lib/cortex_reaver/public/images/header_background.png +0 -0
  71. data/lib/cortex_reaver/public/images/parent.gif +0 -0
  72. data/lib/cortex_reaver/public/images/rss-xml-icon.png +0 -0
  73. data/lib/cortex_reaver/public/images/sections.png +0 -0
  74. data/lib/cortex_reaver/public/images/sections_highlight.png +0 -0
  75. data/lib/cortex_reaver/public/js/admin.js +36 -0
  76. data/lib/cortex_reaver/public/js/cookie.js +27 -0
  77. data/lib/cortex_reaver/public/js/jquery.js +32 -0
  78. data/lib/cortex_reaver/public/js/photo.js +33 -0
  79. data/lib/cortex_reaver/snippets/array.rb +7 -0
  80. data/lib/cortex_reaver/snippets/ramaze/dispatcher/file.rb +37 -0
  81. data/lib/cortex_reaver/support/attachments.rb +235 -0
  82. data/lib/cortex_reaver/support/cached_rendering.rb +79 -0
  83. data/lib/cortex_reaver/support/canonical.rb +107 -0
  84. data/lib/cortex_reaver/support/comments.rb +69 -0
  85. data/lib/cortex_reaver/support/pagination.rb +38 -0
  86. data/lib/cortex_reaver/support/renderer.rb +196 -0
  87. data/lib/cortex_reaver/support/sequenceable.rb +248 -0
  88. data/lib/cortex_reaver/support/tags.rb +108 -0
  89. data/lib/cortex_reaver/support/timestamps.rb +33 -0
  90. data/lib/cortex_reaver/version.rb +8 -0
  91. data/lib/cortex_reaver/view/adminbox.rhtml +56 -0
  92. data/lib/cortex_reaver/view/blank_layout.rhtml +46 -0
  93. data/lib/cortex_reaver/view/comments/comment.rhtml +34 -0
  94. data/lib/cortex_reaver/view/comments/form.rhtml +25 -0
  95. data/lib/cortex_reaver/view/comments/list.rhtml +5 -0
  96. data/lib/cortex_reaver/view/comments/post_form.rhtml +36 -0
  97. data/lib/cortex_reaver/view/config/form.rhtml +10 -0
  98. data/lib/cortex_reaver/view/error.rhtml +72 -0
  99. data/lib/cortex_reaver/view/journals/form.rhtml +12 -0
  100. data/lib/cortex_reaver/view/journals/journal.rhtml +39 -0
  101. data/lib/cortex_reaver/view/journals/list.rhtml +33 -0
  102. data/lib/cortex_reaver/view/journals/short.rhtml +3 -0
  103. data/lib/cortex_reaver/view/journals/show.rhtml +5 -0
  104. data/lib/cortex_reaver/view/pages/form.rhtml +12 -0
  105. data/lib/cortex_reaver/view/pages/list.rhtml +26 -0
  106. data/lib/cortex_reaver/view/pages/show.rhtml +12 -0
  107. data/lib/cortex_reaver/view/photographs/atom_fragment.rhtml +82 -0
  108. data/lib/cortex_reaver/view/photographs/form.rhtml +19 -0
  109. data/lib/cortex_reaver/view/photographs/grid.rhtml +36 -0
  110. data/lib/cortex_reaver/view/photographs/list.rhtml +9 -0
  111. data/lib/cortex_reaver/view/photographs/short.rhtml +3 -0
  112. data/lib/cortex_reaver/view/photographs/show.rhtml +114 -0
  113. data/lib/cortex_reaver/view/photographs/sidebar.rhtml +7 -0
  114. data/lib/cortex_reaver/view/projects/form.rhtml +13 -0
  115. data/lib/cortex_reaver/view/projects/list.rhtml +27 -0
  116. data/lib/cortex_reaver/view/projects/show.rhtml +38 -0
  117. data/lib/cortex_reaver/view/tags/form.rhtml +9 -0
  118. data/lib/cortex_reaver/view/tags/list.rhtml +28 -0
  119. data/lib/cortex_reaver/view/tags/show.rhtml +51 -0
  120. data/lib/cortex_reaver/view/text_layout.rhtml +78 -0
  121. data/lib/cortex_reaver/view/users/form.rhtml +16 -0
  122. data/lib/cortex_reaver/view/users/list.rhtml +38 -0
  123. data/lib/cortex_reaver/view/users/login.rhtml +13 -0
  124. data/lib/cortex_reaver/view/users/register.rhtml +13 -0
  125. data/lib/cortex_reaver/view/users/show.rhtml +37 -0
  126. data/lib/cortex_reaver/view/users/user.rhtml +35 -0
  127. data/lib/proto/cortex_reaver.yaml +28 -0
  128. metadata +285 -0
@@ -0,0 +1,79 @@
1
+ module CortexReaver
2
+ module Model
3
+
4
+ # On save, calls a special rendering method on configured attributes, and
5
+ # saves the results to their cache.
6
+ module CachedRendering
7
+ require 'ostruct'
8
+
9
+ def self.included(base)
10
+ base.class_eval do
11
+ # Before save, render all changed caching fields
12
+ before_save(:render_to_cache) do
13
+ # Get changed fields to render
14
+ if new?
15
+ changed = columns.map { |c| c.to_sym }
16
+ else
17
+ changed = changed_columns.map { |c| c.to_sym }
18
+ end
19
+ fields = render_fields.select do |k, v|
20
+ changed.include? k.to_sym
21
+ end
22
+
23
+ fields.each do |name, field|
24
+ # Render and cache
25
+ self[field.to] = self.send(field.with, self[name])
26
+ end
27
+ end
28
+
29
+ # Refreshes all records with cached fields.
30
+ def self.refresh_render_caches
31
+ # TODO: inefficient, but Model.each breaks Sequel in validation
32
+ # "commands out of sync"
33
+ all.each do |record|
34
+ # Mark all caching columns as changed, so the before_save hook
35
+ # processes them.
36
+ record.skip_timestamp_update = true
37
+ render_fields.keys.each do |column|
38
+ record.changed_columns << column
39
+ end
40
+ record.save
41
+ end
42
+ nil
43
+ end
44
+
45
+ # Assigns a field to cache
46
+ #
47
+ # render :body, :with => 'wikify', :to => 'cached_body'
48
+ #
49
+ # ... calls #wikify on the value of self.body, and stores the result
50
+ # in self.cached_body. :to defaults to the field name with _cache
51
+ # appended. :with defaults to :render.
52
+ def self.render(field, params = {})
53
+ # Assign parameters
54
+ params = {
55
+ :to => (field.to_s + '_cache').to_sym,
56
+ :with => :render
57
+ }.merge!(params)
58
+
59
+ # Store field
60
+ render_fields[field] = OpenStruct.new(params)
61
+ end
62
+
63
+ def self.render_fields
64
+ @render_fields ||= {}
65
+ end
66
+ end
67
+ end
68
+
69
+ # Default renderer
70
+ def render(value)
71
+ value
72
+ end
73
+
74
+ def render_fields
75
+ self.class.render_fields
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,107 @@
1
+ module CortexReaver
2
+ module Model
3
+ # Supports canonical, url-safe identifiers for records, inferred from other
4
+ # fields.
5
+ module Canonical
6
+
7
+ # The canonical name attribute
8
+ CANONICAL_NAME_ATTR = :name
9
+ # The attribute we infer the canonical name from, if not set.
10
+ CANONICAL_INFERENCE_ATTR = :title
11
+
12
+ def self.included(base)
13
+ base.class_eval do
14
+ # Canonical names which cannot be reserved.
15
+ def self.reserved_canonical_names
16
+ @reserved_canonical_names ||= []
17
+ end
18
+
19
+ def self.reserved_canonical_names=(names)
20
+ @reserved_canonical_names = names
21
+ end
22
+
23
+ # Canonicalize a string. Optionally, ignore conflicts with the record
24
+ # with id.
25
+ def self.canonicalize(string, id = nil)
26
+ # Lower case, remove special chars, and replace with hyphens.
27
+ proper = string.downcase.gsub(/[^a-z0-9_]/, '-').squeeze('-')[0..250].sub(/-$/, '')
28
+
29
+ # If proper is blank, just return it at this point.
30
+ if proper.blank?
31
+ return proper
32
+ end
33
+
34
+ # Numeric suffix to append
35
+ suffix = nil
36
+
37
+ if proper != filter(:id => id).map(canonical_name_attr).first
38
+ # We don't already have this name.
39
+
40
+ similar = []
41
+
42
+ if filter(canonical_name_attr => proper).limit(1).count > 0
43
+ similar << proper
44
+ # This name already exists, and it's not ours!
45
+ similar += filter(canonical_name_attr.like(/^#{proper}\-[0-9]+$/)).map(canonical_name_attr)
46
+ end
47
+
48
+ # Check for reserved names
49
+ reserved_canonical_names.each do |name|
50
+ if name =~ /^#{proper}(-\d+)?$/
51
+ similar << name
52
+ end
53
+ end
54
+
55
+ # Find possible conflicting names from actions on this model's controller.
56
+ # if self.respond_to? :url and controller = Ramaze::Controller.at(self.url)
57
+ # similar += controller.action_methods.select do |action|
58
+ # action =~ /^#{proper}(-\d+)?$/
59
+ # end
60
+ # end
61
+
62
+ # Extract numeric suffices
63
+ suffices = {}
64
+ similar.each do |name|
65
+ suffices[name[/\d$/].to_i] = true
66
+ end
67
+
68
+ # Compute suffix
69
+ unless suffices.empty?
70
+ i = 1
71
+ while suffices.include? i
72
+ i += 1
73
+ end
74
+ suffix = i
75
+ end
76
+ end
77
+
78
+ if suffix
79
+ proper + '-' + suffix.to_s
80
+ else
81
+ proper
82
+ end
83
+ end
84
+
85
+ # Sets the attribute we infer the canonical name from to attr, or
86
+ # gets that attr if nil.
87
+ def self.canonical_inference_attr(attr = nil)
88
+ if attr
89
+ @canonical_inference_attr = attr.to_sym
90
+ else
91
+ @canonical_inference_attr || CANONICAL_INFERENCE_ATTR
92
+ end
93
+ end
94
+
95
+ # Sets the canonical name attribute to attr. Returns it if nil.
96
+ def self.canonical_name_attr(attr = nil)
97
+ if attr
98
+ @canonical_name_attr = attr.to_sym
99
+ else
100
+ @canonical_name_attr || CANONICAL_NAME_ATTR
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,69 @@
1
+ module CortexReaver
2
+ module Model
3
+ # Support methods for comments on models
4
+ module Comments
5
+ def self.included(base)
6
+ base.class_eval do
7
+ # When we delete a model that has comments, remove the comments too.
8
+ before_delete(:drop_comments) do
9
+ comments = self.comments
10
+ remove_all_comments
11
+ comments.each do |comment|
12
+ comment.destroy
13
+ end
14
+ end
15
+
16
+ # Refresh all comment counts
17
+ def self.refresh_comment_counts
18
+ all.each do |model|
19
+ model.refresh_comment_count
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ # Recalculates the number of comments on this record (and all comments
26
+ # below it, recursively) and saves those values. Returns the comment
27
+ # count on this record.
28
+ def refresh_comment_count
29
+ count = 0
30
+ comments.each do |comment|
31
+ # Recalculate for sub-comments and sum.
32
+ count += comment.refresh_comment_count + 1
33
+ end
34
+ self[:comment_count] = count
35
+ self.skip_timestamp_update = true
36
+
37
+ # Save and return
38
+ self.save
39
+ self[:comment_count]
40
+ end
41
+
42
+ # Returns the parent of a given comment. Caches, pass true to refresh.
43
+ def parent(refresh = false)
44
+ if refresh or @parent_cache.nil?
45
+ [:comment, :journal, :photograph, :project, :page].each do |p|
46
+ if self.respond_to?(p) and parent = self.send(p)
47
+ # We found an applicable parent.
48
+ @parent_cache = parent
49
+ return parent
50
+ end
51
+ end
52
+ # We didn't find any parent
53
+ nil
54
+ else
55
+ @parent_cache
56
+ end
57
+ end
58
+
59
+ # Returns the top-level parent of a given comment.
60
+ def root_parent
61
+ if parent
62
+ parent.root_parent
63
+ else
64
+ self
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,38 @@
1
+ module CortexReaver
2
+ module Model
3
+ # Defines class-level accessors for page size, order attribute, etc.
4
+ module Pagination
5
+ DEFAULT_SIZE = 16
6
+ DEFAULT_ORDER = 'created_on'
7
+ DEFAULT_REVERSE = false
8
+
9
+ def self.included(base)
10
+ base.class_eval do
11
+ class << self
12
+ attr_accessor :page_size, :page_order, :page_reverse
13
+ end
14
+
15
+ @page_size ||= CortexReaver::Model::Pagination::DEFAULT_SIZE
16
+ @page_order ||= CortexReaver::Model::Pagination::DEFAULT_ORDER
17
+ @page_reverse ||= CortexReaver::Model::Pagination::DEFAULT_REVERSE
18
+ end
19
+
20
+ # Returns a paginated dataset at page number. Optionally, filters on
21
+ # dataset instead of the whole model.
22
+ def page(number, dataset = self.dataset)
23
+ if reverse
24
+ dataset = dataset.reverse
25
+ end
26
+
27
+ dataset.order(@order).paginate(number, @page_size)
28
+ end
29
+ end
30
+
31
+ # Returns the page number for this model. Optionally, filters on dataset
32
+ # rather than the whole model.
33
+ def page_number(dataset = self.class.dataset)
34
+
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,196 @@
1
+ module CortexReaver
2
+ module Model
3
+ # Some common rendering methods, wrapped up for your convenience. Use in your model
4
+ # with something like:
5
+ #
6
+ # render :body, :with => :render_comment
7
+ #
8
+ # See CortexReaver::Model::CachedRendering for more details.
9
+ module Renderer
10
+ require 'bluecloth'
11
+ require 'hpricot'
12
+ require 'syntax'
13
+
14
+ # Elements to allow in sanitized HTML.
15
+ ELEMENTS = [
16
+ 'a', 'b', 'blockquote', 'br', 'code', 'dd', 'dl', 'dt', 'em', 'i', 'li',
17
+ 'ol', 'p', 'pre', 'small', 'strike', 'strong', 'sub', 'sup', 'u', 'ul'
18
+ ]
19
+
20
+ # Attributes to allow in sanitized HTML elements.
21
+ ATTRIBUTES = {
22
+ 'a' => ['href', 'title'],
23
+ 'pre' => ['class']
24
+ }
25
+
26
+ # Attributes to add to sanitized HTML elements.
27
+ ADD_ATTRIBUTES = {
28
+ 'a' => {'rel' => 'nofollow'}
29
+ }
30
+
31
+ # Attributes that should be checked for valid protocols.
32
+ PROTOCOL_ATTRIBUTES = {'a' => ['href']}
33
+
34
+ # Valid protocols.
35
+ PROTOCOLS = ['ftp', 'http', 'https', 'mailto']
36
+
37
+
38
+ # Renders plain text and html to html.
39
+ def bluecloth(text)
40
+ return text if text.nil?
41
+
42
+ BlueCloth::new(text).to_html
43
+ end
44
+
45
+ # Replace <% and %> to prevent Erubis injection.
46
+ def erubis_filter(text)
47
+ return text if text.nil?
48
+
49
+ t = text.dup
50
+ t.gsub!('<%', '&lt;%')
51
+ t.gsub!('%>', '%&rt;')
52
+ t
53
+ end
54
+
55
+ # Macro substitutions
56
+ #
57
+ # Expands [[type:resource][name]] macros. Right now, resource is just an attachment.
58
+ # Included types are:
59
+ #
60
+ # url: returns the URL to an attachment
61
+ # image: returns an image tag
62
+ # link: returns a link to an attachment
63
+ #
64
+ # The default action is a link, so
65
+ #
66
+ # [[foo.jpg]] => <a href="/data/.../foo.jpg">foo.jpg</a>
67
+ def macro(text)
68
+ return text if text.nil?
69
+
70
+ copy = text.dup
71
+
72
+ # Links
73
+ #
74
+ # Example [[image:foo.png][name]]
75
+ # 1. the link type prefix image:
76
+ # 2. the link type, sans-colon image
77
+ # 3. the link itself foo.png
78
+ # 4. the second half of the link [name]
79
+ # 5. the name name
80
+ copy.gsub!(/\[\[(([^\]]+):)?([^\]]+)(\]\[([^\]]+))?\]\]/) do |match|
81
+ prefix = $2
82
+ path = $3
83
+ name = $5
84
+
85
+ # Find the link target
86
+ target = attachment(path)
87
+
88
+ if target.exists?
89
+ # Name of the link
90
+ name ||= path
91
+
92
+ # Create link to this target
93
+ case prefix
94
+ when 'image'
95
+ # Create an inline image
96
+ "<img src=\"#{target.public_path}\" alt=\"#{name.gsub('"', '&quot;')}\" title=\"#{name.gsub('"', '&quot')}\" />"
97
+ when 'url'
98
+ # Create a URL
99
+ target.public_path
100
+ else
101
+ # Create a full link
102
+ "<a href=\"#{target.public_path}\">#{Rack::Utils.escape_html(name).gsub(/#([{@$]@?)/, '&#35;\1')}</a>"
103
+ end
104
+ else
105
+ # Don't create a link
106
+ match
107
+ end
108
+ end
109
+
110
+ copy
111
+ end
112
+
113
+ def syntax_highlight(text)
114
+ return text if text.nil?
115
+
116
+ h = Hpricot(text)
117
+
118
+ h.search('cr:code').replace do |code|
119
+ code[:lang]
120
+ end
121
+ end
122
+
123
+ # Stolen wholesale from Ryan's Thoth (http://github.com/rgrove/thoth/)
124
+ # Who adapted it from http://rid.onkulo.us/archives/14-sanitizing-html-with-ruby-and-hpricot
125
+ def sanitize_html(html)
126
+ return html if html.nil?
127
+
128
+ h = Hpricot(html)
129
+
130
+ h.search('*').each do |el|
131
+ if el.elem?
132
+ tag = el.name.downcase
133
+
134
+ if ELEMENTS.include?(tag)
135
+ if ATTRIBUTES.has_key?(tag)
136
+ # Delete any attribute that isn't in the whitelist for this
137
+ # particular element.
138
+ el.raw_attributes.delete_if do |key, val|
139
+ !ATTRIBUTES[tag].include?(key.downcase)
140
+ end
141
+
142
+ # Check applicable attributes for valid protocols.
143
+ if PROTOCOL_ATTRIBUTES.has_key?(tag)
144
+ el.raw_attributes.delete_if do |key, val|
145
+ PROTOCOL_ATTRIBUTES[tag].include?(key.downcase) &&
146
+ (!(val.downcase =~ /^([^:]+)\:/) || !PROTOCOLS.include?($1))
147
+ end
148
+ end
149
+ else
150
+ # Delete all attributes from elements with no whitelisted
151
+ # attributes.
152
+ el.raw_attributes = {}
153
+ end
154
+
155
+ # Add required attributes.
156
+ if ADD_ATTRIBUTES.has_key?(tag)
157
+ el.raw_attributes.merge!(ADD_ATTRIBUTES[tag])
158
+ end
159
+ else
160
+ # Delete any element that isn't in the whitelist.
161
+ el.parent.replace_child(el, el.children)
162
+ end
163
+ elsif el.comment?
164
+ # Delete all comments, since it's possible to make IE execute JS
165
+ # within conditional comments.
166
+ el.swap('')
167
+ end
168
+ end
169
+
170
+ h.to_s
171
+ end
172
+
173
+ # Default renderer
174
+ def render(text)
175
+ bluecloth(
176
+ macro(
177
+ erubis_filter(
178
+ text
179
+ )
180
+ )
181
+ ) # (((Feeling) LISPish yet)?)
182
+ end
183
+
184
+ # Comments render
185
+ def render_comment(text)
186
+ bluecloth(
187
+ erubis_filter(
188
+ sanitize_html(
189
+ text
190
+ )
191
+ )
192
+ )
193
+ end
194
+ end
195
+ end
196
+ end