diff options
Diffstat (limited to 'webapp/utils')
-rw-r--r-- | webapp/utils/markdown.jsx | 49 | ||||
-rw-r--r-- | webapp/utils/syntax_hightlighting.jsx | 83 |
2 files changed, 65 insertions, 67 deletions
diff --git a/webapp/utils/markdown.jsx b/webapp/utils/markdown.jsx index 7fd165134..6691b57b2 100644 --- a/webapp/utils/markdown.jsx +++ b/webapp/utils/markdown.jsx @@ -2,7 +2,7 @@ // See License.txt for license information. import * as TextFormatting from './text_formatting.jsx'; -import * as syntaxHightlighting from './syntax_hightlighting.jsx'; +import * as SyntaxHighlighting from './syntax_hightlighting.jsx'; import marked from 'marked'; import katex from 'katex'; @@ -43,7 +43,52 @@ class MattermostMarkdownRenderer extends marked.Renderer { usedLanguage = 'xml'; } - return syntaxHightlighting.formatCode(usedLanguage, code, null, this.formattingOptions.searchTerm); + let className = 'post-code'; + if (!usedLanguage) { + className += ' post-code--wrap'; + } + + let header = ''; + if (SyntaxHighlighting.canHighlight(usedLanguage)) { + header = ( + '<span class="post-code__language">' + + SyntaxHighlighting.getLanguageName(language) + + '</span>' + ); + } + + // if we have to apply syntax highlighting AND highlighting of search terms, create two copies + // of the code block, one with syntax highlighting applied and another with invisible text, but + // search term highlighting and overlap them + const content = SyntaxHighlighting.highlight(usedLanguage, code); + let searchedContent = ''; + + if (this.formattingOptions.searchTerm) { + const tokens = new Map(); + + let searched = TextFormatting.sanitizeHtml(code); + searched = TextFormatting.highlightSearchTerms(searched, tokens, this.formattingOptions.searchTerm); + + if (tokens.size > 0) { + searched = TextFormatting.replaceTokens(searched, tokens); + + searchedContent = ( + '<div class="post-code__search-highlighting">' + + searched + + '</div>' + ); + } + } + + return ( + '<div class="' + className + '">' + + header + + '<code class="hljs">' + + searchedContent + + content + + '</code>' + + '</div>' + ); } codespan(text) { diff --git a/webapp/utils/syntax_hightlighting.jsx b/webapp/utils/syntax_hightlighting.jsx index 33b3e2d3d..ce904c41f 100644 --- a/webapp/utils/syntax_hightlighting.jsx +++ b/webapp/utils/syntax_hightlighting.jsx @@ -123,80 +123,21 @@ hlJS.registerLanguage('yaml', hljsYaml); const HighlightedLanguages = Constants.HighlightedLanguages; -export function formatCode(lang, data, filename, searchTerm) { - const language = lang.toLowerCase() || ''; - - let contents; - let header = ''; - let className = 'post-code'; +export function highlight(lang, code) { + const language = lang.toLowerCase(); if (HighlightedLanguages[language]) { - let name = HighlightedLanguages[language].name; - - if (filename) { - const fname = decodeURIComponent(Utils.getFileName(filename)); - name = fname + ' - ' + name; - } - - header = '<span class="post-code__language">' + name + '</span>'; - try { - contents = hlJS.highlight(language, data).value; + return hlJS.highlight(language, code).value; } catch (e) { - contents = TextFormatting.sanitizeHtml(data); + // fall through if highlighting fails and handle below } - } else { - contents = TextFormatting.sanitizeHtml(data); } - if (!language) { - // wrap when no language is specified - className += ' post-code--wrap'; - - const tokens = new Map(); - contents = TextFormatting.highlightSearchTerms(contents, tokens, searchTerm); - contents = TextFormatting.replaceTokens(contents, tokens); - } - - if (filename) { - // add line numbers when viewing a code file preview - const lines = data.match(/\r\n|\r|\n|$/g).length; - let strlines = ''; - for (let i = 1; i <= lines; i++) { - if (strlines) { - strlines += '\n' + i; - } else { - strlines += i; - } - } - - contents = ( - '<table>' + - '<tbody>' + - '<tr>' + - '<td class="post-code__lineno">' + strlines + '</td>' + - '<td>' + - contents + - '</td>' + - '</tr>' + - '</tbody>' + - '</table>' - ); - } - - return ( - '<div class="' + className + '">' + - header + - '<pre>' + - '<code class="hljs">' + - contents + - '</code>' + - '</pre>' + - '</div>' - ); + return TextFormatting.sanitizeHtml(code); } -export function getLang(filename) { +export function getLanguageFromFilename(filename) { const fileInfo = Utils.splitFileLocation(filename); var ext = fileInfo.ext; if (!ext) { @@ -211,3 +152,15 @@ export function getLang(filename) { } return null; } + +export function canHighlight(language) { + return !!HighlightedLanguages[language.toLowerCase()]; +} + +export function getLanguageName(language) { + if (canHighlight(language)) { + return HighlightedLanguages[language.toLowerCase()].name; + } + + return ''; +}
\ No newline at end of file |