diff --git a/README.md b/README.md index cd6bb94a..cb4d7395 100644 --- a/README.md +++ b/README.md @@ -80,8 +80,8 @@ choose. Special footers can be created in `footer files`. Other content ## PAGE FILES Page files may be written in any format supported by -[GitHub-Markup](http://github.com/github/markup) (except roff). The -current list of formats and allowed extensions is: +[GitHub-Markup](http://github.com/github/markup) (except roff). By default, +Gollum recognizes the following extensions: * ASCIIDoc: .asciidoc * Creole: .creole @@ -93,8 +93,14 @@ current list of formats and allowed extensions is: * Textile: .textile * MediaWiki: .mediawiki, .wiki +You may also register your own extensions and parsers: + + Gollum::Markup.register(:angry, "Angry") do |content| + content.upcase + end + Gollum detects the page file format via the extension, so files must have one -of the supported extensions in order to be converted. +of the default or registered extensions in order to be converted. Page file names may contain any printable UTF-8 character except space (U+0020) and forward slash (U+002F). If you commit a page file with any of diff --git a/lib/gollum.rb b/lib/gollum.rb index e4d33d31..b1eec708 100644 --- a/lib/gollum.rb +++ b/lib/gollum.rb @@ -19,6 +19,7 @@ require File.expand_path('../gollum/page', __FILE__) require File.expand_path('../gollum/file', __FILE__) require File.expand_path('../gollum/file_view', __FILE__) require File.expand_path('../gollum/markup', __FILE__) +require File.expand_path('../gollum/markups', __FILE__) require File.expand_path('../gollum/sanitization', __FILE__) require File.expand_path('../gollum/web_sequence_diagram', __FILE__) require File.expand_path('../gollum/frontend/uri_encode_component', __FILE__) diff --git a/lib/gollum/frontend/views/editable.rb b/lib/gollum/frontend/views/editable.rb index 6f9ac51b..365573ad 100644 --- a/lib/gollum/frontend/views/editable.rb +++ b/lib/gollum/frontend/views/editable.rb @@ -1,8 +1,8 @@ module Precious module Editable def formats(selected = @page.format) - Gollum::Page::FORMAT_NAMES.map do |key, val| - { :name => val, + Gollum::Markup.formats.map do |key, val| + { :name => val[:name], :id => key.to_s, :selected => selected == key} end.sort do |a, b| diff --git a/lib/gollum/markup.rb b/lib/gollum/markup.rb index 6d69a9e2..1df5df15 100644 --- a/lib/gollum/markup.rb +++ b/lib/gollum/markup.rb @@ -15,6 +15,28 @@ module Gollum class Markup include Precious::Helpers + @formats = {} + + class << self + attr_reader :formats + + # Register a file extension and associated markup type + # + # ext - The file extension + # name - The name of the markup type + # options - Hash of options: + # regexp - Regexp to match against. + # Defaults to exact match of ext. + # + # If given a block, that block will be registered with GitHub::Markup to + # render any matching pages + def register(ext, name, options = {}, &block) + regexp = options[:regexp] || Regexp.new(ext.to_s) + @formats[ext] = { :name => name, :regexp => regexp } + GitHub::Markup.add_markup(regexp, &block) if block_given? + end + end + attr_accessor :toc attr_reader :metadata diff --git a/lib/gollum/markups.rb b/lib/gollum/markups.rb new file mode 100644 index 00000000..53f45ed3 --- /dev/null +++ b/lib/gollum/markups.rb @@ -0,0 +1,13 @@ +module Gollum + class Markup + register(:markdown, "Markdown", :regexp => /md|mkdn?|mdown|markdown/) + register(:textile, "Textile") + register(:rdoc, "RDoc") + register(:org, "Org-mode") + register(:creole, "Creole") + register(:rest, "reStructuredText", :regexp => /re?st(\.txt)?/) + register(:asciidoc, "AsciiDoc") + register(:mediawiki, "MediaWiki", :regexp => /(media)?wiki/) + register(:pod, "Pod") + end +end \ No newline at end of file diff --git a/lib/gollum/page.rb b/lib/gollum/page.rb index 9a295158..2106ed42 100644 --- a/lib/gollum/page.rb +++ b/lib/gollum/page.rb @@ -5,17 +5,6 @@ module Gollum Wiki.page_class = self - VALID_PAGE_RE = /^(.+)\.(md|mkdn?|mdown|markdown|textile|rdoc|org|creole|re?st(\.txt)?|asciidoc|pod|(media)?wiki)$/i - FORMAT_NAMES = { :markdown => "Markdown", - :textile => "Textile", - :rdoc => "RDoc", - :org => "Org-mode", - :creole => "Creole", - :rest => "reStructuredText", - :asciidoc => "AsciiDoc", - :mediawiki => "MediaWiki", - :pod => "Pod" } - # Sets a Boolean determing whether this page is a historical version. # # Returns nothing. @@ -26,13 +15,29 @@ module Gollum # Returns a Page attr_accessor :parent_page - # Checks if a filename has a valid extension understood by GitHub::Markup. + + # Checks a filename against the registered markup extensions + # + # filename - String filename, like "Home.md" + # + # Returns e.g. ["Home", :markdown], or [] if the extension is unregistered + def self.parse_filename(filename) + return [] unless filename =~ /^(.+)\.([a-zA-Z]\w*)$/i + pref, ext = $1, $2 + + Gollum::Markup.formats.each_pair do |name, format| + return [pref, name] if ext =~ format[:regexp] + end + [] + end + + # Checks if a filename has a valid, registered extension # # filename - String filename, like "Home.md". # # Returns the matching String basename of the file without the extension. def self.valid_filename?(filename) - filename && filename.to_s =~ VALID_PAGE_RE && $1 + self.parse_filename(filename).first end # Checks if a filename has a valid extension understood by GitHub::Markup. @@ -51,34 +56,9 @@ module Gollum # # filename - The String filename. # - # Returns the Symbol format of the page. One of: - # [ :markdown | :textile | :rdoc | :org | :rest | :asciidoc | :pod | - # :roff ] + # Returns the Symbol format of the page; one of the registered format types def self.format_for(filename) - case filename.to_s - when /\.(md|mkdn?|mdown|markdown)$/i - :markdown - when /\.(textile)$/i - :textile - when /\.(rdoc)$/i - :rdoc - when /\.(org)$/i - :org - when /\.(creole)$/i - :creole - when /\.(re?st(\.txt)?)$/i - :rest - when /\.(asciidoc)$/i - :asciidoc - when /\.(pod)$/i - :pod - when /\.(\d)$/i - :roff - when /\.(media)?wiki$/i - :mediawiki - else - nil - end + self.parse_filename(filename).last end # Reusable filter to turn a filename (without path) into a canonical name. @@ -249,9 +229,7 @@ module Gollum # Public: The format of the page. # - # Returns the Symbol format of the page. One of: - # [ :markdown | :textile | :rdoc | :org | :rest | :asciidoc | :pod | - # :roff ] + # Returns the Symbol format of the page; one of the registered format types def format self.class.format_for(@blob.name) end @@ -359,17 +337,7 @@ module Gollum # # Returns the String extension (no leading period). def self.format_to_ext(format) - case format - when :markdown then 'md' - when :textile then 'textile' - when :rdoc then 'rdoc' - when :org then 'org' - when :creole then 'creole' - when :rest then 'rest' - when :asciidoc then 'asciidoc' - when :pod then 'pod' - when :mediawiki then 'mediawiki' - end + format == :markdown ? "md" : format.to_s end #########################################################################