Please add fen support

on my android devices, my chess notes are rendered correctly. On the contrary, it does not work on my apple devices.

please fix it !

It appears AnkiDroid just uses a bit of JavaScript to render it correctly.

If you could share a sample deck, maybe with just one card in it, it should be possible to do something similar using the same JavaScript code and add it to the card template to make it work on AnkiMobile too.

2 Likes

Hello,

Do not know how to share a deck here. Can you just make the “template” and share it ?

Thanks.

No answer. Instead of creating a template, can you explain to me how to do so based on your precedent post ?

Thank you.

Sure. I don’t know how much needs to be explained and if it’ll be useful or not.

The Java code to find and replace all [fen][/fen] tags will need to be replaced with the equivalent JavaScript code

The JavaScript code seems to be possible to copy more or less as it is, except maybe document.write().

A number of clients are implemented by keeping a long running webpage and dynamically updating parts of it as cards are reviewed, so your Javascript will need to update sections of the document using things like document.getElementById() rather than doing things like document.write().
Introduction - Anki Manual

It probably won’t be necessary, but maybe it’d be better to wrap it with onUpdateHook, it’ll probably work on AnkiMobile too, but I’m not sure, or maybe use setTimeout(fn, 0).

https://addon-docs.ankiweb.net/#/more?id=javascript

In addition, maybe a custom font will need to be added, or maybe not.

Introduction - Anki Manual

The Chrome DevTools might come in handy.

You can now debug the webviews using an external Chrome instance, by setting the env var QTWEBENGINE_REMOTE_DEBUGGING to 8080 prior to starting Anki, then surfing to localhost:8080 in Chrome.
Introduction - Writing Anki Add-ons

1 Like

Here it is.

  1. The Front field, for example, contains [fen]rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR[/fen].

  2. Wrap the front or/and the back template with <div> tag and assign some unique id or class attribute, or just wrap a field that contains [fen]...[/fen] tags.

    <div class="wrapper">{{Front}}</div>
    
  3. Add the following script to the end of the front or/and the back template.

    <script>
    function renderFen(fentxt, showBlack) {
        fentxt=fentxt.replace(/ .*/g,'');
        if (showBlack) {
            fentxt = fentxt.split("").reverse().join("");
        }
        fentxt=fentxt.replace(/r/g,'x');
        fentxt=fentxt.replace(/\//g,'</tr><tr>');
        fentxt=fentxt.replace(/1/g,'<td></td>');
        fentxt=fentxt.replace(/2/g,'<td></td><td></td>');
        fentxt=fentxt.replace(/3/g,'<td></td><td></td><td></td>');
        fentxt=fentxt.replace(/4/g,'<td></td><td></td><td></td><td></td>');
        fentxt=fentxt.replace(/5/g,'<td></td><td></td><td></td><td></td><td></td>');
        fentxt=fentxt.replace(/6/g,'<td></td><td></td><td></td><td></td><td></td><td></td>');
        fentxt=fentxt.replace(/7/g,'<td></td><td></td><td></td><td></td><td></td><td></td><td></td>');
        fentxt=fentxt.replace(/8/g,'<td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td>');
        fentxt=fentxt.replace(/K/g,'<td>&#9812;</td>');
        fentxt=fentxt.replace(/Q/g,'<td>&#9813;</td>');
        fentxt=fentxt.replace(/R/g,'<td>&#9814;</td>');
        fentxt=fentxt.replace(/B/g,'<td>&#9815;</td>');
        fentxt=fentxt.replace(/N/g,'<td>&#9816;</td>');
        fentxt=fentxt.replace(/P/g,'<td>&#9817;</td>');
        fentxt=fentxt.replace(/k/g,'<td>&#9818;</td>');
        fentxt=fentxt.replace(/q/g,'<td>&#9819;</td>');
        fentxt=fentxt.replace(/x/g,'<td>&#9820;</td>');
        fentxt=fentxt.replace(/b/g,'<td>&#9821;</td>');
        fentxt=fentxt.replace(/n/g,'<td>&#9822;</td>');
        fentxt=fentxt.replace(/p/g,'<td>&#9823;</td>');
        return '<div align=\"center\" width=\"100%%\"><table class=\"chess_board\" cellspacing=\"0\" cellpadding=\"0\"><tr>'+fentxt+'</tr></table></div>';
    };
    
    function replaceFen(match, p1, p2) {
        let showBlack = false;
        let fenOrientationPattern = /orientation *= *\"?(black|white)\"?/;
        let mo = p1.match(fenOrientationPattern); 
        if (mo && mo[1] == "black") {
            showBlack = true;
        }
        return renderFen(p2, showBlack);
    }
    
    function fenToChessboard() {
        onUpdateHook.push(function () {
            let card = $(".wrapper");
            let txt = card.html();
            txt = txt.replace(/\[fen ?([^\]]*)\]([^\[]+)\[\/fen\]/g, replaceFen);
            card.html(txt);
        })
    }
    
    let isAnkiDroid = /Android/i.test(navigator.userAgent);
    
    if (!isAnkiDroid) {
        fenToChessboard();
    }
    </script>
    
  4. Copy CSS from AnkiDroid to the Styling section.

    https://github.com/ankidroid/Anki-Android/blob/master/AnkiDroid/src/main/assets/chess.css


2 Likes