diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index c6f743dd4a64e72db295a25def14604a8c454c3f..02db2caf5920f0ed87780949f0a517948889441f 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -396,13 +396,14 @@ module ApplicationHelper text = args.shift when 2 obj = args.shift - text = obj.send(args.shift).to_s + attr = args.shift + text = obj.send(attr).to_s else raise ArgumentError, 'invalid arguments to textilizable' end return '' if text.blank? - text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text) { |macro, args| exec_macro(macro, obj, args) } + text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr) { |macro, args| exec_macro(macro, obj, args) } only_path = options.delete(:only_path) == false ? false : true diff --git a/app/views/settings/_general.rhtml b/app/views/settings/_general.rhtml index ff0dde3572db9fab58360d16dd501e9e9094e2b0..a2f014528edbb8b5bd4e63499c683404b026370b 100644 --- a/app/views/settings/_general.rhtml +++ b/app/views/settings/_general.rhtml @@ -20,6 +20,8 @@

<%= setting_select :text_formatting, Redmine::WikiFormatting.format_names.collect{|name| [name, name.to_s]}, :blank => :label_none %>

+

<%= setting_check_box :cache_formatted_text %>

+

<%= setting_select :wiki_compression, [['Gzip', 'gzip']], :blank => :label_none %>

<%= setting_text_field :feeds_limit, :size => 6 %>

diff --git a/config/environment.rb b/config/environment.rb index 97fc54adb46b274498f3e5563c970ba2a6f03973..f89695f468fe2492b9101957046d0dbf0c609093 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -32,7 +32,7 @@ Rails::Initializer.run do |config| # Enable page/fragment caching by setting a file-based store # (remember to create the caching directory and make it readable to the application) - # config.action_controller.fragment_cache_store = :file_store, "#{RAILS_ROOT}/cache" + # config.action_controller.cache_store = :file_store, "#{RAILS_ROOT}/tmp/cache" # Activate observers that should always be running # config.active_record.observers = :cacher, :garbage_collector diff --git a/config/locales/bg.yml b/config/locales/bg.yml index d48c09314c385ec8a9ed4d57eb76500e6b0bb6ed..6e87d6006c693ad2bf0c1fcb8e595d5c09d98f8a 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -879,3 +879,4 @@ bg: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/bs.yml b/config/locales/bs.yml index 6d297fefe4bc5f9e7361f5c95f24bd0565411881..54d6589cfeea77fed63b16951e91e9faf6841a85 100644 --- a/config/locales/bs.yml +++ b/config/locales/bs.yml @@ -903,3 +903,4 @@ bs: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/ca.yml b/config/locales/ca.yml index dc033a24eb2d5148a79678ec1a32c21950316ca6..878cb1ee227e8d43bb30b33052a4db0a048aaa3b 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -882,3 +882,4 @@ ca: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/cs.yml b/config/locales/cs.yml index dd4cea30bd05be52fe056ee423e7ae24ab02f6ef..5ca186bc2766fc1bc7649286e35a9daebe4edc80 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -885,3 +885,4 @@ cs: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/da.yml b/config/locales/da.yml index 1da8ac2fcf486e2c1fb0b8fb484a5d4e195535b5..cdee28158ab788f021c7e000103dadac5756f28b 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -905,3 +905,4 @@ da: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/de.yml b/config/locales/de.yml index ddb292c5d3f026c83270161d8a35f559c4320082..f8a7c9f5c8be0ab134417529d04b1d9005202d66 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -905,3 +905,4 @@ de: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/el.yml b/config/locales/el.yml index 3943cb5c37aea8c3f5c24ff8dae62942803b9547..c5d4f15a6ee97875640ce70d77c1d530d57b040f 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -885,3 +885,4 @@ el: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/en.yml b/config/locales/en.yml index c8b0ddbeee787a5964291e037f4a231551c42caa..8109e5731f8f2aec254a01e9052d290e575c4956 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -329,6 +329,7 @@ en: setting_issue_done_ratio_issue_status: Use the issue status setting_start_of_week: Start calendars on setting_rest_api_enabled: Enable REST web service + setting_cache_formatted_text: Cache formatted text permission_add_project: Create project permission_add_subprojects: Create subprojects diff --git a/config/locales/es.yml b/config/locales/es.yml index 8bc7c8c18d207d435b1ab572af39d17a248b69e1..b34bfdb757af2e684784044955798ec6dcb6de1b 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -929,3 +929,4 @@ es: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/eu.yml b/config/locales/eu.yml index 04bb5c5b7a07fb897586a5bc2192dd71d91c790a..35408067e8888bda8475d6d6461b7abb1aedf150 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -889,3 +889,4 @@ eu: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 9ed111556d3dd66a66b0ad0458bccb267da5b909..3a7cbea65d22e343ac9e71984b9ea2edc1246c9f 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -915,3 +915,4 @@ fi: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 99c4361f08f89669d24cc9ff4ccdb8b74c1a2ecb..663b6f70316e7c0fec704264b8ab0e4469e5d15d 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -352,6 +352,7 @@ fr: setting_rest_api_enabled: Activer l'API REST setting_gravatar_default: Image Gravatar par défaut setting_start_of_week: Jour de début des calendriers + setting_cache_formatted_text: Mettre en cache le texte formaté permission_add_project: Créer un projet permission_add_subprojects: Créer des sous-projets diff --git a/config/locales/gl.yml b/config/locales/gl.yml index b606ad46de668648ed1945da017847f7fb6876e5..deb85638fc0c560391bbac980bc29ec9a67fb525 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -905,3 +905,4 @@ gl: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/he.yml b/config/locales/he.yml index c2604ee5078732de771ccdf95c8cc466ab47e505..1e2ecc68b0f3869acace3a89bc86d4c1b6231fb2 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -889,3 +889,4 @@ he: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/hr.yml b/config/locales/hr.yml index 4244e5b6cdd59964491acc64a8b90cf9a6f69652..7ee3deff82c6830955c6b48f2733a408bf1dcaef 100644 --- a/config/locales/hr.yml +++ b/config/locales/hr.yml @@ -892,3 +892,4 @@ hr: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/hu.yml b/config/locales/hu.yml index f419aa301286e7b804daf2caff04ded2a71c1bd9..7fac563efa773b21831e6de4909ed6fb33b8dfc0 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -910,3 +910,4 @@ label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/id.yml b/config/locales/id.yml index db92948aef28dc6cafdfce9e90e984661f3330a7..cf63d733a92a6e439940e6d284696fb165ace16a 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -897,3 +897,4 @@ id: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/it.yml b/config/locales/it.yml index a3c12ad3fa84ad9983ffbc2a5fbf17a8af8d350f..334e88597b64a7e0573a1af502794e6b5015504c 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -892,3 +892,4 @@ it: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 4a0fb894159ac4a9a725153fb39fa32a96d9169f..69a8c09ebcef4927d8b7f928c7c9d377d4aba10e 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -914,3 +914,4 @@ ja: enumeration_activities: 作業分類 (時間トラッキング) enumeration_system_activity: システム作業分類 permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 99fc180b3f804eb03678ed26d17da45c12f3b0af..0edb2b5466f8732e37056f6a184c7c4c7dccc850 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -945,3 +945,4 @@ ko: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/lt.yml b/config/locales/lt.yml index 43158bccac9031a15b7134bec5b7504f4802df72..e49c09f22a59a772e8d803faa19cb396515d85ce 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -953,3 +953,4 @@ lt: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 024db3238d60d2c34c9866a81b424de1451d592b..a5f69b3b41504170b91e5b31192161aac9005660 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -867,3 +867,4 @@ nl: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/no.yml b/config/locales/no.yml index 726dadb4617384140b66b68bd7c515af69bff6d2..39c54a9f4e63aad88cf9ddc51e5de71e0e8a932c 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -880,3 +880,4 @@ label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 5d4e62e55c2e9fff25baad555f455c893b498955..40605bbacdaa12e46b56c1f41e52486a0d9cf9a7 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -910,3 +910,4 @@ pl: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 53f968ad181e829317208ce51ffdeb97692360ec..17647e45d61ddf87c20ffb5ad55a7dd1cbfc4dde 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -913,3 +913,4 @@ pt-BR: label_board_locked: Travado label_change_log: Registro de alterações permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 5d9d8ce46fe15108c348974eaca5923230bb8b33..6a25981ae3ae11afab3e293df251a94dc4ccc6a8 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -897,3 +897,4 @@ pt: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/ro.yml b/config/locales/ro.yml index 257cf8e1962b64250e40cefeb4e1068b4bba3734..bfefe51807efb4e27b4baf8dec17caaa3b38601b 100644 --- a/config/locales/ro.yml +++ b/config/locales/ro.yml @@ -882,3 +882,4 @@ ro: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 2dd495212fb94caefb78adf1c180845b65fbdf1a..5821f0ba3ebeab03a8197ef64ad0bce53130e33d 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -993,3 +993,4 @@ ru: label_board_sticky: Прикреплена label_board_locked: Заблокирована permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/sk.yml b/config/locales/sk.yml index c1070ab161f9ed1719d835d5294c85e115469670..ce86fc33fb7adf5856110e05390554254ddc0b3f 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -884,3 +884,4 @@ sk: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/sl.yml b/config/locales/sl.yml index b12c77d781d6f21330e06b59e9b7d30a882a2491..7967deeabdb4b86fce38ba5eb2b1f8d7a9a26c6c 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -881,3 +881,4 @@ sl: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/sr.yml b/config/locales/sr.yml index 28eaaaa3c23c925592188628c6d4325042b16459..6b8c7ed318afc1e470ff47aa398eeb05ecf26744 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -900,3 +900,4 @@ label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/sv.yml b/config/locales/sv.yml index d0488ad968f159f1ced1ff68fa54d5768ddd6da0..cca36ec83caa60d8d19ccb3d23f96c6bc2b48f6e 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -934,3 +934,4 @@ sv: enumeration_activities: Aktiviteter (tidsuppföljning) enumeration_system_activity: Systemaktivitet permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/th.yml b/config/locales/th.yml index c5982851f2af8bb6ec48fb4193deddd500c85efa..35461ab15542094679dba08b9a4cff8a8e319075 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -882,3 +882,4 @@ th: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 86b365d85d45780b2a86362eb97b3788580ad1a6..482dcfa5e31d7f6435374217f32e9bda4df686aa 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -912,3 +912,4 @@ tr: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 4ae064d69b27a531cb1e80cd69cf5f003ee7fc3a..f813559bc4444c7aea6d0eff6e7ca87ba860f43b 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -881,3 +881,4 @@ uk: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/vi.yml b/config/locales/vi.yml index c66cdd53b0136e4505b19f5f7ca7974a06bc0164..a359ed230124e48a87773070c87689f52f21c014 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -944,3 +944,4 @@ vi: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index db5bfa2e8336545f89f9bf629f705c479c4533c7..28aedbc629ba8f40cc7c8b1758f60512bfdbccc8 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -976,3 +976,4 @@ enumeration_activities: 活動 (時間追蹤) enumeration_system_activity: 系統活動 permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/locales/zh.yml b/config/locales/zh.yml index 8e7dc4d1cd6dc25cf60349c2d9cde06ed8cd5c42..50f4867837f3fb4e6871d9ccd991057630999dbf 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -907,3 +907,4 @@ zh: label_board_sticky: Sticky label_board_locked: Locked permission_export_wiki_pages: Export wiki pages + setting_cache_formatted_text: Cache formatted text diff --git a/config/settings.yml b/config/settings.yml index cebfbb50011952f6f4bcc396543f8f931e2a2a77..1e905ede3d9c2bd251e81409ab59b6ec796e0453 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -53,6 +53,8 @@ plain_text_mail: default: 0 text_formatting: default: textile +cache_formatted_text: + default: 0 wiki_compression: default: "" default_language: diff --git a/lib/redmine/wiki_formatting.rb b/lib/redmine/wiki_formatting.rb index f33ef9e6d223b65a1cf0124c30621aa69d5524ba..21e8be66be32d5449c197ca4226c126cd5efa2c8 100644 --- a/lib/redmine/wiki_formatting.rb +++ b/lib/redmine/wiki_formatting.rb @@ -44,7 +44,58 @@ module Redmine end def to_html(format, text, options = {}, &block) - formatter_for(format).new(text).to_html(&block) + text = if Setting.cache_formatted_text? && text.size > 2.kilobyte && cache && cache_key = cache_key_for(format, options[:object], options[:attribute]) + # Text retrieved from the cache store may be frozen + # We need to dup it so we can do in-place substitutions with gsub! + cache.fetch cache_key do + formatter_for(format).new(text).to_html + end.dup + else + formatter_for(format).new(text).to_html + end + if block_given? + execute_macros(text, block) + end + text + end + + # Returns a cache key for the given text +format+, +object+ and +attribute+ or nil if no caching should be done + def cache_key_for(format, object, attribute) + if object && attribute && !object.new_record? && object.respond_to?(:updated_on) && !format.blank? + "formatted_text/#{format}/#{object.class.model_name.cache_key}/#{object.id}-#{attribute}-#{object.updated_on.to_s(:number)}" + end + end + + # Returns the cache store used to cache HTML output + def cache + ActionController::Base.cache_store + end + + MACROS_RE = / + (!)? # escaping + ( + \{\{ # opening tag + ([\w]+) # macro name + (\(([^\}]*)\))? # optional arguments + \}\} # closing tag + ) + /x unless const_defined?(:MACROS_RE) + + # Macros substitution + def execute_macros(text, macros_runner) + text.gsub!(MACROS_RE) do + esc, all, macro = $1, $2, $3.downcase + args = ($5 || '').split(',').each(&:strip) + if esc.nil? + begin + macros_runner.call(macro, args) + rescue => e + "
Error executing the #{macro} macro (#{e})
" + end || all + else + all + end + end end end diff --git a/lib/redmine/wiki_formatting/textile/formatter.rb b/lib/redmine/wiki_formatting/textile/formatter.rb index 7e20c7bfcb1c19fc67d0bdef9a1d51d5e859d1a1..ab66ba5b707529b94ade42e20899bfb35ff2de68 100644 --- a/lib/redmine/wiki_formatting/textile/formatter.rb +++ b/lib/redmine/wiki_formatting/textile/formatter.rb @@ -24,7 +24,7 @@ module Redmine class Formatter < RedCloth3 # auto_link rule after textile rules so that it doesn't break !image_url! tags - RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto, :inline_toc, :inline_macros] + RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto, :inline_toc] def initialize(*args) super @@ -33,9 +33,8 @@ module Redmine self.filter_styles=true end - def to_html(*rules, &block) + def to_html(*rules) @toc = [] - @macros_runner = block super(*RULES).to_s end @@ -102,32 +101,6 @@ module Redmine end end - MACROS_RE = / - (!)? # escaping - ( - \{\{ # opening tag - ([\w]+) # macro name - (\(([^\}]*)\))? # optional arguments - \}\} # closing tag - ) - /x unless const_defined?(:MACROS_RE) - - def inline_macros(text) - text.gsub!(MACROS_RE) do - esc, all, macro = $1, $2, $3.downcase - args = ($5 || '').split(',').each(&:strip) - if esc.nil? - begin - @macros_runner.call(macro, args) - rescue => e - "
Error executing the #{macro} macro (#{e})
" - end || all - else - all - end - end - end - AUTO_LINK_RE = %r{ ( # leading text <\w+.*?>| # leading HTML tag, or