Fossil Forum

hruodr 1 month, 2 weeks ago

Post: fossil + MathJax

Post: fossil + MathJax

hruodr 1 month, 2 weeks ago

Edit: fossil + MathJax

hruodr 1 month, 2 weeks ago

Hallo!

It is nice to have a wiki, a forum in which one can write math formulae.

Fossil almost do it. Unfortunately almost.

I have at the root of the web server MathJax installed.

I put at the end of footer:

set cp3 [string range $current_page 0 2] if {$cp3 eq "for" || $cp3 eq "wik" || $cp3 eq "tkt" || $cp3 eq "tec" } { html {}}

Unfortunately it does not work everywhere as expected. In the wiki we see the formulae:

https://2x5.eu/cgi/repo/mathfossil/wiki?name=mathfossil&p

In the home page no effect, we see the source:

https://2x5.eu/cgi/repo/mathfossil/home

It does also not work in the preview.

Any idea?

Thanks! Rod.

UPDATE: In the forum the preview works.

UPDATE 2: added || cp3 eq "hom", now it renders the home page. It remains preview in wiki.

hruodr 1 month, 2 weeks ago

I experimented a little more.

I deleted (temporarily) the conditional on the page name:

if {$cp3 eq "for" || $cp3 eq "wik" || $cp3 eq "tkt" || $cp3 eq "tec" || $cp3 eq "hom"}

(It is against there, I do not remember why I put it, perhaps copied from a template long ago)

The problem is remained for the preview of the wiki.

On technical notes and forum there is no problem with the preview.

Does this mean, the problem lies in the Wiki editor? That it cannot reach the Javascript?

I think everybody can try the sandbox at the moment.

stephan 1 month, 2 weeks ago

Reply: fossil + MathJax

stephan 1 month, 2 weeks ago

Does this mean, the problem lies in the Wiki editor?

/wikiedit and /fileedit are not capable of rendering tags which are rejected by the markdown-to-wiki converter, which includes SCRIPT tags. (Another, i see now, is SVG, but that limitation can almost certainly be lifted.) This is not a bug, but a security precaution.

Embedded docs can handle script tags, but /fileedit doesn't. i'm uncertain as to whether wiki pages imported via the wiki CLI command can support script tags.

hruodr 1 month, 2 weeks ago

Reply: fossil + MathJax

hruodr 1 month, 2 weeks ago

Did you see the links?! As Markup-Style, I am using Fossil-Wiki, not Markdown, and it is rendering the formulae.

As I wrote, the preview in the wiki does not work, but preview in forum and technical notes do work.

The problem is 1) the previw 2) in the wiki. When I submit, the formulae are rendered in the wiki.

wyoung 1 month, 2 weeks ago

I haven’t examined the code, but my hypothesis is that the skin footer doesn’t run on the Preview Ajax load.

I see the same symptoms with ASCIIMathML.js as exemplified here.

(Can’t dig deeper right now.) Z efa

hruodr 1 month, 2 weeks ago

I just saw the last lines of source of the preview in my browser (see below). Is that Ajax?! The footer is being passed almost verbatim.

I do not know much about javascript ...

Rod.



george 1 month, 2 weeks ago

Please see the old post on the topic.

In the past I managed MathJax (version 2.7) to work with Fossil; including within the preview tabs of Fossil's editors.

Below is the relevant excerpt from my footer.txt

<script nonce="$nonce">

....

if( 'undefined' !== typeof fossil && fossil ) {
  if( fossil.page.name == 'wikiedit' || fossil.page.name == 'fileedit' ){
    fossil.page.addEventListener(
      fossil.page.name + '-preview-updated', function( ev ){
        if( ev.detail.mimetype !== 'text/plain' ){

          highlight( ev.detail.element );
          if( 'undefined' !== typeof MathJax && MathJax )
            MathJax.Hub.Queue(["Typeset",MathJax.Hub,ev.detail.element]);
        }
    });
  }
}

....

</script>

Note that you might need $nonce to pass through the CSP.

P.S.

And for highlight.js you may use something like that:

function highlight( element ) {

  if( 'undefined' !== typeof hljs && hljs ) {
    /*
      hljs.initHighlighting();
      Stop hljs from brute-force guessing what any given block is,
      which is an unnecessary CPU hog/battery drain.
    */
    var languages = ['yaml','json','csv','sql','sh','bash','shell',
      'c','cpp','h','hpp','javascript','js','tcl','go','rust','makefile',
      'css','html','markdown','tex'];
    var i;
    for( i=0; i < languages.length; i++ ){
      element.querySelectorAll( "pre > code.language-" + languages[i] )
        .forEach(function(block) { hljs.highlightBlock(block) });
    }
  }
}

window.addEventListener('load', function(){ highlight(document); });
spindrift 1 month, 2 weeks ago

Reply: fossil + MathJax

spindrift 1 month, 2 weeks ago

Another, i see now, is SVG, but that limitation can almost certainly be lifted

Don't forget that SVGs can contain and (in some circumstances) run JavaScript, and so are not entirely benign without additional protection.

You would need to sanitise user provided SVGs if you wanted to avoid XSS risks from them.

edit - parenthesis got away from me there. Whoa boy!

wyoung 1 month, 2 weeks ago

I just saw the last lines of source of the preview in my browser (see below).

ASCIIMathML.js works a bit differently. The stock distribution runs automatically on page load, but then sets a flag to prevent it from running again; this is what was preventing the Preview load from styling the re-rendered page each time. While I could have defeated that, I didn’t actually want it to run all the time, just on <div class="markdown"> blocks, else it messes up /vdiff and /file views of code files containing backticks.

I therefore set the translateOnLoad configuration flag to false, then added a bunch of JS to my custom skin’s footer to carefully control exactly where and when it runs, with this result:

function processMarkdown(el) {
    var md = el && (el.classList && el.classList.contains('markdown') ? el : el.querySelector('div.markdown'));
    if (!md) return;
    if (typeof highlight === 'function') highlight(md);
    var am = (typeof asciimath !== 'undefined' ? asciimath : window.asciimath);
    if (am && am.AMprocesssNode) {
        var raw = md.innerHTML.replace(/&#96;/g, '`').replace(/&grave;/gi, '`');
        if (raw.indexOf('`') !== -1) {
            md.innerHTML = raw.replace(/`(?![\s<\n])/g, '` ');
            am.AMprocesssNode(md, false, null);
        }
    }
    if (typeof Prism !== 'undefined' && Prism.highlightAllUnder)
        Prism.highlightAllUnder(md, false);
}

function setupPreviewHandling() {
    var md = document.querySelector('div.markdown');
    var wrap = document.getElementById('wikiedit-tab-preview-wrapper');
    if (md && (!wrap || !wrap.contains(md))) {
        function runAfterLoad() {
            if (document.readyState === 'complete') processMarkdown(md);
            else window.addEventListener('load', function () { processMarkdown(md); });
        }
        runAfterLoad();
    }

    var fp = (typeof fossil !== 'undefined' && fossil && fossil.page) ? fossil.page : null;
    if (!fp) return;
    if (fp.name === 'fileedit' && typeof fp.addEventListener === 'function') {
        fp.addEventListener('fileedit-preview-updated', function (ev) {
            var d = ev.detail;
            if (d && d.element && d.mimetype !== 'text/plain' && d.previewMode !== 'htmlIframe')
                processMarkdown(d.element);
        });
        return;
    }
    if (fp.name === 'wikiedit' && wrap && typeof MutationObserver !== 'undefined') {
        var raf = 0;
        new MutationObserver(function () {
            if (raf) cancelAnimationFrame(raf);
            raf = requestAnimationFrame(function () { raf = 0; processMarkdown(wrap); });
        }).observe(wrap, { childList: true, subtree: true });
    }
}

if (document.location.href.indexOf('/file') > 0) {
    var pres = document.getElementsByTagName('pre');
    if (pres.length) {
        var p = pres[0], params = new URL(document.location).searchParams, name = params.get('name');
        var href = document.location.href, loc = name || href;
        if (loc.endsWith('.in')) loc = loc.slice(0, -3);
        var lang = '';
        if (href.indexOf('&ln') > 0) { }
        else if (p.innerHTML.indexOf('#!/bin/bash') != -1) lang = 'bash';
        else if (p.innerHTML.indexOf('#!/usr/bin/env perl') != -1) lang = 'perl';
        else if (loc.indexOf('/Makefile') != -1) lang = 'makefile';
        else if (loc.endsWith('.go')) lang = 'go';
        else if (loc.endsWith('/go.mod')) lang = 'go-module';
        else if (loc.endsWith('.json')) lang = 'json';
        else if (loc.endsWith('.yaml')) lang = 'yaml';
        if (lang) { Prism.util.setLanguage(p, lang); Prism.highlightElement(p); }
    }
}

if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', setupPreviewHandling);
}
else {
    setupPreviewHandling();
}

This also integrates my Prism.js customizations, which does similar things to the highlight.js favored by George and Stephan. Each repo gets a different build of Prism and a different set of file type guessers based on the types of code in that repo, but the basic structure is the same for all.

As you see, both JS files are served via Fossil's /uv feature. You are welcome to pull my copies from here. The Prism.css gets folded directly into the custom Fossil skin CSS, because it rarely changes. Mine is slightly customized, primarily to remove several drop-shadows I don’t like in its Coy theme. Z bed

hruodr 1 month, 2 weeks ago

Thanks a lot! Now we are nearer to the solution, but not jet ...

Without understanding too much I added the code below. Not very prudent ...

Now, if I fill text in the editor, refresh the page (in firefox with Control-F5) and change to preview, I see the formulae rendered.

Note that I updated MathJax to MathJax 3, it use other notation for event ("promises").

I would prefer to outsource more javascript to th1.

Any idea?

l@CW,J@Cl,2X: set cp3 [string range $current_page 0 2] if {$cp3 eq "for" || $cp3 eq "wik" || $cp3 eq "tkt" || $cp3 eq "tec" || $cp3 eq "hom" || $cp3 eq "fil"} { html {n@6F,1W:} html "

hruodr 1 month, 2 weeks ago

Reply: fossil + MathJax

hruodr 1 month, 2 weeks ago

The following works, I must only see how to restrict it to some pages:



hruodr 1 month, 2 weeks ago

Delete reply: fossil + MathJax

hruodr 1 month, 2 weeks ago

Thanks a lot!

The following works, I must only see how to restrict it to some pages:



wyoung 1 month, 2 weeks ago

I must only see how to restrict it to some pages:

See my logic above. Much of it applies to MathJax case, too.

hruodr 1 month, 2 weeks ago

Thanks, but the small I wrote above works.

My problem is now to restrict what pages get this javascript.

I am having strange experiences with th1. I try with something like the text below, but something goes wrong.

I do not know the exact name of the pages. home seems not to be home, is not rendered. wikiedit is now OK, but not wiki.

Before I had:

set cp3 [string range $current_page 0 2] if {$cp3 eq "for" || $cp3 eq "wik" || $cp3 eq "tkt" || $cp3 eq "tec" } {...

Soon I may pause and take it offline ...


set cp $current_page if {$cp eq "home" || $cp eq "forumpost" || $cp eq "forume2" || $cp eq "wiki" || $cp eq "wikiedit" || $cp eq "technote" || $cp eq "technoteedit" || $cp eq "tktview" || $cp eq "tktedit"} { html { }} if {$cp eq "wikiedit"} { html " }}


wyoung 1 month, 2 weeks ago

My problem is now to restrict what pages get this javascript.

That's what I'm telling you: my code examines the content of the page to determine whether math formatting should be done here.

ASCIIMathML uses backticks to indicate math expressions, which means I have to escape them in my Markdown source when I don't want them turned into <code> spans, but it also means if I use Markdown in a commit message, I want it to not try interpreting the text as a math expression. I also don't want my Go literal strings mangled in this way; that also uses backticks.

Thus, if the page does not have a div.markdown on it, I don't want math formatting applied. I assume this is the kind of thing you mean when you say you want it to run only on some pages, not others.

hruodr 1 month, 2 weeks ago

Well, I wanted / want a little more than neutralizing any effect of the Javascript code in the pages where is not relevant: I want that it not even appear there. For that is th1 good, but for doing it I need this info:

https://fossil-scm.org/forum/forumpost/88e17ac17b

Note that my knowledge of Javascript and its use in Broswers is very rudimentary, I learnt a lot by only fixing the above code of george to MathJax 4.

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button