GitHub uses what we're calling "GitHub Flavored Markdown" (GFM) for messages, issues, and comments. It differs from standard Markdown (SM) in a few significant ways and adds some additional functionality.

If you're not already familiar with Markdown, you should spend 15 minutes and go over the excellent Markdown Syntax Guide at Daring Fireball.

If you prefer to learn by example, see the following source and result:

You can also use our live javascript preview to see GFM in action.

Differences from traditional Markdown


The biggest difference that GFM introduces is in the handling of linebreaks. With SM you can hard wrap paragraphs of text and they will be combined into a single paragraph. We find this to be the cause of a huge number of unintentional formatting errors. GFM treats newlines in paragraph-like content as real line breaks, which is probably what you intended.

The next paragraph contains two phrases separated by a single newline character:

Roses are red
Violets are blue


Roses are red
Violets are blue

Multiple underscores in words

It is not reasonable to italicize just part of a word, especially when you're dealing with code and names often appear with multiple underscores. Therefore, GFM ignores multiple underscores in words.




URL autolinking

GFM will autolink standard URLs, so if you want to link to a URL (instead of setting link text), you can simply enter the URL and it will be turned into a link to that URL.

A bit of the GitHub spice

In addition to the changes in the previous section, certain references are auto-linked:

* SHA: be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2
* User@SHA ref: mojombo@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2
* User/Project@SHA: mojombo/god@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2
* \#Num: #1
* User/#Num: mojombo#1
* User/Project#Num: mojombo/god#1



The newline and underscore modification code can be seen below. If you find a bug in the rendering, we'd love to hear about it.

require 'digest/md5'

def gfm(text)
  # Extract pre blocks
  extractions = {}
  text.gsub!(%r{<pre>.*?</pre>}m) do |match|
    md5 = Digest::MD5.hexdigest(match)
    extractions[md5] = match

  # prevent foo_bar_baz from ending up with an italic word in the middle
  text.gsub!(/(^(?! {4}|\t)\w+_\w+_\w[\w_]*)/) do |x|
    x.gsub('_', '\_') if x.split('').sort.to_s[0..1] == '__'

  # in very clear cases, let newlines become <br /> tags
  text.gsub!(/^[\w\<][^\n]*\n+/) do |x|
    x =~ /\n{2}/ ? x : (x.strip!; x << " \n")

  # Insert pre block extractions
  text.gsub!(/\{gfm-extraction-([0-9a-f]{32})\}/) do
    "\n\n" + extractions[$1]


if $0 == __FILE__
  require 'test/unit'
  require 'shoulda'

  class GFMTest < Test::Unit::TestCase
    context "GFM" do
      should "not touch single underscores inside words" do
        assert_equal "foo_bar", gfm("foo_bar")

      should "not touch underscores in code blocks" do
        assert_equal " foo_bar_baz", gfm(" foo_bar_baz")

      should "not touch underscores in pre blocks" do
        assert_equal "\n\n<pre>\nfoo_bar_baz\n</pre>", gfm("<pre>\nfoo_bar_baz\n</pre>")

      should "not treat pre blocks with pre-text differently" do
        a = "\n\n<pre>\nthis is `a\\_test` and this\\_too\n</pre>"
        b = "hmm<pre>\nthis is `a\\_test` and this\\_too\n</pre>"
        assert_equal gfm(a)[2..-1], gfm(b)[3..-1]

      should "escape two or more underscores inside words" do
        assert_equal "foo\\_bar\\_baz", gfm("foo_bar_baz")

      should "turn newlines into br tags in simple cases" do
        assert_equal "foo \nbar", gfm("foo\nbar")

      should "convert newlines in all groups" do
        assert_equal "apple \npear \norange\n\nruby \npython \nerlang",

      should "convert newlines in even long groups" do
        assert_equal "apple \npear \norange \nbanana\n\nruby \npython \nerlang",

      should "not convert newlines in lists" do
        assert_equal "# foo\n# bar", gfm("# foo\n# bar")
        assert_equal "* foo\n* bar", gfm("* foo\n* bar")
view raw gfm.rb This Gist brought to you by GitHub.
当前网页内容, 由 大妈 ZoomQuiet 使用工具: ScrapBook :: Firefox Extension 人工从互联网中收集并分享;
若有不妥, 欢迎评注提醒:


订阅 substack 体验古早写作:

点击注册~> 获得 100$ 体验券: DigitalOcean Referral Badge

关注公众号, 持续获得相关各种嗯哼:


关于 ~ DebugUself with DAMA ;-)
公安备案号: 44049002000656 ...::