Add mathjax
This commit is contained in:
parent
4d9ef5917e
commit
085bd46440
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -0,0 +1,136 @@
|
|||
package parsing
|
||||
|
||||
import (
|
||||
gohtml "html"
|
||||
"strings"
|
||||
|
||||
"github.com/yuin/goldmark"
|
||||
"github.com/yuin/goldmark/ast"
|
||||
gast "github.com/yuin/goldmark/ast"
|
||||
"github.com/yuin/goldmark/parser"
|
||||
"github.com/yuin/goldmark/renderer"
|
||||
"github.com/yuin/goldmark/renderer/html"
|
||||
"github.com/yuin/goldmark/text"
|
||||
"github.com/yuin/goldmark/util"
|
||||
)
|
||||
|
||||
// ----------------------
|
||||
// Parser and delimiters
|
||||
// ----------------------
|
||||
|
||||
type mathjaxParser struct{}
|
||||
|
||||
var _ parser.BlockParser = mathjaxParser{}
|
||||
|
||||
func (s mathjaxParser) Trigger() []byte {
|
||||
return []byte{'$'}
|
||||
}
|
||||
|
||||
func (s mathjaxParser) Open(parent ast.Node, reader text.Reader, pc parser.Context) (ast.Node, parser.State) {
|
||||
line, _ := reader.PeekLine()
|
||||
lineStr := strings.TrimSpace(string(line))
|
||||
|
||||
if lineStr == "$$" {
|
||||
return NewMathjax(), parser.NoChildren
|
||||
} else {
|
||||
return nil, parser.NoChildren
|
||||
}
|
||||
}
|
||||
|
||||
func (s mathjaxParser) Continue(node ast.Node, reader text.Reader, pc parser.Context) parser.State {
|
||||
line, _ := reader.PeekLine()
|
||||
lineStr := strings.TrimSpace(string(line))
|
||||
|
||||
if lineStr == "$$" {
|
||||
reader.Advance(len(line))
|
||||
return parser.Close
|
||||
}
|
||||
|
||||
node.(*MathjaxNode).Source += string(line)
|
||||
return parser.Continue | parser.NoChildren
|
||||
}
|
||||
|
||||
func (s mathjaxParser) Close(node ast.Node, reader text.Reader, pc parser.Context) {}
|
||||
|
||||
func (s mathjaxParser) CanInterruptParagraph() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (s mathjaxParser) CanAcceptIndentedLine() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ----------------------
|
||||
// AST node
|
||||
// ----------------------
|
||||
|
||||
type MathjaxNode struct {
|
||||
gast.BaseBlock
|
||||
Source string
|
||||
}
|
||||
|
||||
var _ gast.Node = &MathjaxNode{}
|
||||
|
||||
func (n *MathjaxNode) Dump(source []byte, level int) {
|
||||
gast.DumpHelper(n, source, level, nil, nil)
|
||||
}
|
||||
|
||||
var KindMathjax = gast.NewNodeKind("Mathjax")
|
||||
|
||||
func (n *MathjaxNode) Kind() gast.NodeKind {
|
||||
return KindMathjax
|
||||
}
|
||||
|
||||
func NewMathjax() *MathjaxNode {
|
||||
return &MathjaxNode{}
|
||||
}
|
||||
|
||||
// ----------------------
|
||||
// Renderer
|
||||
// ----------------------
|
||||
|
||||
type MathjaxHTMLRenderer struct {
|
||||
html.Config
|
||||
}
|
||||
|
||||
func NewMathjaxHTMLRenderer(opts ...html.Option) renderer.NodeRenderer {
|
||||
r := &MathjaxHTMLRenderer{
|
||||
Config: html.NewConfig(),
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt.SetHTMLOption(&r.Config)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *MathjaxHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
|
||||
reg.Register(KindMathjax, r.renderMathjax)
|
||||
}
|
||||
|
||||
func (r *MathjaxHTMLRenderer) renderMathjax(w util.BufWriter, source []byte, n gast.Node, entering bool) (gast.WalkStatus, error) {
|
||||
if entering {
|
||||
w.WriteString("<div>\n")
|
||||
w.WriteString("$$\n")
|
||||
w.WriteString(gohtml.EscapeString(n.(*MathjaxNode).Source))
|
||||
w.WriteString("$$\n")
|
||||
w.WriteString("</div>\n")
|
||||
}
|
||||
return gast.WalkSkipChildren, nil
|
||||
}
|
||||
|
||||
// ----------------------
|
||||
// Extension
|
||||
// ----------------------
|
||||
|
||||
type MathjaxExtension struct {
|
||||
Preview bool
|
||||
}
|
||||
|
||||
func (e MathjaxExtension) Extend(m goldmark.Markdown) {
|
||||
m.Parser().AddOptions(parser.WithBlockParsers(
|
||||
util.Prioritized(mathjaxParser{}, 500),
|
||||
))
|
||||
m.Renderer().AddOptions(renderer.WithNodeRenderers(
|
||||
util.Prioritized(NewMathjaxHTMLRenderer(), 500),
|
||||
))
|
||||
}
|
|
@ -97,6 +97,7 @@ var previewMarkdown = goldmark.New(
|
|||
EmbedExtension{
|
||||
Preview: true,
|
||||
},
|
||||
MathjaxExtension{},
|
||||
bTag{},
|
||||
),
|
||||
)
|
||||
|
@ -105,6 +106,7 @@ var realMarkdown = goldmark.New(
|
|||
extension.GFM,
|
||||
SpoilerExtension{},
|
||||
EmbedExtension{},
|
||||
MathjaxExtension{},
|
||||
bTag{},
|
||||
),
|
||||
)
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
<input type="submit" class="button ml2" name="preview" value="{{ .PreviewLabel }}" />
|
||||
</div>
|
||||
|
||||
<div class="post post-preview mv3">
|
||||
<div class="post post-preview mv3 mathjax">
|
||||
<div id="preview" class="body contents"></div>
|
||||
</div>
|
||||
|
||||
|
@ -111,6 +111,7 @@
|
|||
function updatePreview() {
|
||||
const previewHtml = parseMarkdown(tf.value);
|
||||
preview.innerHTML = previewHtml;
|
||||
MathJax.typeset();
|
||||
}
|
||||
|
||||
tf.addEventListener('input', () => {
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
{{ end }}
|
||||
}
|
||||
</style>
|
||||
{{ block "extrahead" . }}{{ end }}
|
||||
|
||||
<link rel="stylesheet" href="{{ statictheme .Theme "theme.css" }}" />
|
||||
<link rel="stylesheet" href="{{ .ProjectCSSUrl }}" />
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="{{ static "apple-icon-57x57.png" }}">
|
||||
|
@ -58,6 +58,23 @@
|
|||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="msapplication-TileImage" content="{{ static "ms-icon-144x144.png" }}">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
{{ if .MathjaxEnabled }}
|
||||
<script>
|
||||
MathJax = {
|
||||
tex: {
|
||||
inlineMath: [['$', '$']],
|
||||
displayMath: [['$$', '$$']],
|
||||
},
|
||||
svg: {
|
||||
fontCache: 'global',
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script async src="{{ static "mathjax.js" }}"></script>
|
||||
{{ end }}
|
||||
|
||||
{{ block "extrahead" . }}{{ end }}
|
||||
</head>
|
||||
|
||||
<body class="{{ join " " .BodyClasses }}">
|
||||
|
|
|
@ -22,9 +22,10 @@ type BaseData struct {
|
|||
User *User
|
||||
Session *Session
|
||||
|
||||
IsProjectPage bool
|
||||
Header Header
|
||||
Footer Footer
|
||||
IsProjectPage bool
|
||||
Header Header
|
||||
Footer Footer
|
||||
MathjaxEnabled bool
|
||||
}
|
||||
|
||||
type Header struct {
|
||||
|
|
|
@ -531,6 +531,7 @@ func ForumNewThread(c *RequestContext) ResponseData {
|
|||
|
||||
baseData := getBaseData(c)
|
||||
baseData.Title = "Create New Thread"
|
||||
baseData.MathjaxEnabled = true
|
||||
// TODO(ben): Set breadcrumbs
|
||||
|
||||
var res ResponseData
|
||||
|
|
Loading…
Reference in New Issue