Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

combine: Redcarpet2 + BinMan => redcarpet-manpage

  • Loading branch information...
commit 30fae24e942b367d78f69ae6add7e76deaf538ce 1 parent ad5b746
@sunaku authored
View
1  LICENSE
@@ -1,5 +1,6 @@
(the ISC license)
+Copyright 2011 Vicent Martí <vicent@github.com>
Copyright 2011 Suraj N. Kurapati <sunaku@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
View
298 README.markdown
@@ -1,268 +1,78 @@
-Redcarpet 2 is written with sugar, spice and everything nice
-============================================================
+RedcarpetManpage - UNIX man page renderer for Redcarpet2
+========================================================
-Redcarpet is Ruby library for Markdown processing that smells like
-butterflies and popcorn.
+RedcarpetManpage is a Ruby library that converts [Markdown] documents into
+UNIX man pages ([roff] documents) using the awesome [Redcarpet2] library.
-Redcarpet used to be a drop-in replacement for Redcloth. This is no longer the
-case since version 2 -- it now has its own API, but retains the old name. Yes,
-that does mean that Redcarpet 2 is not backwards-compatible with the 1.X
-versions.
+[Markdown]: http://daringfireball.net/projects/markdown/
+[roff]: http://man.cx/roff(7)
+[Redcarpet2]: https://github.com/tanoku/redcarpet
-Redcarpet is powered by the Sundown library, which can be found at
+------------------------------------------------------------------------------
+Installation
+------------------------------------------------------------------------------
- https://www.github.com/tanoku/sundown
+As a Ruby gem:
-You might want to find out more about Sundown to see what makes this Ruby
-library so awesome.
+ gem install redcarpet-manpage
-This library is written by people
--------------------------------------------------------
+As a Git clone:
-Redcarpet 2 has been rewritten from scratch by Vicent Marti (@tanoku). Why
-are you not following me on Twitter?
+ git clone git://github.com/sunaku/redcarpet-manpage
+ cd redcarpet-manpage
+ bundle install
-Redcarpet would not be possible without the Sundown library and its authors
-(Natacha Porté, Vicent Martí, and its many awesome contributors).
+------------------------------------------------------------------------------
+Specification
+------------------------------------------------------------------------------
-You can totally install it as a Gem
------------------------------------
+### Markdown Processing Extensions
-Redcarpet is readily available as a Ruby gem. It will build some native
-extensions, but the parser is standalone and requires no installed libraries.
+`RedcarpetManpage::RENDERER` enables the following [Redcarpet2] extensions:
- $ [sudo] gem install redcarpet
+* `autolink`
+* `no_intra_emphasis`
+* `fenced_code_blocks`
+* `space_after_headers`
-The Redcarpet source (including Sundown as a submodule) is available at GitHub:
+### Markdown Processing Divergence
- $ git clone git://github.com/tanoku/redcarpet.git
+Although your input documents are written in [Markdown], RedcarpetManpage
+introduces the following additional conventions to simplify common tasks:
-And it's like *really* simple to use
-------------------------------------
+1. Paragraphs beginning with bold/italic and followed by at least
+ one two-space indented line are considered to be definitions.
+ The first line of such a paragraph is the term being defined and
+ the subsequent two-space indented lines are the definition body.
-The core of the Redcarpet library is the `Redcarpet::Markdown` class. Each
-instance of the class is attached to a `Renderer` object; the Markdown class
-performs parsing of a document and uses the attached renderer to generate
-output.
+------------------------------------------------------------------------------
+Usage
+------------------------------------------------------------------------------
-The `Markdown` object is encouraged to be instantiated once with the required
-settings, and reused between parses.
+Use the default renderer:
- Markdown.new(renderer, extensions={})
+``` ruby
+require 'redcarpet-manpage'
+your_roff_output = RedcarpetManpage::RENDERER.render(your_markdown_input)
+```
- Initializes a Markdown parser
+Or extend it for yourself:
- renderer - a renderer object, inheriting from Redcarpet::Render::Base.
- If the given object has not been instantiated, the library
- will do it with default arguments.
+``` ruby
+require 'redcarpet-manpage'
- extensions - a hash containing the Markdown extesions which the parser
- will identify. The following extensions are accepted:
-
- :no_intra_emphasis - do not parse emphasis inside of words.
- Strings such as `foo_bar_baz` will not generate `<em>`
- tags.
-
- :tables - parse tables, PHP-Markdown style
-
- :fenced_code_blocks - parse fenced code blocks, PHP-Markdown
- style .Blocks delimited with 3 or more `~` or backticks
- will be considered as code, without the need to be
- indented. An optional language name may be added at the
- end of the opening fence for the code block
-
- :autolink - parse links even when they are not enclosed in
- `<>` characters. Autolinks for the http, https and ftp
- protocols will be automatically detected. Email addresses
- are also handled, and http links without protocol, but
- starting with `www.`
-
- :strikethrough - parse strikethrough, PHP-Markdown style
- Two `~` characters mark the start of a strikethrough,
- e.g. `this is ~~good~~ bad`
-
- :lax_html_blocks - HTML blocks do not require to be surrounded
- by an empty line as in the Markdown standard.
-
- :space_after_headers - A space is always required between the
- hash at the beggining of a header and its name, e.g.
- `#this is my header` would not be a valid header.
-
- :superscript - parse superscripts after the `^` character;
- contiguous superscripts are nested together, and complex
- values can be enclosed in parenthesis,
- e.g. `this is the 2^(nd) time`
-
- Example:
-
- markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML,
- :autolink => true, :space_after_headers => true)
-
-Rendering with the `Markdown` object is done through `Markdown#render`.
-Unlike in the RedCloth API, the text to render is passed as an argument
-and not stored inside the `Markdown` instance, to encourage reusability.
-
- Markdown.render(text)
-
- Render a Markdown document with the attached renderer
-
- text - a Markdown document
-
- Example:
-
- markdown.render("This is *bongos*, indeed.")
- #=> "<p>This is <em>bongos</em>, indeed</p>"
-
-
-Darling, I packed you a couple renderers for lunch
---------------------------------------------------
-
-Redcarpet comes with two built-in renderers, `Redcarpet::Render::HTML` and
-`Redcarpet::Render::XHTML`, which output HTML and XHTML, respectively. These
-renderers are actually implemented in C, and hence offer a brilliant
-performance, several degrees of magnitude faster than other Ruby Markdown
-solutions.
-
-The `HTML` renderer has an alternate version, `Redcarpet::Render::HTML_TOC`,
-which will output a table of contents in HTML based on the headers of the
-Markdown document.
-
-Furthermore, the abstract base class `Redcarpet::Render::Base` can be used
-to write a custom renderer purely in Ruby, or extending an existing renderer.
-See the following section for more information.
-
-
-And you can even cook your own
-------------------------------
-
-Custom renderers are created by inheriting from an existing renderer. The
-builtin renderers, `HTML` and `XHTML` may be extended as such:
-
-~~~~~ ruby
-# create a custom renderer that allows highlighting of code blocks
-class HTMLwithAlbino < Redcarpet::Render::HTML
- def block_code(code, language)
- Albino.safe_colorize(code, language)
- end
-end
-
-markdown = Redcarpet::Markdown.new(HTMLwithAlbino, :fenced_code_blocks => true)
-~~~~~
-
-But new renderers can also be created from scratch (see `lib/render_man.rb` for
-an example implementation of a Manpage renderer)
-
-~~~~~~ ruby
-class ManPage < Redcarpet::Render::Base
- # you get the drill -- keep going from here
+class YourManpageRenderer < RedcarpetManpage::Renderer
+ # ... your stuff here ...
+ # See Redcarpet::Render::Base documentation for more information:
+ # http://rdoc.info/github/tanoku/redcarpet/master/Redcarpet/Render/Base
end
-~~~~~
-
-The following instance methods may be implemented by the renderer:
-
- # Block-level calls
- # If the return value of the method is `nil`, the block
- # will be skipped.
- # If the method for a document element is not implemented,
- # the block will be skipped.
- #
- # Example:
- #
- # class RenderWithoutCode < Redcarpet::Render::HTML
- # def block_code(code, language)
- # nil
- # end
- # end
- #
- block_code(code, language)
- block_quote(quote)
- block_html(raw_html)
- header(text, header_level)
- hrule()
- list(contents, list_type)
- list_item(text, list_type)
- paragraph(text)
- table(header, body)
- table_row(content)
- table_cell(content, alignment)
-
- # Span-level calls
- # A return value of `nil` will not output any data
- # If the method for a document element is not implemented,
- # the contents of the span will be copied verbatim
- autolink(link, link_type)
- codespan(code)
- double_emphasis(text)
- emphasis(text)
- image(link, title, alt_text)
- linebreak()
- link(link, title, content)
- raw_html(raw_html)
- triple_emphasis(text)
- strikethrough(text)
- superscript(text)
-
- # Low level rendering
- entity(text)
- normal_text(text)
-
- # Header of the document
- # Rendered before any another elements
- doc_header()
-
- # Footer of the document
- # Rendered after all the other elements
- doc_footer()
-
- # Pre/post-process
- # Special callback: preprocess or postprocess the whole
- # document before or after the rendering process begins
- preprocess(full_document)
- postprocess(full_document)
-
-
-Also, now our Pants are much smarter
-------------------------------------
-
-Redcarpet 2 comes with a standalone [SmartyPants](
-http://daringfireball.net/projects/smartypants/) implementation. It is fully
-compilant with the original implementation. It is the fastest SmartyPants
-parser there is, with a difference of several orders of magnitude.
-
-The SmartyPants parser can be found in `Redcarpet::Render::SmartyPants`. It has
-been implemented as a module, so it can be used standalone or as a mixin.
-
-When mixed with a Renderer class, it will override the `postprocess` method
-to perform SmartyPants replacements once the rendering is complete
-
-~~~~ ruby
-# Mixin
-class HTMLWithPants < Redcarpet::Render::HTML
- include Redcarpet::Render::SmartyPants
-end
-
-# Standalone
-Redcarpet::Render::SmartyPants.render("<p>Oh SmartyPants, you're so crazy...</p>")
-~~~~~
-
-SmartyPants works on top of already-rendered HTML, and will ignore replacements
-inside the content of HTML tags and inside specific HTML blocks such as
-`<code>` or `<pre>`.
-
-Boring legal stuff
-------------------
-
-Copyright (c) 2011, Vicent Martí
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
+renderer = Redcarpet::Markdown.new(YourManpageRenderer, your_options_hash)
+your_roff_output = renderer.render(your_markdown_input)
+```
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+------------------------------------------------------------------------------
+License
+------------------------------------------------------------------------------
+Released under the ISC license. See the LICENSE file for details.
View
58 lib/binman/renderer.rb
@@ -1,58 +0,0 @@
-require 'redcarpet'
-require 'redcarpet/render_man'
-
-module BinMan
- class Renderer < Redcarpet::Render::ManPage
- def normal_text text
- text.gsub(/(?<=\W)-(?=\W)/, '\\-') if text
- end
-
- def paragraph(text)
- "\n.PP\n#{text}\n"
- end
-
- alias codespan double_emphasis
- alias triple_emphasis double_emphasis
-
- def autolink link, link_type
- emphasis link
- end
-
- def link link, title, content
- "#{triple_emphasis content} #{emphasis link}"
- end
-
- DEFINITION_INDENT = ' ' # two spaces
-
- def postprocess document
- document.
- # squeeze blank lines to prevent double-spaced output
- gsub(/^\n/, '').
-
- # first paragraphs inside list items
- gsub(/^(\.IP.*)\n\.PP/, '\1').
-
- # paragraphs beginning with bold/italic and followed by
- # at least one definition-indented line are definitions
- gsub(/^\.PP(?=\n\\f.+\n#{DEFINITION_INDENT}\S)/, '.TP').
-
- # make indented paragraphs occupy less space on screen:
- # roff will fit the second line of the paragraph along
- # side the first line if it has enough room to do so!
- gsub(/^#{DEFINITION_INDENT}(?=\S)/, '').
-
- # encode references to other man pages as "hyperlinks"
- gsub(/(\w+)(\([1-9nol]\)[[:punct:]]?\s*)/, "\n.BR \\1 \\2\n").
- # keep the SEE ALSO sequence of references in-line
- gsub(/(?:^\.BR.+\n)+/m){ |sequence| sequence.squeeze("\n") }
- end
- end
-
- RENDERER = Redcarpet::Markdown.new(Renderer,
- #:tables => true,
- :autolink => true,
- #:superscript => true,
- :no_intra_emphasis => true,
- :fenced_code_blocks => true,
- :space_after_headers => true)
-end
View
108 lib/redcarpet-manpage.rb
@@ -1,7 +1,107 @@
-require "redcarpet-manpage/version"
+require 'redcarpet'
-module Redcarpet
- module Manpage
- # Your code goes here...
+module RedcarpetManpage
+
+ class Renderer < Redcarpet::Render::Base
+ def normal_text(text)
+ text.gsub(/(?<=\W)-(?=\W)/, '\\-') if text
+ end
+
+ def triple_emphasis(text)
+ "\\fB#{text}\\fP"
+ end
+
+ alias double_emphasis triple_emphasis
+
+ def emphasis(text)
+ "\\fI#{text}\\fP"
+ end
+
+ def block_code(code, language)
+ "\n.nf\n#{normal_text(code)}\n.fi\n"
+ end
+
+ alias codespan double_emphasis
+
+ def link(link, title, content)
+ "#{triple_emphasis(content)} #{emphasis(link)}"
+ end
+
+ def autolink(link, link_type)
+ emphasis(link)
+ end
+
+ def header(title, level)
+ case level
+ when 1
+ "\n.TH #{title}\n"
+
+ when 2
+ "\n.SH #{title}\n"
+
+ when 3
+ "\n.SS #{title}\n"
+ end
+ end
+
+ def paragraph(text)
+ "\n.PP\n#{text}\n"
+ end
+
+ def linebreak
+ "\n.LP\n"
+ end
+
+ def list(content, list_type)
+ case list_type
+ when :ordered
+ "\n\n.nr step 0 1\n#{content}\n"
+ when :unordered
+ "\n.\n#{content}\n"
+ end
+ end
+
+ def list_item(content, list_type)
+ case list_type
+ when :ordered
+ ".IP \\n+[step]\n#{content.strip}\n"
+ when :unordered
+ ".IP \\[bu] 2 \n#{content.strip}\n"
+ end
+ end
+
+ DEFINITION_INDENT = ' ' # two spaces
+
+ def postprocess document
+ document.
+ # squeeze blank lines to prevent double-spaced output
+ gsub(/^\n/, '').
+
+ # first paragraphs inside list items
+ gsub(/^(\.IP.*)\n\.PP/, '\1').
+
+ # paragraphs beginning with bold/italic and followed by
+ # at least one definition-indented line are definitions
+ gsub(/^\.PP(?=\n\\f.+\n#{DEFINITION_INDENT}\S)/, '.TP').
+
+ # make indented paragraphs occupy less space on screen:
+ # roff will fit the second line of the paragraph along
+ # side the first line if it has enough room to do so!
+ gsub(/^#{DEFINITION_INDENT}(?=\S)/, '').
+
+ # encode references to other man pages as "hyperlinks"
+ gsub(/(\w+)(\([1-9nol]\)[[:punct:]]?\s*)/, "\n.BR \\1 \\2\n").
+ # keep the SEE ALSO sequence of references in-line
+ gsub(/(?:^\.BR.+\n)+/m){ |sequence| sequence.squeeze("\n") }
+ end
end
+
+ RENDERER = Redcarpet::Markdown.new(Renderer,
+ #:tables => true,
+ :autolink => true,
+ #:superscript => true,
+ :no_intra_emphasis => true,
+ :fenced_code_blocks => true,
+ :space_after_headers => true)
+
end
View
6 lib/redcarpet-manpage/version.rb
@@ -1,5 +1,3 @@
-module Redcarpet
- module Manpage
- VERSION = "0.0.1"
- end
+module RedcarpetManpage
+ VERSION = "0.0.1"
end
View
65 lib/redcarpet/render_man.rb
@@ -1,65 +0,0 @@
-module Redcarpet
- module Render
- class ManPage < Base
-
- def normal_text(text)
- text.gsub('-', '\\-').strip
- end
-
- def block_code(code, language)
- "\n.nf\n#{normal_text(code)}\n.fi\n"
- end
-
- def codespan(code)
- block_code(code, nil)
- end
-
- def header(title, level)
- case level
- when 1
- "\n.TH #{title}\n"
-
- when 2
- "\n.SH #{title}\n"
-
- when 3
- "\n.SS #{title}\n"
- end
- end
-
- def double_emphasis(text)
- "\\fB#{text}\\fP"
- end
-
- def emphasis(text)
- "\\fI#{text}\\fP"
- end
-
- def linebreak
- "\n.LP\n"
- end
-
- def paragraph(text)
- "\n.TP\n#{text}\n"
- end
-
- def list(content, list_type)
- case list_type
- when :ordered
- "\n\n.nr step 0 1\n#{content}\n"
- when :unordered
- "\n.\n#{content}\n"
- end
- end
-
- def list_item(content, list_type)
- case list_type
- when :ordered
- ".IP \\n+[step]\n#{content.strip}\n"
- when :unordered
- ".IP \\[bu] 2 \n#{content.strip}\n"
- end
- end
- end
- end
-end
View
15 redcarpet-manpage.gemspec
@@ -4,14 +4,12 @@ require "redcarpet-manpage/version"
Gem::Specification.new do |s|
s.name = "redcarpet-manpage"
- s.version = Redcarpet::Manpage::VERSION
- s.authors = ["Suraj N. Kurapati"]
- s.email = ["sunaku@gmail.com"]
- s.homepage = ""
- s.summary = %q{TODO: Write a gem summary}
- s.description = %q{TODO: Write a gem description}
-
- s.rubyforge_project = "redcarpet-manpage"
+ s.version = RedcarpetManpage::VERSION
+ s.authors,
+ s.email = File.read('LICENSE').scan(/Copyright \d+ (.+) <(.+?)>/).transpose
+ s.homepage = "http://github.com/sunaku/redcarpet-manpage"
+ s.summary = "UNIX man page renderer for Redcarpet2"
+ s.description = nil
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -21,4 +19,5 @@ Gem::Specification.new do |s|
# specify any dependencies here; for example:
# s.add_development_dependency "rspec"
# s.add_runtime_dependency "rest-client"
+ s.add_runtime_dependency "redcarpet", ">= 2.0.0b5"
end
Please sign in to comment.
Something went wrong with that request. Please try again.