mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			137 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
# Markdown implementation
 | 
						|
 | 
						|
Zulip has a special flavor of Markdown, currently called 'bugdown'
 | 
						|
after Zulip's original name of "humbug". End users are using Bugdown
 | 
						|
within the client, not original Markdown.
 | 
						|
 | 
						|
Zulip has two implementations of Bugdown.  The first is based on
 | 
						|
Python-Markdown (`zerver/lib/bugdown/`) and is used to authoritatively
 | 
						|
render messages on the backend (and implements expensive features like
 | 
						|
querying the Twitter API to render tweets nicely).  The other is in
 | 
						|
JavaScript, based on marked (`static/js/echo.js`), and is used to
 | 
						|
preview and locally echo messages the moment the sender hits enter,
 | 
						|
without waiting for round trip from the server.  The two
 | 
						|
implementations are tested for compatibility via
 | 
						|
`zerver/tests/test_bugdown.py` and the fixtures under
 | 
						|
`zerver/fixtures/bugdown-data.json`.
 | 
						|
 | 
						|
The JavaScript implementation knows which types of messages it can
 | 
						|
render correctly, and thus while there is code to rerender messages
 | 
						|
based on the authoritative backend rendering (which would clause a
 | 
						|
change in the rendering visible only to the sender shortly after a
 | 
						|
message is sent), this should never happen, and whenever it does it is
 | 
						|
considered a bug.  Instead, if the frontend doesn't know how to
 | 
						|
correctly render a message, we simply won't echo the message for the
 | 
						|
sender until it's rendered by the backend.  So for example, a message
 | 
						|
containing a link to Twitter will not be rendered by the JavaScript
 | 
						|
implementation because it doesn't support doing the 3rd party API
 | 
						|
queries required to render tweets nicely.
 | 
						|
 | 
						|
I should note that the below documentation is based on a comparison
 | 
						|
with original Markdown, not newer Markdown variants like CommonMark.
 | 
						|
 | 
						|
## Zulip's Markdown philosophy
 | 
						|
 | 
						|
Markdown is great for group chat for the same reason it's been
 | 
						|
successful in products ranging from blogs to wikis to bug trackers:
 | 
						|
it's close enough to how people try to express themselves when writing
 | 
						|
plain text (e.g. emails) that is helps more than getting in the way.
 | 
						|
 | 
						|
The main issue for using Markdown in instant messaging is that the
 | 
						|
Markdown standard syntax used in a lot of wikis/blogs has nontrivial
 | 
						|
error rates, where the author needs to go back and edit the post to
 | 
						|
fix the formatting after typing it the first time.  While that's
 | 
						|
basically fine when writing a blog, it gets annoying very fast in a
 | 
						|
chat product; even though you can edit messages to fix formatting
 | 
						|
mistakes, you don't want to be doing that often.  There are basically
 | 
						|
2 types of error rates that are important for a product like Zulip:
 | 
						|
 | 
						|
* What fraction of the time, if you pasted a short technical email
 | 
						|
that you wrote to your team and passed it through your Markdown
 | 
						|
implementation, would you need to change the text of your email for it
 | 
						|
to render in a reasonable way?  This is the "accidental Markdown
 | 
						|
syntax" problem, common with Markdown syntax like the italics syntax
 | 
						|
interacting with talking about `char *`s.
 | 
						|
 | 
						|
* What fraction of the time do users attempting to use a particular
 | 
						|
Markdown syntax actually succeed at doing so correctly?  Syntax like
 | 
						|
required a blank line between text and the start of a bulleted list
 | 
						|
raise this figure substantially.
 | 
						|
 | 
						|
Both of these are minor issues for most products using Markdown, but
 | 
						|
they are major problems in the instant messaging context, because one
 | 
						|
can't edit a message that has already been sent and users are
 | 
						|
generally writing quickly.  Zulip's Markdown strategy is based on the
 | 
						|
principles of giving users the power they need to express complicated
 | 
						|
ideas in a chat context while minimizing those two error rates.
 | 
						|
 | 
						|
## Zulip's Changes to Markdown
 | 
						|
 | 
						|
Below, we document the changes that Zulip has against stock
 | 
						|
Python-Markdown; some of the features we modify / disable may already
 | 
						|
be non-standard.
 | 
						|
 | 
						|
### Basic syntax
 | 
						|
 | 
						|
* Enable `nl2br</tt> extension: this means one newline creates a line
 | 
						|
  break (not paragraph break).
 | 
						|
 | 
						|
* Disable italics entirely.  This resolves an issue where people were
 | 
						|
  using `*` and `_` and hitting it by mistake too often.  E.g. with
 | 
						|
  stock Markdown `You should use char * instead of void * there` would
 | 
						|
  trigger italics.
 | 
						|
 | 
						|
* Allow only `**` syntax for bold, not `__` (easy to hit by mistake if
 | 
						|
  discussing Python `__init__` or something)
 | 
						|
 | 
						|
* Disable special use of `\` to escape other syntax. Rendering `\\` as
 | 
						|
  `\` was hugely controversial, but having no escape syntax is also
 | 
						|
  controversial.  We may revisit this.  For now you can always put
 | 
						|
  things in code blocks.
 | 
						|
 | 
						|
### Lists
 | 
						|
 | 
						|
* Allow tacking a bulleted list or block quote onto the end of a
 | 
						|
  paragraph, i.e. without a blank line before it
 | 
						|
 | 
						|
* Allow only `*` for bulleted lists, not `+` or `-` (previously
 | 
						|
  created confusion with diff-style text sloppily not included in a
 | 
						|
  code block)
 | 
						|
 | 
						|
* Disable ordered list syntax: it automatically renumbers, which can
 | 
						|
  be really confusing when sending a numbered list across multiple
 | 
						|
  messages.
 | 
						|
 | 
						|
### Links
 | 
						|
 | 
						|
* Enable auto-linkification, both for `http://...` and guessing at
 | 
						|
  things like `t.co/foo`.
 | 
						|
 | 
						|
* Force links to be absolute. `[foo](google.com)` will go to
 | 
						|
  `http://google.com`, and not `http://zulip.com/google.com` which
 | 
						|
  is the default behavior.
 | 
						|
 | 
						|
* Set `target="_blank"` and `title=`(the url) on every link tag so
 | 
						|
  clicking always opens a new window
 | 
						|
 | 
						|
* Disable link-by-reference syntax, `[foo][bar]` ... `[bar]: http://google.com`
 | 
						|
 | 
						|
### Code
 | 
						|
 | 
						|
* Enable fenced code block extension, with syntax highlighting
 | 
						|
 | 
						|
* Disable line-numbering within fenced code blocks -- the `<table>`
 | 
						|
  output confused our web client code.
 | 
						|
 | 
						|
### Other
 | 
						|
 | 
						|
* Disable headings, both `# foo` and `== foo ==` syntax: they don't
 | 
						|
  make much sense for chat messages.
 | 
						|
 | 
						|
* Disabled images.
 | 
						|
 | 
						|
* Allow embedding any avatar as a tiny (list bullet size) image.  This
 | 
						|
  is used primarily by version control integrations.
 | 
						|
 | 
						|
* We added the `~~~ quote` block quote syntax.
 |