Code Monkey home page Code Monkey logo

redcarpet's Introduction

Redcarpet is written with sugar, spice and everything nice

Build status Help Contribute to Open Source Gem Version

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í. It is maintained by Robin Dupret and Matt Rogers.

Redcarpet would not be possible without the 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.

# 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:

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:

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:

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:

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:

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:

# 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):

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:

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?" for some more explanations.

Also, now our Pants are much smarter

Redcarpet 2 comes with a standalone 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.

# 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:

require 'redcarpet/compat'

Requiring the compatibility library will declare a Markdown class with the classical RedCloth API, e.g.

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.

redcarpet's People

Contributors

ahti avatar amatsuda avatar brief avatar byroot avatar codyrobbins avatar djanowski avatar dwaller avatar eric-brechemier avatar grosser avatar hawur avatar joliss avatar kaneshin avatar kevin1 avatar kolen avatar lsegal avatar maschwenk avatar mattr- avatar mmorearty avatar nathany avatar nono avatar rkh avatar rmm5t avatar robin850 avatar rtomayko avatar sanmai avatar silverhammermba avatar soffes avatar tomhughes avatar vmg avatar x3ro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

redcarpet's Issues

Ignore link markup but still use :autolink

I want to use redcarpet to format user comments. However, I am wary of allowing them to use arbitrary text for links. I see it as potentially being used to misdirect users. Say for example what appears to be an auto-linked Youtube URL really directs the user elsewhere, which might snag less careful users.

I essentially want to use the :autolink and :no_links options together, but the latter cancels out the former. I would argue that if the programmer purposely provided both options, he or she probably intended for autolinking to take place irrespective of other options. This would be ideal for my purposes as it would allow for pasted links to still be clickable without obfuscating the destination of those links (excluding shortened URLs).

Locally I did this by trivially removing a single line from html.c, but I don't know if a pull request is in order for such a small change or if anyone else is behind this idea.

hard_wrap gone in 2.0?

I was trying to upgrade to Redcarpet 2.0 and it appears that some of the options like hard_wrap went away.

Is there a way to implement this myself? Any specific reason for the change?

Thanks,
Karthik

Semantic Anchors for Table of Contents

Any chance of RedCarpet switching to using (or providing a flag for) semantic anchor tags, rather than "toc_0", etc.?

A.k.a.

# Header 1

# Header 2
<h1 id="header_1">Header 1</h1>
<h1 id="header_2">Header 2</h1>

I'm happy to do some hacking, but C is definitely not my strength...

Smart quotes don't work when they surround links

This works:

[Dev]> Redcarpet.new(%{"Google"}, :smart).to_html 
=> "<p>&ldquo;Google&rdquo;</p>\n"

But when "Google" is a link, Redcarpet replaces the right quote with a left quote:

[Dev]> Redcarpet.new(%{"[Google](http://google.com)"}, :smart).to_html
=> "<p>&ldquo;<a href="http://google.com">Google</a>&ldquo;</p>\n"

The output here should be:

"<p>&ldquo;<a href="http://google.com">Google</a>&rdquo;</p>\n"

How to ignore certain code

Is there a way to tell Redcarpet to ignore certain code.

For example, code blocks like <ins class="differ">foobar</ins> or <del class="differ">foobar</del>

:strict inversed?

Hi, I'm not sure but I think that the :strict flag has the opposite behaviour of what should be done:

pry(main)> Redcarpet.new("foo_bar_baz", :strict).to_html
=> "<p>foo_bar_baz</p>\n"
pry(main)> Redcarpet.new("foo_bar_baz").to_html
=> "<p>foo<em>bar</em>baz</p>\n"

In the source code of Redcarpet, we can see :

 # Disable relaxed emphasis processing.
  attr_accessor :strict

But the :strict flag enables relaxed emphasis processing (and not disables it). What do you think of it?

How not to escape HTML?

This isn't really an bug/issue but I can't find the answer anywhere, if theres a way to tell Redcarpet not to escape HTML?

ID tags....

I really like markdown, it is clean and simple. But for a project I'm working on tonight, I was trying to find a way to use it without having to mix html into the mix.
Most of the time that I have to add raw html is to add a class or a id tag to a style element.
So without knowing enough C could we have a option to allow for id's to be added from either the alt text of header title. e.g. -

The really cool title

Which would render:
<h1 id="the_really_cool_title">The really cool title</h1>
OR

<img id="fish"..... ````

I looked into the php markdown extra, and that would be ok, but it seems a bit more complex. 

HTML rendering flags

There are two typos in the Readme. The HTML rendering flags should be no_image and with_toc_data -- not no_images and with_doc_data -- to match what's in rc_render.c.

That said, I prefer no_images as the flag name.

Broken formatting following HTML header

Check out the difference between RDiscount and Redcarpet in this case. I think RDiscount's behavior is correct:

> Redcarpet.new("<h2>a</h2>\n>a").to_html
=> "<p><h2>a</h2>\n&gt;a</p>\n"
> RDiscount.new("<h2>a</h2>\n>a").to_html
=> "<h2>a</h2>\n\n\n<blockquote><p>a</p></blockquote>\n"

At the very least, surrounding the <h2> with a <p> looks like a bug

Also, note the difference in this simpler case:

> Redcarpet.new("<h2>a</h2>\nabcd").to_html
=> "<p><h2>a</h2>\nabcd</p>\n"
> RDiscount.new("<h2>a</h2>\nabcd").to_html
=> "<h2>a</h2>\n\n\n<p>abcd</p>\n"

Again, I think RDiscount is correct

RFC: a regex sieve for the redcarpet v2.0.3b

Here is a regular expression sieve which takes the API code and blows it up into a sparse matrix:

          IVE =     /^   \s+                           $                             
                    |^   .*                            \(   (.*)      \)   .*   $    
                    |^   \s*  \#   (.*)                $                             
                    |^   \s*  (pre|post|raw|doc)(.*)   $                             
                    |^   \s*  (b|h|p|t|lis)(.*)        $                             
                    |^   \s*  (a|c|d|em|i|lin|s)(.*)   $                             
                    |^   \s*  (en|n)(.*)               $                             
                    /                                                                

Copying and pasting the regex itself, without the leading or trailing /s:

^   \s+                           $                             
                    |^   .*                            \(   (.*)      \)   .*   $    
                    |^   \s*  \#   (.*)                $                             
                    |^   \s*  (pre|post|raw|doc)(.*)   $                             
                    |^   \s*  (b|h|p|t|lis)(.*)        $                             
                    |^   \s*  (a|c|d|em|i|lin|s)(.*)   $                             
                    |^   \s*  (en|n)(.*)               $                             

Along with the current API spec:

# 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)

And inputting these (with options //ix) at Rubular demonstrates a total covering.

NOTE

Curiously, the make permalink button doesn't preserve the output at Rubular. The link shows as resulting in pairs of results:

  1. ...
  2. ...

Instead of the correct result format:

  1. ...
  2. ...
  3. ...

all the way to 10. ...

So you'll have to cut-n-paste to see the right output.

/NOTE

This sort of thing might be useful to someone who wants to wrap the API using a rulebook style approach, but who might want to know the shortest match for lookup (or auto-completion) purposes.

I plan on trying exactly such a thing, but I figured I'd post the idea up here for anyone to comment on.

Thanks,

tgeeky

Embedding syntax highlighting in lists

Hi! Thanks for this cool feature! However, I'm having the following problem.

In original Markdown, you can have code formatting embedded in any other container, like an enumeration:

  • Item 1

  • Item 2

    // Some code here
    public static final boolean DEBUG = true;
    

    Some additional comment on Item 2

  • Item 3

Now, if I want to use the new syntax highliht, it is broken because it either indented and parsed as code formatting:

  • Item 1

  • Item 2

    ```java
    // Some code here
    public static final boolean DEBUG = true;
    ```
    

    Some additional comment on Item 2

  • Item 3

Or ends the current item, and I cannot make any subparagraphs for Item 2.

  • Item 1
  • Item 2
// Some code here
public static final boolean DEBUG = true;
Some additional comment on Item 2
  • Item 3

In the case written above, it ends the list definition, so the simple indentation means Some additional comment on Item 2 is formatted as a code.

  1. Item 1
  2. Item 2
// Some code here
public static final boolean DEBUG = true;

Some additional comment on Item 2

  1. Item 3

Removing the indentation removes code formatting, but the line gets out of the list. This is a problem for numbered lists:

Please, do you have any ideas/suggestions how to deal with embedding syntax highlighting in lists/enumerations?

where did upskirt repo go?

Tried to install recarpet submodules today:

Submodule 'upskirt' (git://github.com/tanoku/upskirt.git) registered for path 'upskirt'
fatal: remote error: 
  Could not find Repository tanoku/upskirt

^ for <sup>

By the way, I have found another incompatibility with RDiscount. ^ can be used for <sup> tag, like this :

pry(main)> RDiscount.new("2^nd").to_html
=> "<p>2<sup>nd</sup></p>\n"

But, I can't find a similar flag for Redcarpet:

pry(main)> Redcarpet.new("2^nd").to_html
=> "<p>2^nd</p>\n"

The users of my website like this feature. So, it could be cool if you implement it ;-)

- (single dash) is transformed into en dash

Dashes (“--” and “---”) supposedly are transformed into en- and em-dash entities. However Redcarpet with :smart option transforms - (single dash) into en dash and -- (double dash) into em dash. Therefore there is no way to inset normal dash (-).

All table rows contain <th> cells

I tried this …

| First Header  | Second Header |
| ------------- | ------------- |
| Content Cell  | Content Cell  |
| Content Cell  | Content Cell  |

… and got three <tr> elements containing two <th> elements each. I would have expected one row of <th> cells and zwei rows of ordinary <td>s. My fault or the renderer's?

Parentheses in link titles don’t work

Trying to use parentheses in link titles doesn’t produce the correct output. I’m not sure if this should work when the parentheses are unescaped, but escaping them doesn’t make any difference.

Rendering

[Wikipedia](http://wikipedia.org/ "Wikipedia (a great website)”]

and

[Wikipedia](http://wikipedia.org/ "Wikipedia \(a great website\)")

both produce

<p><a href=\"http://wikipedia.org/%20%22Wikipedia%20(a%20great%20website\">Wikipedia</a>&quot;)</p>\n

SmartyPants quote handling isn’t actually compliant with original implementation

Here are a few counterexamples which John Gruber’s original Perl implementation of SmartyPants correctly handle:

  • ma'am
  • o'clock
  • s'étendre
  • à l'extrême
  • j'apprecie tes efforts
  • d'une manière soignée
  • c'est pour cela que

Looking at ext/redcarpet/html_smartypants.c, this appears to be due to the hard-coded recognition of a small subset of English contractions in smartypants_cb__squote. Is there a way to handle these single quotes more generally while maintaining the same performance?

Calling super in a subclass of Render::HTML should render the HTML

class SCREAMING < Redcarpet::Render::HTML
  def header(text, level)
    super(text.upcase, level)
  end
end

Redcarpet::Markdown.new(SCREAMING).render("# Hello")

Output: NoMethodError: super: no superclass method 'header' for #<SCREAMING:0x007fd0b4035d40>

Expected result: "<h1>HELLO</h1>"

option to not use self-closing tags?

Are there any plans for a non-self-closing tags mode (much like haml has with format :html5)?

While html5 can support self-closing tags (with void tags self-closing is apparently optional), but it would be nice to have a non-self-closing tags output option.

don't insert 'br' after image

Right now there's the 'br' tag automatically inserted after image, is this desired behavior?

For example, let's suppose I would like to insert list of screenshots for my project, arranged in line:

Here are screenshots of some projects I worked on:

[![lookatme_icon]][lookatme] [![store_icon]][store] [![ford_fiesta_icon]][ford_fiesta]

bla bla bla

But the result is broken, images are in column instead of to be in row:

Here are screenshots of some projects I worked on:

lookatme_icon store_icon ford_fiesta_icon

bla bla bla

Links in headers

Headers should be linkable. Something like this test:

def test_that_headers_are_linkable
  markdown = Markdown.new('### Hello [GitHub](http://github.com)')
  html_equal "<h3>Hello <a href=\"http://github.com\">GitHub</a></h3>", markdown.to_html.strip
end

HTML5 Block Level Elements

Any chance of these being added to the underlying library...

e.g. <article>, <section> et al being treated like <div> by Markdown.

I've tried to build a patch locally but can't seem to make it hang together...

Writing a Node.js port

I like Ruby as much as the next guy, but at Nodejitsu we run an all node.js stack. Since this is essentially a wrapper for some c code it seems like it wouldn't be too difficult to port it to node.js

Could you give me some details about the finer points of this integration? Been talking to a few people and we're interested in spearheading the node.js porting effort.

Escaping special characters

Is there a way to escape text to ensure all special Markdown characters are interpreted as their literal values? I’m generating Markdown programmatically from user-supplied data, so—for example—I need to escape parentheses from strings that are going to be inserted into the title part of links. For example, I might be generating

[Wikipedia](http://wikipedia.org/ "Wikipedia (a great website)"]

where 'Wikipedia (a great website)’ is user-generated. In this case, the parentheses need to be escaped to prevent the Markdown from breaking.

I scoured the documentation but I can’t find any mention of a method to do this. There’s char_escape() in ext/redcarpet/markdown.c, but I’m not too familiar with Ruby C extensions and I don’t know if this is a private method or how to invoke it.

Mixing HTML and Markdown.

Is there an option to have both HTML and markdown processed within the same block?
Example below doesn't work for me with these options (i.e. heading's being processed as it should, but "autolink" doesn't seem to work, and also title syntax doesn't):

in ruby:

Redcarpet.new(markup, :smart, :autolink, :fenced_code, :lax_htmlblock).to_html

example.mdown:

# Markdown

<dl>
  <dt>HTML</dt>
  <dd>http://link.not.processed</dd>
  <dd>[Link](http://not.processed)</dd>
</dl> 

Thanks.

Automatic syntax highlighting appropriate to shebang

Demo

Below indented block:

    #!/usr/bin/env ruby
    require "awesomeness"

would be transformed to:

#!/usr/bin/env ruby
require "awesomeness"

Similarly fenced block

```
#!/bin/sh
set +awesomeness
```

would be transformed to:

#!/bin/sh
set +awesomeness

Additional remark

Fenced blocks w/ syntax highlighting appropriate to language tag are nice, but IMO they don't look as good as indented blocks for raw reading, i.e. when they are unformatted. It's important for README and other files distributed w/o any preprocessing. Such automatic syntax highlighting would help a lot here.

JRuby isn't loading redcarpet it seems.

Hey, I can't seem to get this running in JRuby.. missing _environ

The short:

$ bundle exec rake
rake aborted!
load error: redcarpet -- java.lang.UnsatisfiedLinkError: dlopen(/Users/parndt/.rvm/gems/jruby-1.6.4/gems/redcarpet-2.0.0b4/lib/redcarpet.bundle, 9): Symbol not found: _environ
  Referenced from: /Users/parndt/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.1.9.1.dylib
  Expected in: flat namespace
 in /Users/parndt/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.1.9.1.dylib

The long:

$ bundle exec rake --trace
** Invoke load_app (first_time)
** Execute load_app
rake aborted!
load error: redcarpet -- java.lang.UnsatisfiedLinkError: dlopen(/Users/parndt/.rvm/gems/jruby-1.6.4/gems/redcarpet-2.0.0b4/lib/redcarpet.bundle, 9): Symbol not found: _environ
  Referenced from: /Users/parndt/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.1.9.1.dylib
  Expected in: flat namespace
 in /Users/parndt/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.1.9.1.dylib
org/jruby/RubyKernel.java:1038:in `require'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/redcarpet-2.0.0b4/lib/redcarpet.rb:1:in `(root)'
org/jruby/RubyKernel.java:1038:in `require'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/redcarpet-2.0.0b4/lib/redcarpet.rb:2:in `(root)'
org/jruby/RubyKernel.java:1038:in `require'
/code/parndt/forem/lib/forem.rb:1:in `(root)'
org/jruby/RubyKernel.java:1038:in `require'
/Users/parndt/.rvm/gems/jruby-1.6.4/bundler/gems/forem-theme-base-ad595697feb1/lib/forem-theme-base.rb:68:in `require'
org/jruby/RubyArray.java:1603:in `each'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/bundler-1.1.pre.8/lib/bundler/runtime.rb:66:in `require'
org/jruby/RubyArray.java:1603:in `each'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/bundler-1.1.pre.8/lib/bundler/runtime.rb:55:in `require'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/bundler-1.1.pre.8/lib/bundler.rb:123:in `require'
/code/parndt/forem/spec/dummy/config/application.rb:5:in `(root)'
org/jruby/RubyKernel.java:1038:in `require'
/code/parndt/forem/spec/dummy/config/application.rb:5:in `(root)'
org/jruby/RubyKernel.java:1063:in `load'
/code/parndt/forem/spec/dummy/Rakefile:3:in `(root)'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/lib/rake/task_manager.rb:207:in `in_namespace'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/lib/rake/dsl_definition.rb:95:in `namespace'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/railties-3.1.0/lib/rails/tasks/engine.rake:2:in `(root)'
org/jruby/RubyProc.java:274:in `call'
org/jruby/RubyProc.java:229:in `call'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/lib/rake/task.rb:205:in `execute'
org/jruby/RubyArray.java:1603:in `each'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/lib/rake/task.rb:200:in `execute'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/lib/rake/task.rb:158:in `invoke_with_call_chain'
/Users/parndt/.rvm/rubies/jruby-1.6.4/lib/ruby/1.8/monitor.rb:191:in `mon_synchronize'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/lib/rake/task.rb:151:in `invoke_with_call_chain'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/lib/rake/task.rb:144:in `invoke'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/lib/rake/application.rb:112:in `invoke_task'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/railties-3.1.0/lib/rails/tasks/engine.rake:71:in `(root)'
org/jruby/RubyKernel.java:1063:in `load'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/railties-3.1.0/lib/rails/tasks/engine.rake:8:in `(root)'
org/jruby/RubyKernel.java:1063:in `load'
/code/parndt/forem/Rakefile:25:in `load_rakefile'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/lib/rake/application.rb:495:in `raw_load_rakefile'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/lib/rake/application.rb:78:in `load_rakefile'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/lib/rake/application.rb:129:in `standard_exception_handling'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/lib/rake/application.rb:77:in `load_rakefile'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/lib/rake/application.rb:61:in `run'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/lib/rake/application.rb:129:in `standard_exception_handling'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/lib/rake/application.rb:59:in `run'
/Users/parndt/.rvm/gems/jruby-1.6.4/gems/rake-0.9.2/bin/rake:32:in `(root)'
org/jruby/RubyKernel.java:1063:in `load'
/Users/parndt/.rvm/gems/jruby-1.6.4/bin/rake:19:in `(root)'
Tasks: TOP => load_app

Hope this makes sense to you
Phil

2.0.0b2: compilation fails on i386-mingw32

$ rake install
gem install pkg/redcarpet-2.0.0b2.gem
Temporarily enhancing PATH to include DevKit...
Building native extensions.  This could take a while...

Error 1: did not detect $TMP or $TEMP:

ERROR:  Error installing pkg/redcarpet-2.0.0b2.gem:
        ERROR: Failed to build gem native extension.

        C:/msg/lang/ruby/bin/ruby.exe extconf.rb
creating Makefile

make
C:/msg/lang/ruby/bin/ruby -e "puts 'EXPORTS', 'Init_redcarpet'"  > redcarpet-i386-mingw32.def
bash.exe: warning: could not find /tmp, please create!
gcc -I. -IC:/msg/lang/ruby/include/ruby-1.9.1/i386-mingw32 -I/C/msg/lang/ruby/include/ruby-1.9.1/ruby/backward -I/C/msg/lang/ruby/include/ruby-1.9.1 -I.   -O3 -g -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -o array.o -c array.c
gcc -I. -IC:/msg/lang/ruby/include/ruby-1.9.1/i386-mingw32 -I/C/msg/lang/ruby/include/ruby-1.9.1/ruby/backward -I/C/msg/lang/ruby/include/ruby-1.9.1 -I.   -O3 -g -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -o autolink.o -c autolink.c
gcc -I. -IC:/msg/lang/ruby/include/ruby-1.9.1/i386-mingw32 -I/C/msg/lang/ruby/include/ruby-1.9.1/ruby/backward -I/C/msg/lang/ruby/include/ruby-1.9.1 -I.   -O3 -g -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -o buffer.o -c buffer.c
buffer.c: In function 'vbufprintf':
buffer.c:309:33: warning: signed and unsigned type in conditional expression
gcc -I. -IC:/msg/lang/ruby/include/ruby-1.9.1/i386-mingw32 -I/C/msg/lang/ruby/include/ruby-1.9.1/ruby/backward -I/C/msg/lang/ruby/include/ruby-1.9.1 -I.   -O3 -g -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -o html.o -c html.c
gcc -I. -IC:/msg/lang/ruby/include/ruby-1.9.1/i386-mingw32 -I/C/msg/lang/ruby/include/ruby-1.9.1/ruby/backward -I/C/msg/lang/ruby/include/ruby-1.9.1 -I.   -O3 -g -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -o html_smartypants.o -c html_smartypants.c
gcc -I. -IC:/msg/lang/ruby/include/ruby-1.9.1/i386-mingw32 -I/C/msg/lang/ruby/include/ruby-1.9.1/ruby/backward -I/C/msg/lang/ruby/include/ruby-1.9.1 -I.   -O3 -g -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -o markdown.o -c markdown.c
gcc -I. -IC:/msg/lang/ruby/include/ruby-1.9.1/i386-mingw32 -I/C/msg/lang/ruby/include/ruby-1.9.1/ruby/backward -
I/C/msg/lang/ruby/include/ruby-1.9.1 -I.   -O3 -g -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long  -o rc_markdown.o -c rc_markdown.c

Error 2: redcarpet.h does not exist?

rc_markdown.c:16:23: fatal error: redcarpet.h: No such file or directory
compilation terminated.
make: *** [rc_markdown.o] Error 1
Gem files will remain installed in C:/msg/lang/ruby/lib/ruby/gems/1.9.1/gems/redcarpet-2.0.0b2 for inspection.
Results logged to C:/msg/lang/ruby/lib/ruby/gems/1.9.1/gems/redcarpet-2.0.0b2/ext/redcarpet/gem_make.out
rake aborted!
Command failed with status (1): [gem install pkg/redcarpet-2.0.0b2.gem...]

Tasks: TOP => install
(See full trace by running task with --trace)

For reference, installing the ordinary redcarpet-1.17.2 gem works fine:

$ gem install redcarpet
Temporarily enhancing PATH to include DevKit...
Building native extensions.  This could take a while...
Successfully installed redcarpet-1.17.2
1 gem installed
Installing ri documentation for redcarpet-1.17.2...
Installing RDoc documentation for redcarpet-1.17.2...

Encoding issues with 1.9.2 on Solaris

Hi,
I'm having some encoding problems with both Redcarpet and RDiscount. I'm not convinced it's their fault, but I'm not quite sure how to narrow it down any further.

Some strings in our database are producing invalid encodings when passed through Redcarpet/RDiscount. Certain character sets seem to cause trouble - for example, the tamil character ழ - U+0BB4.

s = "\u0BB4\n"
'\x%X\x%X\x%X' % s.each_byte.to_a             # => "\xE0\xAE\xB4"

Redcarpet.new(s).to_html                      # => "<p>\xE0\xAE</p>\n"
Redcarpet.new(s).to_html.valid_encoding?      # => false

So in the original string, that codepoint is represented with the bytes 0xE0,0xAE,0xB4, but after redcarpeting we end up with just 0xE0,0xAE.

I've created a duplicate issue on the Rdiscount tracker

This is on a Solaris box running ruby 1.9.2p180. An OS X box running the same ruby & redcarpet version works fine. What else can I look at to pinpoint the problem some more?

add language hints

I know this is not standard Markdown, but people start using it in READMEs and it currently breaks all the generated docs (like from YARD).

Redcarpet::Markdown.new(Redcarpet::Render::HTML).render "``` ruby\nfoo\n```"
#  => "<p><code>ruby\nfoo\n</code></p>\n" 

Should be

Redcarpet::Markdown.new(Redcarpet::Render::HTML).render "``` ruby\nfoo\n```"
#  => "<p><code>foo\n</code></p>\n" 

Inline HTML gets wrapped in <p> tag

When an inline HTML is added for example <div class="clear"></div>, the result will be <p><div class="clear"></div></p>.

This is a wrong behavior. In 2.0.0b3 this issue doesn't exists, but in 2.0.0b4 it does.

Closing parenthesis in a link

Hi,

I'd like to make a link with a closing parenthesis in it, but escaping with a backslash doesn't seem to be enough. The typical use case is Wikipedia pages (disambiguation).

For example, I'm expecting

[Pogo]( http://en.wikipedia.org/wiki/Pogo_\(dance\) )

to generate this output:

<a href="http://en.wikipedia.org/wiki/Pogo_(dance)">Pogo</a>

Extend (like RedCloth) for new tags?

I'd love to give this library a whirl but I'm moving from RedCloth and have an additional tag that I've extended RedCloth to recognize. Is there some way to extend redcarpet as well? I can't find a way to do it but perhaps I'm missing something.

thx, Art

incorrect html for inline emphasis

Given the input:

this is the *n*th item in *path* in the object

Gruber's actual markdown program produces:

<p>this is the <em>n</em>th item in <em>path</em> in the object</p>

but redcarpet produces:

<p>this is the <em>n*th item in *path</em> in the object</p>

It would be nice to have consistency with the real markdown converter.

markdown.rb superfluous

RDiscount and Redcarpet both provide markdown.rb for the Ruby $LOAD_PATH. This makes it difficult to install them both as Debian packages at the same time.

In a discussion in the Debian bugtracker, Antonio Terceiro explained:

When using rubygems it "works", i.e. you can install the libraries. But
the effects of require 'markdown' are unpredictable: depending on
which gem gets loaded first, one or the other will be loaded. If they
don't provide exactly the same API, then your code will break in
non-deterministic ways.

AFAIK, the API is very much different, one provides Redcarpet.new etc, the other provides RDiscount.new. There seems to be no functionality at all that "just works" no matter which markdown.rb is found. So it looks like markdown.rb is superfluous.

URLS with parens can lose last paren

Wikipedia loves its URLs to have parentheses. I'm not sure, but it looks like Redcarpet doesn't like parentheses in URLs quite as much.

Here's the test.

class HTMLRenderTest 
  def test_that_urls_with_parens_are_rendered_intact
      markdown = @markdown.render('[wikipedia](http://en.wikipedia.org/wiki/Text_(literary_theory))')
      html_equal %{<a href="http://en.wikipedia.org/wiki/Text_(literary_theory)">wikipedia</a></p>\n}, markdown  
  end
end

Here's the output with a recent github pull:

1) Failure:
test_that_urls_with_parens_are_rendered_intact(MarkdownTest)
    [/Users/brian/Projects/redcarpet/test/redcarpet_test.rb:11:in `html_equal'
     /Users/brian/Projects/redcarpet/test/redcarpet_test.rb:128:in `test_that_urls_with_parens_are_rendered_intact']:
<"<a href=\"http://en.wikipedia.org/wiki/Text_(literary_theory)\">wikipedia</a>"> expected but was
<"<p><a href=\"http://en.wikipedia.org/wiki/Text_(literary_theory\">wikipedia</a></p>">.

without \n change the output

I have this strings

code="\n```ruby\nclass Hello\nend\n```\n"                                                                                           
text="<p><strong>Leyenda de la Encantada</strong></p>"
content = "#{text}\n#title #{code}"
options = [:hard_wrap, :autolink,:filter_html, :no_intraemphasis, :fenced_code, :gh_blockcode]
Redcarpet.new(content, *options).to_html.html_safe

and get

<p>Leyenda de la Encantada</p> 
<h1>title</h1> 
<div class="highlight"> 
<pre><span class="k">class</span> <span class="nc">Hello</span> 
<span class="k">end</span> 
</pre> 
</div> 

ok, great. but if I change content to (without \n)

content = "#{text}#title #{code}"

I get

<p>Leyenda de la Encantada#title <br><code>ruby<br> 
class Hello<br> 
end<br></code></p> 

why?

Fenced Code Blocks should support prior art.

At least three other markdown implementations (Pandoc, Python, and PHP) support fenced code blocks and have for some time before redcarpet even existed. Many people will already have those documents in there repos and they should "Just Work" in Redcarpet.

Yes, Redcarpet currently supports use of the tilde (~), but it is undocumented. I believe you should be encouraging people to use the already existing syntax. If there is some legitimate reason why a subset of your users need a different character to delimit fenced code blocks, that's fine, but document it as a secondary option - not the only way!

Additionally, the already existing syntax for language identification should work. For example:

~~~ .python
print "This should work."
~~~

~~~ {.python}
print "As should this."
~~~

If you want to continue supporting the existing behavior, that's fine, but don't make me go and edit all my existing documents just so they work on Github.

segfault under REE

Seeing the following from the github development console under REE with Redcarpet 1.6:

$ script/console
Loading development environment (Rails 2.2.2)
Loading config/console.rb
ree-1.8.7-2010.01 :001 > Redcarpet.new('blah').to_html
(irb):1: [BUG] Segmentation fault
ruby 1.8.7 (2009-12-24 patchlevel 248) [i686-darwin10.3.1], MBARI 0x6770, Ruby Enterprise Edition 2010.01

Abort trap (core dumped)

Backtrace:

#0  0x00007fff85b49616 in __kill ()
#1  0x00007fff85be9cca in abort ()
#2  0x00000001000155b1 in rb_bug (fmt=0x1000a50e8 "Segmentation fault") at error.c:213
#3  0x0000000100084837 in sigsegv (sig=<value temporarily unavailable, due to optimizations>) at signal.c:633
#4  <signal handler called>
#5  0x00007fffffe00690 in __bzero ()
#6  0x00007fff5fbed3a0 in ?? ()
#7  0x00000001007e008e in mkd_compile (doc=0x10c88a7b0, flags=1606341600) at markdown.c:1220
#8  0x00000001007e101e in markdown (document=0x10c88a7b0, out=0x7fff5fbed4b0, flags=<value temporarily unavailable, due to optimizations>) at mkdio.c:209
#9  0x0000000101cbe96e in rb_redcarpet__render (self=<value temporarily unavailable, due to optimizations>,render_type=REDCARPET_RENDER_XHTML) at redcarpet.c:104
#10 0x0000000100023432 in rb_call0(klass=4365098600, recv=4491018560, id=78873, oid=78873, argc=0, argv=0x0, body=0x1042e1210, flags=<value temporarily unavailable, due to optimizations>) at eval.c:6049
#11 0x00000001000237bc in rb_call (klass=4365098600, recv=4491018560, mid=78873, argc=0, argv=0x0, scope=0, self=4491018920) at eval.c:6308
#12 0x000000010002d96b in eval_call (self=4491018920, node=0x103c18d48) at eval.c:3381
#13 0x000000010001ed18 in rb_eval (self=4491018920, node=0x103c18e88) at eval.c:4100
#14 0x000000010001e96d in rb_eval (self=4491018920, node=0x103c18cd0) at eval.c:3858
...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.