Add asciimath processing (#10)
This version sets the new asciimath parsing to be an option. It also deals with the old zoom_on_hover and enable_accessibility options a bit better.
This commit is contained in:
parent
5588d2ba65
commit
05d52f593f
|
@ -2,14 +2,13 @@ import { withPluginApi } from 'discourse/lib/plugin-api';
|
|||
import loadScript from 'discourse/lib/load-script';
|
||||
|
||||
let initializedMathJax = false;
|
||||
let zoom_on_hover, enable_accessibility;
|
||||
|
||||
function initMathJax() {
|
||||
function initMathJax(opts) {
|
||||
if (initializedMathJax) { return; }
|
||||
|
||||
var extensions = ["toMathML.js", "Safe.js"];
|
||||
|
||||
if (enable_accessibility) {
|
||||
if (opts.enable_accessibility) {
|
||||
extensions.push("[a11y]/accessibility-menu.js");
|
||||
}
|
||||
|
||||
|
@ -21,7 +20,7 @@ function initMathJax() {
|
|||
root: '/plugins/discourse-math/mathjax'
|
||||
};
|
||||
|
||||
if(zoom_on_hover) {
|
||||
if(opts.zoom_on_hover) {
|
||||
settings.menuSettings = {zoom: "Hover"};
|
||||
settings.MathEvents = {hover: 750};
|
||||
}
|
||||
|
@ -29,12 +28,13 @@ function initMathJax() {
|
|||
initializedMathJax = true;
|
||||
}
|
||||
|
||||
function ensureMathJax(){
|
||||
initMathJax();
|
||||
function ensureMathJax(opts){
|
||||
initMathJax(opts);
|
||||
return loadScript('/plugins/discourse-math/mathjax/MathJax.1.7.1.js');
|
||||
}
|
||||
|
||||
function decorate(elem, isPreview){
|
||||
|
||||
const $elem= $(elem);
|
||||
|
||||
if ($elem.data('applied-mathjax')){
|
||||
|
@ -42,14 +42,20 @@ function decorate(elem, isPreview){
|
|||
}
|
||||
$elem.data('applied-mathjax', true);
|
||||
|
||||
const tag = elem.tagName === "DIV" ? "div" : "span";
|
||||
const display = tag === "div" ? "; mode=display" : "";
|
||||
|
||||
const $mathWrapper = $(`<${tag} style="display: none;"><script type="math/tex${display}"></script></${tag}>`);
|
||||
const $math = $mathWrapper.children();
|
||||
|
||||
$math.html($elem.text());
|
||||
$elem.after($mathWrapper);
|
||||
if($elem.hasClass('math')) {
|
||||
const tag = elem.tagName === "DIV" ? "div" : "span";
|
||||
const display = tag === "div" ? "; mode=display" : "";
|
||||
var $mathWrapper = $(`<${tag} style="display: none;"><script type="math/tex${display}"></script></${tag}>`);
|
||||
var $math = $mathWrapper.children();
|
||||
$math.html($elem.text());
|
||||
$elem.after($mathWrapper);
|
||||
}
|
||||
else if($elem.hasClass('asciimath')) {
|
||||
var $mathWrapper = $(`<span style="display: none;"><script type="math/asciimath"></script></span>`);
|
||||
var $math = $mathWrapper.children();
|
||||
$math.html($elem.text());
|
||||
$elem.after($mathWrapper);
|
||||
}
|
||||
|
||||
Em.run.later(this, ()=> {
|
||||
window.MathJax.Hub.Queue(() => {
|
||||
|
@ -64,35 +70,43 @@ function decorate(elem, isPreview){
|
|||
}, isPreview ? 200 : 0);
|
||||
}
|
||||
|
||||
function mathjax($elem) {
|
||||
|
||||
function mathjax($elem, opts) {
|
||||
if (!$elem || !$elem.find) {
|
||||
return;
|
||||
}
|
||||
|
||||
const mathElems = $elem.find('.math');
|
||||
let mathElems;
|
||||
if(opts.enable_asciimath) {
|
||||
mathElems = $elem.find('.math, .asciimath');
|
||||
}
|
||||
else {
|
||||
mathElems = $elem.find('.math');
|
||||
}
|
||||
|
||||
if (mathElems.length > 0) {
|
||||
const isPreview = $elem.hasClass('d-editor-preview');
|
||||
|
||||
ensureMathJax().then(()=>{
|
||||
ensureMathJax(opts).then(()=>{
|
||||
mathElems.each((idx,elem) => decorate(elem, isPreview));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function initializeMath(api) {
|
||||
api.decorateCooked(mathjax);
|
||||
function initializeMath(api, discourse_math_opts) {
|
||||
api.decorateCooked(function(elem) {mathjax(elem,discourse_math_opts)});
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "apply-math",
|
||||
initialize(container) {
|
||||
const siteSettings = container.lookup('site-settings:main');
|
||||
zoom_on_hover = siteSettings.discourse_math_zoom_on_hover;
|
||||
enable_accessibility = siteSettings.discourse_math_enable_accessibility;
|
||||
let discourse_math_opts = {
|
||||
zoom_on_hover: siteSettings.discourse_math_zoom_on_hover,
|
||||
enable_accessibility: siteSettings.discourse_math_enable_accessibility,
|
||||
enable_asciimath: siteSettings.discourse_math_enable_asciimath
|
||||
};
|
||||
if (siteSettings.discourse_math_enabled) {
|
||||
withPluginApi('0.5', initializeMath);
|
||||
withPluginApi('0.5', function(api) {initializeMath(api,discourse_math_opts)});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,43 +2,44 @@
|
|||
//
|
||||
//
|
||||
//
|
||||
function isSafeBoundary(code, md) {
|
||||
if (code === 36) {
|
||||
|
||||
function isSafeBoundary(character_code, delimiter_code, md) {
|
||||
if (character_code === delimiter_code) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (md.utils.isWhiteSpace(code)) {
|
||||
if (md.utils.isWhiteSpace(character_code)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (md.utils.isMdAsciiPunct(code)) {
|
||||
if (md.utils.isMdAsciiPunct(character_code)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (md.utils.isPunctChar(code)) {
|
||||
if (md.utils.isPunctChar(character_code)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function inlineMath(state, silent) {
|
||||
function math_input(state, silent, delimiter_code) {
|
||||
|
||||
let pos = state.pos,
|
||||
posMax = state.posMax;
|
||||
|
||||
if (silent || state.src.charCodeAt(pos) !== 36 /* $ */ || posMax < pos+2) {
|
||||
if (silent || state.src.charCodeAt(pos) !== delimiter_code || posMax < pos+2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// too short
|
||||
if (state.src.charCodeAt(pos+1) === 36 /* $ */) {
|
||||
if (state.src.charCodeAt(pos+1) === delimiter_code) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pos > 0) {
|
||||
let prev = state.src.charCodeAt(pos-1);
|
||||
if (!isSafeBoundary(prev, state.md)) {
|
||||
if (!isSafeBoundary(prev, delimiter_code, state.md)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +48,7 @@ function inlineMath(state, silent) {
|
|||
let found;
|
||||
for(let i=pos+1; i<posMax; i++) {
|
||||
let code = state.src.charCodeAt(i);
|
||||
if (code === 36 /* $ */ && state.src.charCodeAt(i-1) !== 92 /* \ */) {
|
||||
if (code === delimiter_code && state.src.charCodeAt(i-1) !== 92 /* \ */) {
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
|
@ -59,7 +60,7 @@ function inlineMath(state, silent) {
|
|||
|
||||
if (found+1 <= posMax) {
|
||||
let next = state.src.charCodeAt(found+1);
|
||||
if (next && !isSafeBoundary(next, state.md)) {
|
||||
if (next && !isSafeBoundary(next, delimiter_code, state.md)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -68,11 +69,20 @@ function inlineMath(state, silent) {
|
|||
let token = state.push('html_raw', '', 0);
|
||||
|
||||
const escaped = state.md.utils.escapeHtml(data);
|
||||
token.content = `<span class='math'>${escaped}</span>`;
|
||||
let math_class = delimiter_code === 36 ? "'math'" : "'asciimath'";
|
||||
token.content = `<span class=${math_class}>${escaped}</span>`;
|
||||
state.pos = found+1;
|
||||
return true;
|
||||
}
|
||||
|
||||
function inlineMath(state, silent) {
|
||||
return math_input(state, silent, 36 /* $ */)
|
||||
}
|
||||
|
||||
function asciiMath(state, silent) {
|
||||
return math_input(state, silent, 37 /* % */)
|
||||
}
|
||||
|
||||
function isBlockMarker(state, start, max, md) {
|
||||
|
||||
if (state.src.charCodeAt(start) !== 36 /* $ */) {
|
||||
|
@ -144,11 +154,16 @@ export function setup(helper) {
|
|||
return;
|
||||
}
|
||||
|
||||
let enable_asciimath;
|
||||
helper.registerOptions((opts, siteSettings) => {
|
||||
opts.features.math = siteSettings.discourse_math_enabled;
|
||||
enable_asciimath = siteSettings.discourse_math_enable_asciimath;
|
||||
});
|
||||
|
||||
helper.registerPlugin(md => {
|
||||
if(enable_asciimath) {
|
||||
md.inline.ruler.after('escape', 'asciimath', asciiMath);
|
||||
}
|
||||
md.inline.ruler.after('escape', 'math', inlineMath);
|
||||
md.block.ruler.after('code', 'math', blockMath, {
|
||||
alt: ['paragraph', 'reference', 'blockquote', 'list']
|
||||
|
|
|
@ -6,3 +6,4 @@ en:
|
|||
discourse_math_enabled: 'Enable Discourse Math plugin (will add special processing to $ and $$ blocks)'
|
||||
discourse_math_zoom_on_hover: 'Zoom 200% on hover'
|
||||
discourse_math_enable_accessibility: 'Enable accessibility features'
|
||||
discourse_math_enable_asciimath: 'Enable asciimath (will add special processing to % delimited input)'
|
||||
|
|
|
@ -8,3 +8,6 @@ plugins:
|
|||
discourse_math_enable_accessibility:
|
||||
default: false
|
||||
client: true
|
||||
discourse_math_enable_asciimath:
|
||||
default: false
|
||||
client: true
|
||||
|
|
Loading…
Reference in New Issue