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 ######################################################################### diff --git a/test/examples/lotr.git/logs/HEAD b/test/examples/lotr.git/logs/HEAD index 3259d5f7..6290f7a5 100644 --- a/test/examples/lotr.git/logs/HEAD +++ b/test/examples/lotr.git/logs/HEAD @@ -6,3 +6,4 @@ b16b3d9fad9d78e5a669e7f33d94c96da374eccd b0de6e794dfdc7ef3400e894225bfe23308aae5 b0de6e794dfdc7ef3400e894225bfe23308aae5c cfea406f5f77afc7fb673a43e97721234385b1bd Darren Oakley 1341830099 +0100 push cfea406f5f77afc7fb673a43e97721234385b1bd 629aa678272b017a4d136d35e77ac94d80b08dc2 Darren Oakley 1341830833 +0100 push 629aa678272b017a4d136d35e77ac94d80b08dc2 7d6aeab8b84c895f21f6c66b84a457b0fced9693 Daniel Kimsey 1352501984 -0500 push +7d6aeab8b84c895f21f6c66b84a457b0fced9693 563cc3701db990caf63e4ce9c3697a062890ca48 James Dabbs 1361843315 -0500 push diff --git a/test/examples/lotr.git/logs/refs/heads/master b/test/examples/lotr.git/logs/refs/heads/master index 3259d5f7..6290f7a5 100644 --- a/test/examples/lotr.git/logs/refs/heads/master +++ b/test/examples/lotr.git/logs/refs/heads/master @@ -6,3 +6,4 @@ b16b3d9fad9d78e5a669e7f33d94c96da374eccd b0de6e794dfdc7ef3400e894225bfe23308aae5 b0de6e794dfdc7ef3400e894225bfe23308aae5c cfea406f5f77afc7fb673a43e97721234385b1bd Darren Oakley 1341830099 +0100 push cfea406f5f77afc7fb673a43e97721234385b1bd 629aa678272b017a4d136d35e77ac94d80b08dc2 Darren Oakley 1341830833 +0100 push 629aa678272b017a4d136d35e77ac94d80b08dc2 7d6aeab8b84c895f21f6c66b84a457b0fced9693 Daniel Kimsey 1352501984 -0500 push +7d6aeab8b84c895f21f6c66b84a457b0fced9693 563cc3701db990caf63e4ce9c3697a062890ca48 James Dabbs 1361843315 -0500 push diff --git a/test/examples/lotr.git/objects/56/3cc3701db990caf63e4ce9c3697a062890ca48 b/test/examples/lotr.git/objects/56/3cc3701db990caf63e4ce9c3697a062890ca48 new file mode 100644 index 00000000..d3c21036 Binary files /dev/null and b/test/examples/lotr.git/objects/56/3cc3701db990caf63e4ce9c3697a062890ca48 differ diff --git a/test/examples/lotr.git/objects/7a/cc5626e5ab453dd82857bb1843793ea058fa2c b/test/examples/lotr.git/objects/7a/cc5626e5ab453dd82857bb1843793ea058fa2c new file mode 100644 index 00000000..45ccf1d0 Binary files /dev/null and b/test/examples/lotr.git/objects/7a/cc5626e5ab453dd82857bb1843793ea058fa2c differ diff --git a/test/examples/lotr.git/objects/99/49601deb167a35ca444311d7372864f3e8e1b8 b/test/examples/lotr.git/objects/99/49601deb167a35ca444311d7372864f3e8e1b8 new file mode 100644 index 00000000..ad47cd48 Binary files /dev/null and b/test/examples/lotr.git/objects/99/49601deb167a35ca444311d7372864f3e8e1b8 differ diff --git a/test/examples/lotr.git/refs/heads/master b/test/examples/lotr.git/refs/heads/master index f01a5091..546030a2 100644 --- a/test/examples/lotr.git/refs/heads/master +++ b/test/examples/lotr.git/refs/heads/master @@ -1 +1 @@ -7d6aeab8b84c895f21f6c66b84a457b0fced9693 +563cc3701db990caf63e4ce9c3697a062890ca48 diff --git a/test/test_committer.rb b/test/test_committer.rb index e9b2e17b..15b11231 100644 --- a/test/test_committer.rb +++ b/test/test_committer.rb @@ -50,7 +50,7 @@ context "Wiki" do end test "parents with default master ref" do - ref = '7d6aeab8b84c895f21f6c66b84a457b0fced9693' + ref = '563cc3701db990caf63e4ce9c3697a062890ca48' committer = Gollum::Committer.new(@wiki) assert_equal ref, committer.parents.first.sha end diff --git a/test/test_git_access.rb b/test/test_git_access.rb index caaa37d5..6e62e663 100644 --- a/test/test_git_access.rb +++ b/test/test_git_access.rb @@ -18,7 +18,7 @@ context "GitAccess" do assert @access.ref_map.empty? assert @access.tree_map.empty? @access.tree 'master' - assert_equal({"master"=>"7d6aeab8b84c895f21f6c66b84a457b0fced9693"}, @access.ref_map) + assert_equal({"master"=>"563cc3701db990caf63e4ce9c3697a062890ca48"}, @access.ref_map) @access.tree '1db89ebba7e2c14d93b94ff98cfa3708a4f0d4e3' map = @access.tree_map['1db89ebba7e2c14d93b94ff98cfa3708a4f0d4e3'] diff --git a/test/test_page.rb b/test/test_page.rb index fc1c34a4..a2cd4c6c 100644 --- a/test/test_page.rb +++ b/test/test_page.rb @@ -236,4 +236,18 @@ if $METADATA end end +end + +context "with custom markup engines" do + setup do + Gollum::Markup.register(:redacted, "Redacted", :regexp => /rd/) { |content| content.gsub /\S/, '-' } + @wiki = Gollum::Wiki.new(testpath("examples/lotr.git")) + end + + test "should use the specified engine" do + page = @wiki.page('Riddles') + assert_equal :redacted, page.format + assert page.raw_data.include? 'Time' + assert page.raw_data =~ /^[\s\-]*$/ + end end \ No newline at end of file diff --git a/test/test_wiki.rb b/test/test_wiki.rb index 531c1200..af51ab06 100644 --- a/test/test_wiki.rb +++ b/test/test_wiki.rb @@ -61,7 +61,7 @@ context "Wiki" do test "list files" do files = @wiki.files assert_equal \ - ['Data.csv', 'eye.jpg', 'todo.txt'], + ['Data.csv', 'Riddles.rd', 'eye.jpg', 'todo.txt'], files.map { |p| p.filename }.sort end