From 8030db914a1e7331d245db0b9b787b4364994440 Mon Sep 17 00:00:00 2001 From: Golmote Date: Thu, 25 Jun 2015 08:00:14 +0200 Subject: [PATCH] File Highlight: allow to specify the language (takes precedence over extension guess) + Set language on parent even if unknown. Fix #607 --- components/prism-core.js | 8 +++--- components/prism-core.min.js | 2 +- plugins/file-highlight/index.html | 4 +-- .../file-highlight/prism-file-highlight.js | 17 +++++++++++-- .../prism-file-highlight.min.js | 2 +- prism.js | 25 ++++++++++++++----- 6 files changed, 42 insertions(+), 16 deletions(-) diff --git a/components/prism-core.js b/components/prism-core.js index 750ebb19f0..b9a0ac61a8 100644 --- a/components/prism-core.js +++ b/components/prism-core.js @@ -161,10 +161,6 @@ var _ = self.Prism = { grammar = _.languages[language]; } - if (!grammar) { - return; - } - // Set language on the element, if not present element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; @@ -175,6 +171,10 @@ var _ = self.Prism = { parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; } + if (!grammar) { + return; + } + var code = element.textContent; if(!code) { diff --git a/components/prism-core.min.js b/components/prism-core.min.js index 703d1430ef..df4ccd4c43 100644 --- a/components/prism-core.min.js +++ b/components/prism-core.min.js @@ -1 +1 @@ -self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(d instanceof a)){u.lastIndex=0;var m=u.exec(d);if(m){c&&(f=m[1].length);var y=m.index-1+f,m=m[0].slice(f),v=m.length,k=y+v,b=d.slice(0,y+1),w=d.slice(k+1),N=[p,1];b&&N.push(b);var O=new a(l,g?t.tokenize(m,g):m,h);N.push(O),w&&N.push(w),Array.prototype.splice.apply(r,N)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("Array"===t.util.type(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var i={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}t.hooks.run("wrap",i);var s="";for(var o in i.attributes)s+=o+'="'+(i.attributes[o]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+s+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(r,t.languages[a])))),self.close()},!1),self.Prism):self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism); \ No newline at end of file +self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(d instanceof a)){u.lastIndex=0;var m=u.exec(d);if(m){c&&(f=m[1].length);var y=m.index-1+f,m=m[0].slice(f),v=m.length,k=y+v,b=d.slice(0,y+1),w=d.slice(k+1),N=[p,1];b&&N.push(b);var O=new a(l,g?t.tokenize(m,g):m,h);N.push(O),w&&N.push(w),Array.prototype.splice.apply(r,N)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("Array"===t.util.type(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var i={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}t.hooks.run("wrap",i);var s="";for(var o in i.attributes)s+=o+'="'+(i.attributes[o]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+s+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(r,t.languages[a])))),self.close()},!1),self.Prism):self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism); \ No newline at end of file diff --git a/plugins/file-highlight/index.html b/plugins/file-highlight/index.html index 0a3cb58be7..686a7f796d 100644 --- a/plugins/file-highlight/index.html +++ b/plugins/file-highlight/index.html @@ -37,7 +37,7 @@

How to use

Examples

- +

The plugin’s JS code:


 	
@@ -53,7 +53,7 @@ 

Examples

- + diff --git a/plugins/file-highlight/prism-file-highlight.js b/plugins/file-highlight/prism-file-highlight.js index c81dd01af1..5fea85abf0 100644 --- a/plugins/file-highlight/prism-file-highlight.js +++ b/plugins/file-highlight/prism-file-highlight.js @@ -18,8 +18,21 @@ Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function(pre) { var src = pre.getAttribute('data-src'); - var extension = (src.match(/\.(\w+)$/) || [,''])[1]; - var language = Extensions[extension] || extension; + + var language, parent = pre; + var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i; + while (parent && !lang.test(parent.className)) { + parent = parent.parentNode; + } + + if (parent) { + language = (pre.className.match(lang) || [,''])[1]; + } + + if (!language) { + var extension = (src.match(/\.(\w+)$/) || [, ''])[1]; + language = Extensions[extension] || extension; + } var code = document.createElement('code'); code.className = 'language-' + language; diff --git a/plugins/file-highlight/prism-file-highlight.min.js b/plugins/file-highlight/prism-file-highlight.min.js index a14cc1369e..42889f90b6 100644 --- a/plugins/file-highlight/prism-file-highlight.min.js +++ b/plugins/file-highlight/prism-file-highlight.min.js @@ -1 +1 @@ -!function(){self.Prism&&self.document&&document.querySelector&&(self.Prism.fileHighlight=function(){var e={js:"javascript",html:"markup",svg:"markup",xml:"markup",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell"};Array.prototype.slice.call(document.querySelectorAll("pre[data-src]")).forEach(function(t){var r=t.getAttribute("data-src"),s=(r.match(/\.(\w+)$/)||[,""])[1],n=e[s]||s,a=document.createElement("code");a.className="language-"+n,t.textContent="",a.textContent="Loading…",t.appendChild(a);var l=new XMLHttpRequest;l.open("GET",r,!0),l.onreadystatechange=function(){4==l.readyState&&(l.status<400&&l.responseText?(a.textContent=l.responseText,Prism.highlightElement(a)):a.textContent=l.status>=400?"✖ Error "+l.status+" while fetching file: "+l.statusText:"✖ Error: File does not exist or is empty")},l.send(null)})},self.Prism.fileHighlight())}(); \ No newline at end of file +!function(){self.Prism&&self.document&&document.querySelector&&(self.Prism.fileHighlight=function(){var e={js:"javascript",html:"markup",svg:"markup",xml:"markup",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell"};Array.prototype.slice.call(document.querySelectorAll("pre[data-src]")).forEach(function(t){for(var r,s=t.getAttribute("data-src"),a=t,n=/\blang(?:uage)?-(?!\*)(\w+)\b/i;a&&!n.test(a.className);)a=a.parentNode;if(a&&(r=(t.className.match(n)||[,""])[1]),!r){var l=(s.match(/\.(\w+)$/)||[,""])[1];r=e[l]||l}var o=document.createElement("code");o.className="language-"+r,t.textContent="",o.textContent="Loading…",t.appendChild(o);var i=new XMLHttpRequest;i.open("GET",s,!0),i.onreadystatechange=function(){4==i.readyState&&(i.status<400&&i.responseText?(o.textContent=i.responseText,Prism.highlightElement(o)):o.textContent=i.status>=400?"✖ Error "+i.status+" while fetching file: "+i.statusText:"✖ Error: File does not exist or is empty")},i.send(null)})},self.Prism.fileHighlight())}(); \ No newline at end of file diff --git a/prism.js b/prism.js index 7ef3b77011..fb0aeca690 100644 --- a/prism.js +++ b/prism.js @@ -166,10 +166,6 @@ var _ = self.Prism = { grammar = _.languages[language]; } - if (!grammar) { - return; - } - // Set language on the element, if not present element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; @@ -180,6 +176,10 @@ var _ = self.Prism = { parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; } + if (!grammar) { + return; + } + var code = element.textContent; if(!code) { @@ -648,8 +648,21 @@ if (Prism.languages.markup) { Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function(pre) { var src = pre.getAttribute('data-src'); - var extension = (src.match(/\.(\w+)$/) || [,''])[1]; - var language = Extensions[extension] || extension; + + var language, parent = pre; + var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i; + while (parent && !lang.test(parent.className)) { + parent = parent.parentNode; + } + + if (parent) { + language = (pre.className.match(lang) || [,''])[1]; + } + + if (!language) { + var extension = (src.match(/\.(\w+)$/) || [, ''])[1]; + language = Extensions[extension] || extension; + } var code = document.createElement('code'); code.className = 'language-' + language;