Commit e90a9b01 authored by Robert Speicher's avatar Robert Speicher

Merge branch 'blockquote-fence-filter' into 'master'

Add blockquote fence syntax to Markdown

Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/16564

Before Markdown rendering happens, this will transform this:

```
Let me quote this here email:

>>>
Dear friend,

How are you?

Greetings,

Me
>>>
```

Into this, saving me from having to prefix all of those lines with `>` manually when I copy some multiline text from another medium:

```
Let me quote this here email:

> Dear friend,
> 
> How are you?
> 
> Greetings,
> 
> Me
```

See merge request !3954
parents 1a9adb2d 6ba88453
...@@ -18,6 +18,7 @@ v 8.10.0 (unreleased) ...@@ -18,6 +18,7 @@ v 8.10.0 (unreleased)
- Fix MR-auto-close text added to description. !4836 - Fix MR-auto-close text added to description. !4836
- Fix issue, preventing users w/o push access to sort tags !5105 (redetection) - Fix issue, preventing users w/o push access to sort tags !5105 (redetection)
- Add Spring EmojiOne updates. - Add Spring EmojiOne updates.
- Add syntax for multiline blockquote using `>>>` fence !3954
- Fix viewing notification settings when a project is pending deletion - Fix viewing notification settings when a project is pending deletion
- Fix pagination when sorting by columns with lots of ties (like priority) - Fix pagination when sorting by columns with lots of ties (like priority)
- The Markdown reference parsers now re-use query results to prevent running the same queries multiple times !5020 - The Markdown reference parsers now re-use query results to prevent running the same queries multiple times !5020
......
...@@ -7,11 +7,12 @@ ...@@ -7,11 +7,12 @@
* [Newlines](#newlines) * [Newlines](#newlines)
* [Multiple underscores in words](#multiple-underscores-in-words) * [Multiple underscores in words](#multiple-underscores-in-words)
* [URL auto-linking](#url-auto-linking) * [URL auto-linking](#url-auto-linking)
* [Multiline Blockquote](#multiline-blockquote)
* [Code and Syntax Highlighting](#code-and-syntax-highlighting) * [Code and Syntax Highlighting](#code-and-syntax-highlighting)
* [Inline Diff](#inline-diff) * [Inline Diff](#inline-diff)
* [Emoji](#emoji) * [Emoji](#emoji)
* [Special GitLab references](#special-gitlab-references) * [Special GitLab references](#special-gitlab-references)
* [Task lists](#task-lists) * [Task Lists](#task-lists)
**[Standard Markdown](#standard-markdown)** **[Standard Markdown](#standard-markdown)**
...@@ -89,6 +90,37 @@ GFM will autolink almost any URL you copy and paste into your text. ...@@ -89,6 +90,37 @@ GFM will autolink almost any URL you copy and paste into your text.
* irc://irc.freenode.net/gitlab * irc://irc.freenode.net/gitlab
* http://localhost:3000 * http://localhost:3000
## Multiline Blockquote
On top of standard Markdown [blockquotes](#blockquotes), which require prepending `>` to quoted lines,
GFM supports multiline blockquotes fenced by <code>>>></code>.
```no-highlight
>>>
If you paste a message from somewhere else
that
spans
multiple lines,
you can quote that without having to manually prepend `>` to every line!
>>>
```
>>>
If you paste a message from somewhere else
that
spans
multiple lines,
you can quote that without having to manually prepend `>` to every line!
>>>
## Code and Syntax Highlighting ## Code and Syntax Highlighting
_GitLab uses the [Rouge Ruby library][rouge] for syntax highlighting. For a _GitLab uses the [Rouge Ruby library][rouge] for syntax highlighting. For a
......
module Banzai
module Filter
class BlockquoteFenceFilter < HTML::Pipeline::TextFilter
REGEX = %r{
(?<code>
# Code blocks:
# ```
# Anything, including `>>>` blocks which are ignored by this filter
# ```
^```
.+?
\n```$
)
|
(?<html>
# HTML block:
# <tag>
# Anything, including `>>>` blocks which are ignored by this filter
# </tag>
^<[^>]+?>\n
.+?
\n<\/[^>]+?>$
)
|
(?:
# Blockquote:
# >>>
# Anything, including code and HTML blocks
# >>>
^>>>\n
(?<quote>
(?:
# Any character that doesn't introduce a code or HTML block
(?!
^```
|
^<[^>]+?>\n
)
.
|
# A code block
\g<code>
|
# An HTML block
\g<html>
)+?
)
\n>>>$
)
}mx.freeze
def initialize(text, context = nil, result = nil)
super text, context, result
@text = @text.delete("\r")
end
def call
@text.gsub(REGEX) do
if $~[:quote]
$~[:quote].gsub(/^/, "> ").gsub(/^> $/, ">")
else
$~[0]
end
end
end
end
end
end
...@@ -3,7 +3,8 @@ module Banzai ...@@ -3,7 +3,8 @@ module Banzai
class PreProcessPipeline < BasePipeline class PreProcessPipeline < BasePipeline
def self.filters def self.filters
FilterArray[ FilterArray[
Filter::YamlFrontMatterFilter Filter::YamlFrontMatterFilter,
Filter::BlockquoteFenceFilter,
] ]
end end
......
Single `>>>` inside code block:
```
# Code
>>>
# Code
```
Double `>>>` inside code block:
```txt
# Code
>>>
# Code
>>>
# Code
```
Blockquote outside code block:
> Quote
Code block inside blockquote:
> Quote
>
> ```
> # Code
> ```
>
> Quote
Single `>>>` inside code block inside blockquote:
> Quote
>
> ```
> # Code
> >>>
> # Code
> ```
>
> Quote
Double `>>>` inside code block inside blockquote:
> Quote
>
> ```
> # Code
> >>>
> # Code
> >>>
> # Code
> ```
>
> Quote
Single `>>>` inside HTML:
<pre>
# Code
>>>
# Code
</pre>
Double `>>>` inside HTML:
<pre>
# Code
>>>
# Code
>>>
# Code
</pre>
Blockquote outside HTML:
> Quote
HTML inside blockquote:
> Quote
>
> <pre>
> # Code
> </pre>
>
> Quote
Single `>>>` inside HTML inside blockquote:
> Quote
>
> <pre>
> # Code
> >>>
> # Code
> </pre>
>
> Quote
Double `>>>` inside HTML inside blockquote:
> Quote
>
> <pre>
> # Code
> >>>
> # Code
> >>>
> # Code
> </pre>
>
> Quote
Single `>>>` inside code block:
```
# Code
>>>
# Code
```
Double `>>>` inside code block:
```txt
# Code
>>>
# Code
>>>
# Code
```
Blockquote outside code block:
>>>
Quote
>>>
Code block inside blockquote:
>>>
Quote
```
# Code
```
Quote
>>>
Single `>>>` inside code block inside blockquote:
>>>
Quote
```
# Code
>>>
# Code
```
Quote
>>>
Double `>>>` inside code block inside blockquote:
>>>
Quote
```
# Code
>>>
# Code
>>>
# Code
```
Quote
>>>
Single `>>>` inside HTML:
<pre>
# Code
>>>
# Code
</pre>
Double `>>>` inside HTML:
<pre>
# Code
>>>
# Code
>>>
# Code
</pre>
Blockquote outside HTML:
>>>
Quote
>>>
HTML inside blockquote:
>>>
Quote
<pre>
# Code
</pre>
Quote
>>>
Single `>>>` inside HTML inside blockquote:
>>>
Quote
<pre>
# Code
>>>
# Code
</pre>
Quote
>>>
Double `>>>` inside HTML inside blockquote:
>>>
Quote
<pre>
# Code
>>>
# Code
>>>
# Code
</pre>
Quote
>>>
require 'rails_helper'
describe Banzai::Filter::BlockquoteFenceFilter, lib: true do
include FilterSpecHelper
it 'converts blockquote fences to blockquote lines' do
content = File.read(Rails.root.join('spec/fixtures/blockquote_fence_before.md'))
expected = File.read(Rails.root.join('spec/fixtures/blockquote_fence_after.md'))
output = filter(content)
expect(output).to eq(expected)
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment