1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
|
Redcarpet is written with sugar, spice and everything nice
============================================================
[](https://github.com/vmg/redcarpet/actions/workflows/test.yml)
[](https://www.codetriage.com/vmg/redcarpet)
[](https://badge.fury.io/rb/redcarpet)
Redcarpet is a Ruby library for Markdown processing that smells like
butterflies and popcorn.
This library is written by people
---------------------------------
Redcarpet was written by [Vicent Martí](https://github.com/vmg). It is maintained by
[Robin Dupret](https://github.com/robin850) and [Matt Rogers](https://github.com/mattr-).
Redcarpet would not be possible without the [Sundown](https://www.github.com/vmg/sundown)
library and its authors (Natacha Porté, Vicent Martí, and its many awesome contributors).
You can totally install it as a Gem
-----------------------------------
Redcarpet is readily available as a Ruby gem. It will build some native
extensions, but the parser is standalone and requires no installed libraries.
Starting with Redcarpet 3.0, the minimum required Ruby version is 1.9.2 (or Rubinius in 1.9 mode).
$ [sudo] gem install redcarpet
If you need to use it with Ruby 1.8.7, you will have to stick with 2.3.0:
$ [sudo] gem install redcarpet -v 2.3.0
The Redcarpet source is available at GitHub:
$ git clone git://github.com/vmg/redcarpet.git
And it's like *really* simple to use
------------------------------------
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.
The `Redcarpet::Markdown` object is encouraged to be instantiated once with the
required settings, and reused between parses.
~~~~ ruby
# Initializes a Markdown parser
markdown = Redcarpet::Markdown.new(renderer, extensions = {})
~~~~
Here, the `renderer` variable refers to a renderer object, inheriting
from `Redcarpet::Render::Base`. If the given object has not been
instantiated, the library will do it with default arguments.
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.
Example:
~~~~ ruby
markdown.render("This is *bongos*, indeed.")
# => "<p>This is <em>bongos</em>, indeed.</p>"
~~~~
You can also specify a hash containing the Markdown extensions 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 and http links without protocol,
but starting with `www` are also handled.
* `:disable_indented_code_blocks`: do not parse usual markdown
code blocks. Markdown converts text with four spaces at
the front of each line to code blocks. This option
prevents it from doing so. Recommended to use
with `fenced_code_blocks: true`.
* `:strikethrough`: parse strikethrough, PHP-Markdown style.
Two `~` characters mark the start of a strikethrough,
e.g. `this is ~~good~~ bad`.
* `:lax_spacing`: 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 beginning 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`.
* `:underline`: parse underscored emphasis as underlines.
`This is _underlined_ but this is still *italic*`.
* `:highlight`: parse highlights.
`This is ==highlighted==`. It looks like this: `<mark>highlighted</mark>`
* `:quote`: parse quotes.
`This is a "quote"`. It looks like this: `<q>quote</q>`
* `:footnotes`: parse footnotes, PHP-Markdown style. A footnote works very much
like a reference-style link: it consists of a marker next to the text (e.g.
`This is a sentence.[^1]`) and a footnote definition on its own line anywhere
within the document (e.g. `[^1]: This is a footnote.`).
Example:
~~~~ ruby
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, tables: true)
~~~~
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 brilliant
performance — several degrees of magnitude faster than other Ruby Markdown
solutions.
All the rendering flags that previously applied only to HTML output have
now been moved to the `Redcarpet::Render::HTML` class, and may be enabled when
instantiating the renderer:
~~~~ ruby
Redcarpet::Render::HTML.new(render_options = {})
~~~~
Initializes an HTML renderer. The following flags are available:
* `:filter_html`: do not allow any user-inputted HTML in the output.
* `:no_images`: do not generate any `<img>` tags.
* `:no_links`: do not generate any `<a>` tags.
* `:no_styles`: do not generate any `<style>` tags.
* `:escape_html`: escape any HTML tags. This option has precedence over
`:no_styles`, `:no_links`, `:no_images` and `:filter_html` which means
that any existing tag will be escaped instead of being removed.
* `:safe_links_only`: only generate links for protocols which are considered
safe.
* `:with_toc_data`: add HTML anchors to each header in the output HTML,
to allow linking to each section.
* `:hard_wrap`: insert HTML `<br>` tags inside paragraphs where the original
Markdown document had newlines (by default, Markdown ignores these newlines).
* `:xhtml`: output XHTML-conformant tags. This option is always enabled in the
`Render::XHTML` renderer.
* `:prettify`: add prettyprint classes to `<code>` tags for google-code-prettify.
* `:link_attributes`: hash of extra attributes to add to links.
Example:
~~~~ ruby
renderer = Redcarpet::Render::HTML.new(no_links: true, hard_wrap: true)
~~~~
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.
When instantiating this render object, you can optionally pass a `nesting_level`
option which takes an integer or a range and allows you to make it render only
headers at certain levels.
Redcarpet also includes a plaintext renderer, `Redcarpet::Render::StripDown`, that
strips out all the formatting:
~~~~ ruby
require 'redcarpet'
require 'redcarpet/render_strip'
markdown = Redcarpet::Markdown.new(Redcarpet::Render::StripDown)
markdown.render("**This** _is_ an [example](http://example.org/).")
# => "This is an example (http://example.org/)."
~~~~
And you can even cook your own
------------------------------
Custom renderers are created by inheriting from an existing renderer. The
built-in renderers, `HTML` and `XHTML` may be extended as such:
~~~~ ruby
# Create a custom renderer that sets a custom class for block-quotes.
class CustomRender < Redcarpet::Render::HTML
def block_quote(quote)
%(<blockquote class="my-custom-class">#{quote}</blockquote>)
end
end
markdown = Redcarpet::Markdown.new(CustomRender, fenced_code_blocks: true)
~~~~
But new renderers can also be created from scratch by extending the abstract
base class `Redcarpet::Render::Base` (see `lib/redcarpet/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
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.
Therefore, make sure that your renderer has at least a `paragraph` method
implemented. If the method for a document element is not implemented, the
block will be skipped.
Example:
~~~~ ruby
class RenderWithoutCode < Redcarpet::Render::HTML
def block_code(code, language)
nil
end
end
~~~~
* block_code(code, language)
* block_quote(quote)
* block_html(raw_html)
* footnotes(content)
* footnote_def(content, number)
* 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, header)
### 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)
* underline(text)
* highlight(text)
* quote(text)
* footnote_ref(number)
**Note**: When overriding a renderer's method, be sure to return a HTML
element with a level that matches the level of that method (e.g. return a
block element when overriding a block-level callback). Otherwise, the output
may be unexpected.
### 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)
You can look at
["How to extend the Redcarpet 2 Markdown library?"](https://web.archive.org/web/20170505231254/http://dev.af83.com/2012/02/27/howto-extend-the-redcarpet2-markdown-lib.html)
for some more explanations.
Also, now our Pants are much smarter
------------------------------------
Redcarpet 2 comes with a standalone [SmartyPants](
http://daringfireball.net/projects/smartypants/) implementation. It is fully
compliant 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 (`pre`, `code`,
`var`, `samp`, `kbd`, `math`, `script`, `style`).
What? You really want to mix Markdown renderers?
------------------------------------------------
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 is not backwards-compatible with the 1.X
versions.
Each renderer has its own API and its own set of extensions: you should choose one
(it doesn't have to be Redcarpet, though that would be great!), write your
software accordingly, and force your users to install it. That's the
only way to have reliable and predictable Markdown output on your program.
Markdown is already ill-specified enough; if you create software that is
renderer-independent, the results will be completely unreliable!
Still, if major forces (let's say, tornadoes or other natural disasters) force you
to keep a Markdown-compatibility layer, Redcarpet also supports this:
~~~~ ruby
require 'redcarpet/compat'
~~~~
Requiring the compatibility library will declare a `Markdown` class with the
classical RedCloth API, e.g.
~~~~ ruby
Markdown.new('this is my text').to_html
~~~~
This class renders 100% standards compliant Markdown with 0 extensions. Nada.
Don't even try to enable extensions with a compatibility layer, because
that's a maintenance nightmare and won't work.
On a related topic: if your Markdown gem has a `lib/markdown.rb` file that
monkeypatches the Markdown class, you're a terrible human being. Just saying.
Boring legal stuff
------------------
Copyright (c) 2011-2016, Vicent Martí
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
|