Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
d90d141c
Commit
d90d141c
authored
Dec 20, 2017
by
Tony Rom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Colors to GitLab Flavored Markdown
parent
501d81c5
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
360 additions
and
2 deletions
+360
-2
app/assets/javascripts/gfm_auto_complete.js
app/assets/javascripts/gfm_auto_complete.js
+1
-1
app/assets/stylesheets/framework/gfm.scss
app/assets/stylesheets/framework/gfm.scss
+30
-0
changelogs/unreleased/24167__color_label.yml
changelogs/unreleased/24167__color_label.yml
+5
-0
doc/user/markdown.md
doc/user/markdown.md
+40
-1
lib/banzai/color_parser.rb
lib/banzai/color_parser.rb
+50
-0
lib/banzai/filter/color_filter.rb
lib/banzai/filter/color_filter.rb
+31
-0
lib/banzai/pipeline/broadcast_message_pipeline.rb
lib/banzai/pipeline/broadcast_message_pipeline.rb
+1
-0
lib/banzai/pipeline/gfm_pipeline.rb
lib/banzai/pipeline/gfm_pipeline.rb
+1
-0
spec/features/markdown_spec.rb
spec/features/markdown_spec.rb
+8
-0
spec/fixtures/markdown.md.erb
spec/fixtures/markdown.md.erb
+12
-0
spec/javascripts/gfm_auto_complete_spec.js
spec/javascripts/gfm_auto_complete_spec.js
+9
-0
spec/lib/banzai/color_parser_spec.rb
spec/lib/banzai/color_parser_spec.rb
+90
-0
spec/lib/banzai/filter/color_filter_spec.rb
spec/lib/banzai/filter/color_filter_spec.rb
+61
-0
spec/support/matchers/markdown_matchers.rb
spec/support/matchers/markdown_matchers.rb
+21
-0
No files found.
app/assets/javascripts/gfm_auto_complete.js
View file @
d90d141c
...
...
@@ -461,7 +461,7 @@ class GfmAutoComplete {
const
accentAChar
=
decodeURI
(
'
%C3%80
'
);
const
accentYChar
=
decodeURI
(
'
%C3%BF
'
);
const
regexp
=
new
RegExp
(
`^(?:\\B|[^a-zA-Z0-9_
${
atSymbolsWithoutBar
}
]|\\s)
${
resultantFlag
}
(?!
${
atSymbolsWithBar
}
)((?:[A-Za-z
${
accentAChar
}
-
${
accentYChar
}
0-9_'.+-]|[^\\x00-\\x7a])*)$`
,
'
gi
'
);
const
regexp
=
new
RegExp
(
`^(?:\\B|[^a-zA-Z0-9_
\`
${
atSymbolsWithoutBar
}
]|\\s)
${
resultantFlag
}
(?!
${
atSymbolsWithBar
}
)((?:[A-Za-z
${
accentAChar
}
-
${
accentYChar
}
0-9_'.+-]|[^\\x00-\\x7a])*)$`
,
'
gi
'
);
return
regexp
.
exec
(
targetSubtext
);
}
...
...
app/assets/stylesheets/framework/gfm.scss
View file @
d90d141c
...
...
@@ -16,3 +16,33 @@
background-color
:
$user-mention-bg-hover
;
}
}
.gfm-color_chip
{
display
:
inline-block
;
margin-left
:
4px
;
margin-bottom
:
2px
;
vertical-align
:
middle
;
border-radius
:
3px
;
$side
:
0
.9em
;
$bg-size
:
$side
/
0
.9
;
$bg-pos
:
$bg-size
/
2
;
$bg-color
:
$gray-dark
;
width
:
$side
;
height
:
$side
;
background
:
$white-light
;
background-image
:
linear-gradient
(
135deg
,
$bg-color
25%
,
transparent
0%
,
transparent
75%
,
$bg-color
0%
)
,
linear-gradient
(
135deg
,
$bg-color
25%
,
transparent
0%
,
transparent
75%
,
$bg-color
0%
);
background-size
:
$bg-size
$bg-size
;
background-position
:
0
0
,
$bg-pos
$bg-pos
;
>
span
{
display
:
inline-block
;
width
:
100%
;
height
:
100%
;
margin-bottom
:
2px
;
border-radius
:
3px
;
border
:
1px
solid
$black-transparent
;
}
}
changelogs/unreleased/24167__color_label.yml
0 → 100644
View file @
d90d141c
---
title
:
Add Colors to GitLab Flavored Markdown
merge_request
:
16095
author
:
Tony Rom <thetonyrom@gmail.com>
type
:
added
doc/user/markdown.md
View file @
d90d141c
...
...
@@ -253,7 +253,7 @@ GFM will recognize the following:
|
`@user_name`
| specific user |
|
`@group_name`
| specific group |
|
`@all`
| entire team |
|
`#123
`
| issue |
|
`#123
45`
| issue |
|
`!123`
| merge request |
|
`$123`
| snippet |
|
`~123`
| label by ID |
...
...
@@ -379,6 +379,45 @@ _Be advised that KaTeX only supports a [subset][katex-subset] of LaTeX._
>**Note:**
This also works for the asciidoctor
`:stem: latexmath`
. For details see the
[
asciidoctor user manual
][
asciidoctor-manual
]
.
### Colors
> If this is not rendered correctly, see
https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/user/markdown.md#colors
It is possible to have color written in HEX, RGB or HSL format rendered with a color indicator.
Color written inside backticks will be followed by a color "chip".
Examples:
`#F00`
`#F00A`
`#FF0000`
`#FF0000AA`
`RGB(0,255,0)`
`RGB(0%,100%,0%)`
`RGBA(0,255,0,0.7)`
`HSL(540,70%,50%)`
`HSLA(540,70%,50%,0.7)`
Becomes:
`#F00`
`#F00A`
`#FF0000`
`#FF0000AA`
`RGB(0,255,0)`
`RGB(0%,100%,0%)`
`RGBA(0,255,0,0.7)`
`HSL(540,70%,50%)`
`HSLA(540,70%,50%,0.7)`
#### Supported formats:
*
HEX:
`` `#RGB[A]` ``
or
`` `#RRGGBB[AA]` ``
*
RGB:
`` `RGB[A](R, G, B[, A])` ``
*
HSL:
`` `HSL[A](H, S, L[, A])` ``
### Mermaid
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/15107) in
...
...
lib/banzai/color_parser.rb
0 → 100644
View file @
d90d141c
module
Banzai
module
ColorParser
ALPHA
=
/0(?:\.\d+)?|\.\d+|1(?:\.0+)?/
# 0.0..1.0
PERCENTS
=
/(?:\d{1,2}|100)%/
# 00%..100%
ALPHA_CHANNEL
=
/(?:,\s*(?:
#{
ALPHA
}
|
#{
PERCENTS
}
))?/
BITS
=
/\d{1,2}|1\d\d|2(?:[0-4]\d|5[0-5])/
# 00..255
DEGS
=
/-?\d+(?:deg)?/i
# [-]digits[deg]
RADS
=
/-?(?:\d+(?:\.\d+)?|\.\d+)rad/i
# [-](digits[.digits] OR .digits)rad
HEX_FORMAT
=
/\#(?:\h{3}|\h{4}|\h{6}|\h{8})/
RGB_FORMAT
=
/
(?:rgba?
\(
(?:
(?:(?:
#{
BITS
}
,\s*){2}
#{
BITS
}
)
|
(?:(?:
#{
PERCENTS
}
,\s*){2}
#{
PERCENTS
}
)
)
#{
ALPHA_CHANNEL
}
\)
)
/xi
HSL_FORMAT
=
/
(?:hsla?
\(
(?:
#{
DEGS
}
|
#{
RADS
}
),\s*
#{
PERCENTS
}
,\s*
#{
PERCENTS
}
#{
ALPHA_CHANNEL
}
\)
)
/xi
FORMATS
=
[
HEX_FORMAT
,
RGB_FORMAT
,
HSL_FORMAT
].
freeze
class
<<
self
# Public: Analyzes whether the String is a color code.
#
# text - The String to be parsed.
#
# Returns the recognized color String or nil if none was found.
def
parse
(
text
)
text
if
color_format
=~
text
end
private
def
color_format
@color_format
||=
/\A(
#{
Regexp
.
union
(
FORMATS
)
}
)\z/ix
end
end
end
end
lib/banzai/filter/color_filter.rb
0 → 100644
View file @
d90d141c
module
Banzai
module
Filter
# HTML filter that renders `color` followed by a color "chip".
#
class
ColorFilter
<
HTML
::
Pipeline
::
Filter
COLOR_CHIP_CLASS
=
'gfm-color_chip'
.
freeze
def
call
doc
.
css
(
'code'
).
each
do
|
node
|
color
=
ColorParser
.
parse
(
node
.
content
)
node
<<
color_chip
(
color
)
if
color
end
doc
end
private
def
color_chip
(
color
)
checkerboard
=
doc
.
document
.
create_element
(
'span'
,
class:
COLOR_CHIP_CLASS
)
chip
=
doc
.
document
.
create_element
(
'span'
,
style:
inline_styles
(
color:
color
))
checkerboard
<<
chip
end
def
inline_styles
(
color
:)
"background-color:
#{
color
}
;"
end
end
end
end
lib/banzai/pipeline/broadcast_message_pipeline.rb
View file @
d90d141c
...
...
@@ -7,6 +7,7 @@ module Banzai
Filter
::
SanitizationFilter
,
Filter
::
EmojiFilter
,
Filter
::
ColorFilter
,
Filter
::
AutolinkFilter
,
Filter
::
ExternalLinkFilter
]
...
...
lib/banzai/pipeline/gfm_pipeline.rb
View file @
d90d141c
...
...
@@ -14,6 +14,7 @@ module Banzai
Filter
::
SyntaxHighlightFilter
,
Filter
::
MathFilter
,
Filter
::
ColorFilter
,
Filter
::
MermaidFilter
,
Filter
::
VideoLinkFilter
,
Filter
::
ImageLazyLoadFilter
,
...
...
spec/features/markdown_spec.rb
View file @
d90d141c
...
...
@@ -259,6 +259,10 @@ describe 'GitLab Markdown' do
it
'includes VideoLinkFilter'
do
expect
(
doc
).
to
parse_video_links
end
it
'includes ColorFilter'
do
expect
(
doc
).
to
parse_colors
end
end
context
'wiki pipeline'
do
...
...
@@ -320,6 +324,10 @@ describe 'GitLab Markdown' do
it
'includes VideoLinkFilter'
do
expect
(
doc
).
to
parse_video_links
end
it
'includes ColorFilter'
do
expect
(
doc
).
to
parse_colors
end
end
# Fake a `current_user` helper
...
...
spec/fixtures/markdown.md.erb
View file @
d90d141c
...
...
@@ -280,6 +280,18 @@ However the wrapping tags cannot be mixed as such:
![My Video](/assets/videos/gitlab-demo.mp4)
### Colors
`#F00`
`#F00A`
`#FF0000`
`#FF0000AA`
`RGB(0,255,0)`
`RGB(0%,100%,0%)`
`RGBA(0,255,0,0.7)`
`HSL(540,70%,50%)`
`HSLA(540,70%,50%,0.7)`
### Mermaid
> If this is not rendered correctly, see
...
...
spec/javascripts/gfm_auto_complete_spec.js
View file @
d90d141c
...
...
@@ -131,6 +131,7 @@ describe('GfmAutoComplete', function () {
describe
(
'
should not match special sequences
'
,
()
=>
{
const
ShouldNotBeFollowedBy
=
flags
.
concat
([
'
\
x00
'
,
'
\
x10
'
,
'
\
x3f
'
,
'
\n
'
,
'
'
]);
const
ShouldNotBePrependedBy
=
[
'
`
'
];
flagsUseDefaultMatcher
.
forEach
((
atSign
)
=>
{
ShouldNotBeFollowedBy
.
forEach
((
followedSymbol
)
=>
{
...
...
@@ -140,6 +141,14 @@ describe('GfmAutoComplete', function () {
expect
(
defaultMatcher
(
atwhoInstance
,
atSign
,
seq
)).
toBe
(
null
);
});
});
ShouldNotBePrependedBy
.
forEach
((
prependedSymbol
)
=>
{
const
seq
=
prependedSymbol
+
atSign
;
it
(
`should not match "
${
seq
}
"`
,
()
=>
{
expect
(
defaultMatcher
(
atwhoInstance
,
atSign
,
seq
)).
toBe
(
null
);
});
});
});
});
});
...
...
spec/lib/banzai/color_parser_spec.rb
0 → 100644
View file @
d90d141c
require
'spec_helper'
describe
Banzai
::
ColorParser
do
describe
'.parse'
do
context
'HEX format'
do
[
'#abc'
,
'#ABC'
,
'#d2d2d2'
,
'#D2D2D2'
,
'#123a'
,
'#123A'
,
'#123456aa'
,
'#123456AA'
].
each
do
|
color
|
it
"parses the valid hex color
#{
color
}
"
do
expect
(
subject
.
parse
(
color
)).
to
eq
(
color
)
end
end
[
'#'
,
'#1'
,
'#12'
,
'#12g'
,
'#12G'
,
'#12345'
,
'#r2r2r2'
,
'#R2R2R2'
,
'#1234567'
,
'# 123'
,
'# 1234'
,
'# 123456'
,
'# 12345678'
,
'#1 2 3'
,
'#123 4'
,
'#12 34 56'
,
'#123456 78'
].
each
do
|
color
|
it
"does not parse the invalid hex color
#{
color
}
"
do
expect
(
subject
.
parse
(
color
)).
to
be_nil
end
end
end
context
'RGB format'
do
[
'rgb(0,0,0)'
,
'rgb(255,255,255)'
,
'rgb(0, 0, 0)'
,
'RGB(0,0,0)'
,
'rgb(0,0,0,0)'
,
'rgb(0,0,0,0.0)'
,
'rgb(0,0,0,.0)'
,
'rgb(0,0,0, 0)'
,
'rgb(0,0,0, 0.0)'
,
'rgb(0,0,0, .0)'
,
'rgb(0,0,0,1)'
,
'rgb(0,0,0,1.0)'
,
'rgba(0,0,0)'
,
'rgba(0,0,0,0)'
,
'RGBA(0,0,0)'
,
'rgb(0%,0%,0%)'
,
'rgba(0%,0%,0%,0%)'
].
each
do
|
color
|
it
"parses the valid rgb color
#{
color
}
"
do
expect
(
subject
.
parse
(
color
)).
to
eq
(
color
)
end
end
[
'FOOrgb(0,0,0)'
,
'rgb(0,0,0)BAR'
,
'rgb(0,0,-1)'
,
'rgb(0,0,-0)'
,
'rgb(0,0,256)'
,
'rgb(0,0,0,-0.1)'
,
'rgb(0,0,0,-0.0)'
,
'rgb(0,0,0,-.1)'
,
'rgb(0,0,0,1.1)'
,
'rgb(0,0,0,2)'
,
'rgba(0,0,0,)'
,
'rgba(0,0,0,0.)'
,
'rgba(0,0,0,1.)'
,
'rgb(0,0,0%)'
,
'rgb(101%,0%,0%)'
].
each
do
|
color
|
it
"does not parse the invalid rgb color
#{
color
}
"
do
expect
(
subject
.
parse
(
color
)).
to
be_nil
end
end
end
context
'HSL format'
do
[
'hsl(0,0%,0%)'
,
'hsl(0,100%,100%)'
,
'hsl(540,0%,0%)'
,
'hsl(-720,0%,0%)'
,
'hsl(0deg,0%,0%)'
,
'hsl(0DEG,0%,0%)'
,
'hsl(0, 0%, 0%)'
,
'HSL(0,0%,0%)'
,
'hsl(0,0%,0%,0)'
,
'hsl(0,0%,0%,0.0)'
,
'hsl(0,0%,0%,.0)'
,
'hsl(0,0%,0%, 0)'
,
'hsl(0,0%,0%, 0.0)'
,
'hsl(0,0%,0%, .0)'
,
'hsl(0,0%,0%,1)'
,
'hsl(0,0%,0%,1.0)'
,
'hsla(0,0%,0%)'
,
'hsla(0,0%,0%,0)'
,
'HSLA(0,0%,0%)'
,
'hsl(1rad,0%,0%)'
,
'hsl(1.1rad,0%,0%)'
,
'hsl(.1rad,0%,0%)'
,
'hsl(-1rad,0%,0%)'
,
'hsl(1RAD,0%,0%)'
].
each
do
|
color
|
it
"parses the valid hsl color
#{
color
}
"
do
expect
(
subject
.
parse
(
color
)).
to
eq
(
color
)
end
end
[
'hsl(+0,0%,0%)'
,
'hsl(0,0,0%)'
,
'hsl(0,0%,0)'
,
'hsl(0 deg,0%,0%)'
,
'hsl(0,-0%,0%)'
,
'hsl(0,101%,0%)'
,
'hsl(0,-1%,0%)'
,
'hsl(0,0%,0%,-0.1)'
,
'hsl(0,0%,0%,-.1)'
,
'hsl(0,0%,0%,1.1)'
,
'hsl(0,0%,0%,2)'
,
'hsl(0,0%,0%,)'
,
'hsl(0,0%,0%,0.)'
,
'hsl(0,0%,0%,1.)'
,
'hsl(deg,0%,0%)'
,
'hsl(rad,0%,0%)'
].
each
do
|
color
|
it
"does not parse the invalid hsl color
#{
color
}
"
do
expect
(
subject
.
parse
(
color
)).
to
be_nil
end
end
end
end
end
spec/lib/banzai/filter/color_filter_spec.rb
0 → 100644
View file @
d90d141c
require
'spec_helper'
describe
Banzai
::
Filter
::
ColorFilter
,
lib:
true
do
include
FilterSpecHelper
let
(
:color
)
{
'#F00'
}
let
(
:color_chip_selector
)
{
'code > span.gfm-color_chip > span'
}
[
'#123'
,
'#1234'
,
'#123456'
,
'#12345678'
,
'rgb(0,0,0)'
,
'RGB(0, 0, 0)'
,
'rgba(0,0,0,1)'
,
'RGBA(0,0,0,0.7)'
,
'hsl(270,30%,50%)'
,
'HSLA(270, 30%, 50%, .7)'
].
each
do
|
color
|
it
"inserts color chip for supported color format
#{
color
}
"
do
content
=
code_tag
(
color
)
doc
=
filter
(
content
)
color_chip
=
doc
.
at_css
(
color_chip_selector
)
expect
(
color_chip
.
content
).
to
be_empty
expect
(
color_chip
.
parent
[
:class
]).
to
eq
'gfm-color_chip'
expect
(
color_chip
[
:style
]).
to
eq
"background-color:
#{
color
}
;"
end
end
it
'ignores valid color code without backticks(code tags)'
do
doc
=
filter
(
color
)
expect
(
doc
.
css
(
'span.gfm-color_chip'
).
size
).
to
be_zero
end
it
'ignores valid color code with prepended space'
do
content
=
code_tag
(
' '
+
color
)
doc
=
filter
(
content
)
expect
(
doc
.
css
(
color_chip_selector
).
size
).
to
be_zero
end
it
'ignores valid color code with appended space'
do
content
=
code_tag
(
color
+
' '
)
doc
=
filter
(
content
)
expect
(
doc
.
css
(
color_chip_selector
).
size
).
to
be_zero
end
it
'ignores valid color code surrounded by spaces'
do
content
=
code_tag
(
' '
+
color
+
' '
)
doc
=
filter
(
content
)
expect
(
doc
.
css
(
color_chip_selector
).
size
).
to
be_zero
end
it
'ignores invalid color code'
do
invalid_color
=
'#BAR'
content
=
code_tag
(
invalid_color
)
doc
=
filter
(
content
)
expect
(
doc
.
css
(
color_chip_selector
).
size
).
to
be_zero
end
def
code_tag
(
string
)
"<code>
#{
string
}
</code>"
end
end
spec/support/matchers/markdown_matchers.rb
View file @
d90d141c
...
...
@@ -190,6 +190,27 @@ module MarkdownMatchers
expect
(
video
[
'src'
]).
to
end_with
(
'/assets/videos/gitlab-demo.mp4'
)
end
end
# ColorFilter
matcher
:parse_colors
do
set_default_markdown_messages
match
do
|
actual
|
color_chips
=
actual
.
css
(
'code > span.gfm-color_chip > span'
)
expect
(
color_chips
.
count
).
to
eq
(
9
)
[
'#F00'
,
'#F00A'
,
'#FF0000'
,
'#FF0000AA'
,
'RGB(0,255,0)'
,
'RGB(0%,100%,0%)'
,
'RGBA(0,255,0,0.7)'
,
'HSL(540,70%,50%)'
,
'HSLA(540,70%,50%,0.7)'
].
each_with_index
do
|
color
,
i
|
parsed_color
=
Banzai
::
ColorParser
.
parse
(
color
)
expect
(
color_chips
[
i
][
'style'
]).
to
match
(
"background-color:
#{
parsed_color
}
;"
)
expect
(
color_chips
[
i
].
parent
.
parent
.
content
).
to
match
(
color
)
end
end
end
end
# Monkeypatch the matcher DSL so that we can reduce some noisy duplication for
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment