Skip to content

Commit

Permalink
Merge pull request #814 from Golmote/prism-kotlin
Browse files Browse the repository at this point in the history
Add support for Kotlin
  • Loading branch information
Golmote committed Oct 26, 2015
2 parents d7faf2c + eb7aa96 commit e8a31a5
Show file tree
Hide file tree
Showing 14 changed files with 520 additions and 2 deletions.
5 changes: 5 additions & 0 deletions components.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,11 @@ var components = {
"title": "Keyman",
"owner": "mcdurdin"
},
"kotlin": {
"title": "Kotlin",
"require": "clike",
"owner": "Golmote"
},
"latex": {
"title": "LaTeX",
"owner": "japborst"
Expand Down
68 changes: 68 additions & 0 deletions components/prism-kotlin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
(function (Prism) {
Prism.languages.kotlin = Prism.languages.extend('clike', {
'keyword': {
// The lookbehind prevents wrong highlighting of e.g. kotlin.properties.get
pattern: /(^|[^.])\b(?:abstract|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|else|enum|final|finally|for|fun|get|if|import|in|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|out|override|package|private|protected|public|reified|return|sealed|set|super|tailrec|this|throw|to|try|val|var|when|where|while)\b/,
lookbehind: true
},
'function': [
/\w+(?=\s*\()/,
{
pattern: /(\.)\w+(?=\s*\{)/,
lookbehind: true
}
],
'number': /\b(?:0[bx][\da-fA-F]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?[fFL]?)\b/,
'operator': /\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/
});

delete Prism.languages.kotlin["class-name"];

Prism.languages.insertBefore('kotlin', 'string', {
'raw-string': {
pattern: /(["'])\1\1[\s\S]*?\1{3}/,
alias: 'string'
// See interpolation below
}
});
Prism.languages.insertBefore('kotlin', 'keyword', {
'annotation': {
pattern: /\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,
alias: 'builtin'
}
});
Prism.languages.insertBefore('kotlin', 'function', {
'label': {
pattern: /\w+@|@\w+/,
alias: 'symbol'
}
});

var interpolation = [
{
pattern: /\$\{[^}]+\}/,
inside: {
delimiter: {
pattern: /^\$\{|\}$/,
alias: 'variable'
},
rest: Prism.util.clone(Prism.languages.kotlin)
}
},
{
pattern: /\$\w+/,
alias: 'variable'
}
];

Prism.languages.kotlin['string'] = {
pattern: Prism.languages.kotlin['string'],
inside: {
interpolation: interpolation
}
};
Prism.languages.kotlin['raw-string'].inside = {
interpolation: interpolation
};

}(Prism));
1 change: 1 addition & 0 deletions components/prism-kotlin.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

147 changes: 147 additions & 0 deletions examples/prism-kotlin.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<h1>Kotlin</h1>
<p>To use this language, use the class "language-kotlin".</p>

<h2>Numbers</h2>
<pre><code>123
123L
0x0F
0b00001011
123.5
123.5e10
123.5f
123.5F</code></pre>

<h2>Strings and interpolation</h2>
<pre><code>'2'
'\uFF00'
'\''

"foo $bar \"baz"
"""
foo ${40 + 2}
baz${bar()}
"""</code></pre>

<h2>Labels</h2>
<pre><code>loop@ for (i in 1..100) {
for (j in 1..100) {
if (...)
break@loop
}
}</code></pre>

<h2>Annotations</h2>
<pre><code>public class MyTest {
lateinit var subject: TestSubject

@SetUp fun setup() {
subject = TestSubject()
}

@Test fun test() {
subject.method() // dereference directly
}
}</code></pre>

<h2>Full example</h2>
<pre><code>package com.example.html

interface Element {
fun render(builder: StringBuilder, indent: String)

override fun toString(): String {
val builder = StringBuilder()
render(builder, "")
return builder.toString()
}
}

class TextElement(val text: String): Element {
override fun render(builder: StringBuilder, indent: String) {
builder.append("$indent$text\n")
}
}

abstract class Tag(val name: String): Element {
val children = arrayListOf&lt;Element>()
val attributes = hashMapOf&lt;String, String>()

protected fun initTag&lt;T: Element>(tag: T, init: T.() -> Unit): T {
tag.init()
children.add(tag)
return tag
}

override fun render(builder: StringBuilder, indent: String) {
builder.append("$indent&lt;$name${renderAttributes()}>\n")
for (c in children) {
c.render(builder, indent + " ")
}
builder.append("$indent&lt;/$name>\n")
}

private fun renderAttributes(): String? {
val builder = StringBuilder()
for (a in attributes.keySet()) {
builder.append(" $a=\"${attributes[a]}\"")
}
return builder.toString()
}
}

abstract class TagWithText(name: String): Tag(name) {
operator fun String.plus() {
children.add(TextElement(this))
}
}

class HTML(): TagWithText("html") {
fun head(init: Head.() -> Unit) = initTag(Head(), init)

fun body(init: Body.() -> Unit) = initTag(Body(), init)
}

class Head(): TagWithText("head") {
fun title(init: Title.() -> Unit) = initTag(Title(), init)
}

class Title(): TagWithText("title")

abstract class BodyTag(name: String): TagWithText(name) {
fun b(init: B.() -> Unit) = initTag(B(), init)
fun p(init: P.() -> Unit) = initTag(P(), init)
fun h1(init: H1.() -> Unit) = initTag(H1(), init)
fun a(href: String, init: A.() -> Unit) {
val a = initTag(A(), init)
a.href = href
}
}

class Body(): BodyTag("body")

class B(): BodyTag("b")
class P(): BodyTag("p")
class H1(): BodyTag("h1")
class A(): BodyTag("a") {
public var href: String
get() = attributes["href"]!!
set(value) {
attributes["href"] = value
}
}

fun html(init: HTML.() -> Unit): HTML {
val html = HTML()
html.init()
return html
}</code></pre>

<h2>Known failures</h2>
<p>There are certain edge cases where Prism will fail.
There are always such cases in every regex-based syntax highlighter.
However, Prism dares to be open and honest about them.
If a failure is listed here, it doesn’t mean it will never be fixed. This is more of a “known bugs” list, just with a certain type of bug.
</p>

<h3>Comment-like substrings</h3>
<pre><code>"foo /* bar */";</code></pre>
2 changes: 1 addition & 1 deletion plugins/autoloader/prism-autoloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
}

// The dependencies map is built automatically with gulp
var lang_dependencies = /*languages_placeholder[*/{"javascript":"clike","actionscript":"javascript","aspnet":"markup","bison":"c","c":"clike","csharp":"clike","cpp":"c","coffeescript":"javascript","crystal":"ruby","css-extras":"css","d":"clike","dart":"clike","fsharp":"clike","glsl":"clike","go":"clike","groovy":"clike","haml":"ruby","handlebars":"markup","haxe":"clike","jade":"javascript","java":"clike","less":"css","markdown":"markup","nginx":"clike","objectivec":"c","parser":"markup","php":"clike","php-extras":"php","processing":"clike","qore":"clike","jsx":["markup","javascript"],"ruby":"clike","sass":"css","scss":"css","scala":"java","smarty":"markup","swift":"clike","textile":"markup","twig":"markup","typescript":"javascript","wiki":"markup"}/*]*/;
var lang_dependencies = /*languages_placeholder[*/{"javascript":"clike","actionscript":"javascript","aspnet":"markup","bison":"c","c":"clike","csharp":"clike","cpp":"c","coffeescript":"javascript","crystal":"ruby","css-extras":"css","d":"clike","dart":"clike","fsharp":"clike","glsl":"clike","go":"clike","groovy":"clike","haml":"ruby","handlebars":"markup","haxe":"clike","jade":"javascript","java":"clike","kotlin":"clike","less":"css","markdown":"markup","nginx":"clike","objectivec":"c","parser":"markup","php":"clike","php-extras":"php","processing":"clike","qore":"clike","jsx":["markup","javascript"],"ruby":"clike","sass":"css","scss":"css","scala":"java","smarty":"markup","swift":"clike","textile":"markup","twig":"markup","typescript":"javascript","wiki":"markup"}/*]*/;

var lang_data = {};

Expand Down
2 changes: 1 addition & 1 deletion plugins/autoloader/prism-autoloader.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions tests/languages/kotlin/annotation_feature.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@Deprecated(SUBSYSTEM_DEPRECATED)
@SetUp
@Suppress
@field:Ann
@file:JvmName
@set:[Inject VisibleForTesting]

----------------------------------------------------

[
["annotation", "@Deprecated"], ["punctuation", "("], "SUBSYSTEM_DEPRECATED", ["punctuation", ")"],
["annotation", "@SetUp"],
["annotation", "@Suppress"],
["annotation", "@field:Ann"],
["annotation", "@file:JvmName"],
["annotation", "@set:[Inject VisibleForTesting]"]
]

----------------------------------------------------

Checks for annotations.
16 changes: 16 additions & 0 deletions tests/languages/kotlin/function_feature.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
foo()
foo_Bar_42()
list.filter {}

----------------------------------------------------

[
["function", "foo"], ["punctuation", "("], ["punctuation", ")"],
["function", "foo_Bar_42"], ["punctuation", "("], ["punctuation", ")"],
"\r\nlist", ["punctuation", "."],
["function", "filter"], ["punctuation", "{"], ["punctuation", "}"]
]

----------------------------------------------------

Checks for functions.
46 changes: 46 additions & 0 deletions tests/languages/kotlin/interpolation_feature.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"$foo ${bar} ${'$'} ${foobar()}"
"""
$foo ${bar}
${'$'} ${foobar()}
"""

----------------------------------------------------

[
["string", [
"\"",
["interpolation", "$foo"],
["interpolation", [
["delimiter", "${"], "bar", ["delimiter", "}"]
]],
["interpolation", [
["delimiter", "${"], ["string", "'$'"], ["delimiter", "}"]
]],
["interpolation", [
["delimiter", "${"],
["function", "foobar"], ["punctuation", "("], ["punctuation", ")"],
["delimiter", "}"]
]],
"\""
]],
["raw-string", [
"\"\"\"\r\n",
["interpolation", "$foo"],
["interpolation", [
["delimiter", "${"], "bar", ["delimiter", "}"]
]],
["interpolation", [
["delimiter", "${"], ["string", "'$'"], ["delimiter", "}"]
]],
["interpolation", [
["delimiter", "${"],
["function", "foobar"], ["punctuation", "("], ["punctuation", ")"],
["delimiter", "}"]
]],
"\r\n\"\"\""
]]
]

----------------------------------------------------

Checks for string interpolation.
Loading

0 comments on commit e8a31a5

Please sign in to comment.