Browse Source

syntax highlighting for code spans

pull/101/head
adam j hartz 6 days ago
parent
commit
9673414612
4 changed files with 159 additions and 10 deletions
  1. +2
    -0
      CHANGELOG.md
  2. +3
    -0
      catsoop/__STATIC__/templates/main.template
  3. +6
    -0
      catsoop/__STATIC__/themes/base.css
  4. +148
    -10
      catsoop/markdown.py

+ 2
- 0
CHANGELOG.md View File

@@ -27,6 +27,8 @@ _Work toward next release. Currently under development._
["admonitions"](https://casual-effects.com/markdeep/features.md.html#basicformatting/admonitions)
(#90)

* Added support for syntax highlighting of inline code elements (#93 and #101)

**CHANGED:**

* Auto-generated `csq_name` fields increment for every question, even those


+ 3
- 0
catsoop/__STATIC__/templates/main.template View File

@@ -75,6 +75,9 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3
hljs.initHighlightingOnLoad();
window.addEventListener('DOMContentLoaded', function(){{
document.querySelectorAll('.hl code').forEach((block) => {{
hljs.highlightBlock(block);
}});
document.querySelectorAll('code.highlight-lines').forEach(function(b){{
hljs.lineNumbersBlock(b);
if ((b.innerHTML.trim().match(/\r\n|\r|\n/g) || []).length > 0){{


+ 6
- 0
catsoop/__STATIC__/themes/base.css View File

@@ -552,6 +552,12 @@ a.btn:visited {
/* highlight.js styles */
/* Based on default colors in Python's IDLE */

span.hl code {
display: inline !important;
overflow-x: auto;
padding: 2px;
}

.hljs {
display: block;
overflow-x: auto;


+ 148
- 10
catsoop/markdown.py View File

@@ -16,12 +16,138 @@
"""CAT-SOOP Extensions for Mistletoe"""

import re
import html

from mistletoe import Document
from mistletoe.span_token import SpanToken, tokenize_inner
from mistletoe.block_token import BlockToken, tokenize
from mistletoe.html_renderer import HTMLRenderer

# Syntax Highlighting for Code Spans

# auto-generated list of languages for syntax highlighting, from highlight.js
LANGS = [
"apache",
"apacheconf",
"bash",
"sh",
"zsh",
"c",
"c",
"h",
"coffeescript",
"coffee",
"cson",
"iced",
"cpp",
"cc",
"c\\+\\+",
"h\\+\\+",
"hpp",
"hh",
"hxx",
"cxx",
"csharp",
"cs",
"c#",
"css",
"diff",
"patch",
"go",
"golang",
"http",
"https",
"ini",
"toml",
"java",
"jsp",
"javascript",
"js",
"jsx",
"mjs",
"cjs",
"json",
"kotlin",
"kt",
"less",
"lua",
"makefile",
"mk",
"mak",
"xml",
"html",
"xhtml",
"rss",
"atom",
"xjb",
"xsd",
"xsl",
"plist",
"wsf",
"svg",
"markdown",
"md",
"mkdown",
"mkd",
"nginx",
"nginxconf",
"objectivec",
"mm",
"objc",
"obj-c",
"perl",
"pl",
"pm",
"php",
"php",
"php3",
"php4",
"php5",
"php6",
"php7",
"php-template",
"plaintext",
"text",
"txt",
"properties",
"python",
"py",
"gyp",
"ipython",
"python-repl",
"pycon",
"ruby",
"rb",
"gemspec",
"podspec",
"thor",
"irb",
"rust",
"rs",
"scss",
"shell",
"console",
"sql",
"swift",
"typescript",
"ts",
"yaml",
"yml",
"YAML",
]


class SyntaxHighlightedCodeSpan(SpanToken):
pattern = re.compile(
r"(?P<lang>%s)(?P<open>`+)(?P<body>.*?)(?P=open)" % "|".join(LANGS)
)
parse_inner = False
precedence = SpanToken.precedence + 2

def __init__(self, match):
self.language = match.group("lang")
self.body = match.group("body")


# Math

@@ -133,18 +259,20 @@ class Callout(BlockToken):
class CatsoopRenderer(HTMLRenderer):
def __init__(self):
HTMLRenderer.__init__(
self, Callout, DisplayMathEnv, DisplayMath, Math, EscapedDollar
self,
Callout,
DisplayMathEnv,
DisplayMath,
Math,
EscapedDollar,
SyntaxHighlightedCodeSpan,
)

def render_callout(self, token):
if token.title:
rendered_title = '<div class="callout-title">%s</div>' % "".join(
self.render_inner(i) for i in token.title
)
else:
rendered_title = ""
rendered_body = "".join(self.render(i) for i in token.children)
return f'<div class="callout callout-{token.type}">{rendered_title}\n\n{rendered_body}\n</div>'
def render_syntax_highlighted_code_span(self, token):
return '<span class="hl"><code class="lang-%s">%s</code></span>' % (
token.language,
html.escape(token.body),
)

def render_math(self, token):
return f"<math>{token.body}</math>"
@@ -155,6 +283,16 @@ class CatsoopRenderer(HTMLRenderer):
def render_display_math_env(self, token):
return f'<displaymath env="{token.env}">{token.body}</displaymath>'

def render_callout(self, token):
if token.title:
rendered_title = '<div class="callout-title">%s</div>' % "".join(
self.render_inner(i) for i in token.title
)
else:
rendered_title = ""
rendered_body = "".join(self.render(i) for i in token.children)
return f'<div class="callout callout-{token.type}">{rendered_title}\n\n{rendered_body}\n</div>'


def markdown(x):
with CatsoopRenderer() as renderer:


Loading…
Cancel
Save