Commit 345b1b2afd8bc111cc4218036da050be1b54067c

Roman Miroshnychenko 2017-01-28T11:08:49

Adds Django/Jinja2 language definition (#1085)

diff --git a/components.js b/components.js
index bb89769..0d6fe77 100644
--- a/components.js
+++ b/components.js
@@ -167,6 +167,11 @@ var components = {
 			"require": "clike",
 			"owner": "Golmote"
 		},
+		"django": {
+			"title": "Django/Jinja2",
+			"require": "markup",
+			"owner": "romanvm"
+		},
 		"diff": {
 			"title": "Diff",
 			"owner": "uranusjr"
diff --git a/components/prism-django.js b/components/prism-django.js
new file mode 100644
index 0000000..d545b14
--- /dev/null
+++ b/components/prism-django.js
@@ -0,0 +1,41 @@
+// Django/Jinja2 syntax definition for Prism.js <http://prismjs.com> syntax highlighter.
+// Mostly it works OK but can paint code incorrectly on complex html/template tag combinations.
+
+var _django_template = {
+	'property': {
+		pattern: /(?:{{|{%)[\w\W]*?(?:%}|}})/g,
+		greedy: true,
+		inside: {
+			'string': {
+				pattern: /("|')(?:\\\\|\\?[^\\\r\n])*?\1/,
+				greedy: true
+			},
+			'keyword': /\b(?:\||load|verbatim|widthratio|ssi|firstof|for|url|ifchanged|csrf_token|lorem|ifnotequal|autoescape|now|templatetag|debug|cycle|ifequal|regroup|comment|filter|endfilter|if|spaceless|with|extends|block|include|else|empty|endif|endfor|as|endblock|endautoescape|endverbatim|trans|endtrans|[Tt]rue|[Ff]alse|[Nn]one|in|is|static|macro|endmacro|call|endcall|set|endset|raw|endraw)\b/,
+			'operator' : /[-+=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,
+			'function': /\b(?:_|abs|add|addslashes|attr|batch|callable|capfirst|capitalize|center|count|cut|d|date|default|default_if_none|defined|dictsort|dictsortreversed|divisibleby|e|equalto|escape|escaped|escapejs|even|filesizeformat|first|float|floatformat|force_escape|forceescape|format|get_digit|groupby|indent|int|iriencode|iterable|join|last|length|length_is|linebreaks|linebreaksbr|linenumbers|list|ljust|lower|make_list|map|mapping|number|odd|phone2numeric|pluralize|pprint|random|reject|rejectattr|removetags|replace|reverse|rjust|round|safe|safeseq|sameas|select|selectattr|sequence|slice|slugify|sort|string|stringformat|striptags|sum|time|timesince|timeuntil|title|trim|truncate|truncatechars|truncatechars_html|truncatewords|truncatewords_html|undefined|unordered_list|upper|urlencode|urlize|urlizetrunc|wordcount|wordwrap|xmlattr|yesno)\b/,
+			'important': /\b-?\d+(?:\.\d+)?\b/,
+			'variable': /\b\w+?\b/,
+			'punctuation' : /[[\];(),.:]/
+		}
+	},
+};
+
+Prism.languages.django = Prism.languages.extend('markup', {'comment': /(?:<!--|{#)[\w\W]*?(?:#}|-->)/});
+// Updated html tag pattern to allow template tags inside html tags
+Prism.languages.django.tag.pattern = /<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^>=]+))?)*\s*\/?>/i;
+Prism.languages.insertBefore('django', 'entity', _django_template);
+Prism.languages.insertBefore('inside', 'tag', _django_template, Prism.languages.django.tag);
+
+if (Prism.languages.javascript) {
+	// Combine js code and template tags painting inside <script> blocks
+	Prism.languages.insertBefore('inside', 'string', _django_template, Prism.languages.django.script);
+	Prism.languages.django.script.inside.string.inside = _django_template;
+}
+if (Prism.languages.css) {
+	// Combine css code and template tags painting inside <style> blocks
+	Prism.languages.insertBefore('inside', 'atrule', {'tag': _django_template.property}, Prism.languages.django.style);
+	Prism.languages.django.style.inside.string.inside = _django_template;
+}
+
+// Add an Jinja2 alias
+Prism.languages.jinja2 = Prism.languages.django;
diff --git a/components/prism-django.min.js b/components/prism-django.min.js
new file mode 100644
index 0000000..162ecce
--- /dev/null
+++ b/components/prism-django.min.js
@@ -0,0 +1 @@
+var _django_template={property:{pattern:/(?:{{|{%)[\w\W]*?(?:%}|}})/g,greedy:!0,inside:{string:{pattern:/("|')(?:\\\\|\\?[^\\\r\n])*?\1/,greedy:!0},keyword:/\b(?:\||load|verbatim|widthratio|ssi|firstof|for|url|ifchanged|csrf_token|lorem|ifnotequal|autoescape|now|templatetag|debug|cycle|ifequal|regroup|comment|filter|endfilter|if|spaceless|with|extends|block|include|else|empty|endif|endfor|as|endblock|endautoescape|endverbatim|trans|endtrans|[Tt]rue|[Ff]alse|[Nn]one|in|is|static|macro|endmacro|call|endcall|set|endset|raw|endraw)\b/,operator:/[-+=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,"function":/\b(?:_|abs|add|addslashes|attr|batch|callable|capfirst|capitalize|center|count|cut|d|date|default|default_if_none|defined|dictsort|dictsortreversed|divisibleby|e|equalto|escape|escaped|escapejs|even|filesizeformat|first|float|floatformat|force_escape|forceescape|format|get_digit|groupby|indent|int|iriencode|iterable|join|last|length|length_is|linebreaks|linebreaksbr|linenumbers|list|ljust|lower|make_list|map|mapping|number|odd|phone2numeric|pluralize|pprint|random|reject|rejectattr|removetags|replace|reverse|rjust|round|safe|safeseq|sameas|select|selectattr|sequence|slice|slugify|sort|string|stringformat|striptags|sum|time|timesince|timeuntil|title|trim|truncate|truncatechars|truncatechars_html|truncatewords|truncatewords_html|undefined|unordered_list|upper|urlencode|urlize|urlizetrunc|wordcount|wordwrap|xmlattr|yesno)\b/,important:/\b-?\d+(?:\.\d+)?\b/,variable:/\b\w+?\b/,punctuation:/[[\];(),.:]/}}};Prism.languages.django=Prism.languages.extend("markup",{comment:/(?:<!--|{#)[\w\W]*?(?:#}|-->)/}),Prism.languages.django.tag.pattern=/<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^>=]+))?)*\s*\/?>/i,Prism.languages.insertBefore("django","entity",_django_template),Prism.languages.insertBefore("inside","tag",_django_template,Prism.languages.django.tag),Prism.languages.javascript&&(Prism.languages.insertBefore("inside","string",_django_template,Prism.languages.django.script),Prism.languages.django.script.inside.string.inside=_django_template),Prism.languages.css&&(Prism.languages.insertBefore("inside","atrule",{tag:_django_template.property},Prism.languages.django.style),Prism.languages.django.style.inside.string.inside=_django_template),Prism.languages.jinja2=Prism.languages.django;
\ No newline at end of file
diff --git a/examples/prism-django.html b/examples/prism-django.html
new file mode 100644
index 0000000..2244e1a
--- /dev/null
+++ b/examples/prism-django.html
@@ -0,0 +1,34 @@
+<h1>Django/Jinja2</h1>
+<p>To use this language, add the class "language-django" or "language-jinja2".</p>
+
+<h2>Comment</h2>
+<pre><code>{# This is a comment #}</code></pre>
+
+<h2>Variable</h2>
+<pre><code>{{ some_variable }}</code></pre>
+
+<h2>Template Tag</h2>
+<pre><code>{% if some_condition %}
+Conditional block
+{% endif %}
+</code></pre>
+
+<h2>Full Example</h2>
+<pre><code>{# This a Django template example #}
+{% extends "base_generic.html" %}
+
+{% block title %}{{ section.title }}{% endblock %}
+
+{% block content %}
+&lt;h1&gt;{{ section.title }}&lt;/h1&gt;
+
+{% for story in story_list %}
+&lt;h2&gt;
+  &lt;a href="{{ story.get_absolute_url }}"&gt;
+    {{ story.headline|upper }}
+  &lt;/a&gt;
+&lt;/h2&gt;
+&lt;p&gt;{{ story.tease|truncatewords:"100" }}&lt;/p&gt;
+{% endfor %}
+{% endblock %}
+</code></pre>