Skip to content

Commit

Permalink
Support non-RGB colours
Browse files Browse the repository at this point in the history
  • Loading branch information
nihil-admirari committed Sep 11, 2023
1 parent b69ce20 commit 5e036f6
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 29 deletions.
28 changes: 4 additions & 24 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -125,27 +125,7 @@ and ``back.template.anki``, and redefine ``\AnkiClozeA`` and ``\AnkiClozeA`` as
Reloading ``_cloze-overlapper.mjs``
-----------------------------------

If you make changes to ``_cloze-overlapper.mjs``, you'll have to restart Anki.
``_cloze-overlapper.mjs`` defines a custom element ``<cloze-generator>`` and any attempt
to redefine it (e.g. by loading ``_cloze-overlapper.mjs?dev=1``) will throw an error.

.. |strike-start| raw:: html

<strike>

.. |strike-end| raw:: html

</strike>

|strike-start|
JavaScript modules, such as ``_cloze-overlapper.mjs``, are loaded exactly once and never reloaded
(unless you restart Anki). However, you can use a dummy query parameter, such as ``?dev=1``,
to reload the module without restarting Anki:

.. code:: javascript
const ClozeOverlapper = await import(`${mediaRoot}/_cloze-overlapper.mjs?dev=1`);
``dev``-counter must be incremented after every modification of ``_cloze-overlapper.mjs``.
When the development is complete, ``dev`` query parameter can be removed and Anki restarted.
|strike-end|
JavaScript modules are not reloaded from disk automatically. In order to reload
``_cloze-overlapper.mjs``, open DevTools on the Network tab, check “Disable cache”,
and press :kbd:`Ctrl + Shift + R`. It empties the card's page completely, but after navigating to
the next/previous card and back the module is reloaded.
34 changes: 29 additions & 5 deletions _cloze-overlapper.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,31 @@ export function stripHtmlFromMathJax(html, cardInfo) {
});
}

const convertToRgba = (() => {
/** @type {OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D | null} */
let context = null;

/**
* @param {string} cssColor
* @return {Uint8ClampedArray}
* */
return cssColor => {
// Android WebView doesn't support offscreen 2D canvas.
// https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas/getContext#browser_compatibility
context ??= new OffscreenCanvas(1, 1).getContext('2d', { willReadFrequently: true });
if (!context) {
const canvas = document.createElement('canvas');
canvas.height = canvas.width = 1;
context = /** @type {CanvasRenderingContext2D} */ (
canvas.getContext('2d', { willReadFrequently: true }));
}
context.clearRect(0, 0, 1, 1);
context.fillStyle = cssColor;
context.fillRect(0, 0, 1, 1);
return context.getImageData(0, 0, 1, 1).data;
};
})();

/** @param {HTMLDivElement} clozeContainer */
function defineMathJaxClozeCommands(clozeContainer) {
// Not using querySelector('span.cloze')
Expand All @@ -582,11 +607,10 @@ function defineMathJaxClozeCommands(clozeContainer) {
const rgbStartIdx = color.startsWith('rgb(') ? 4
: color.startsWith('rgba(') ? 5
: -1;
if (rgbStartIdx !== -1) {
const rgb = color.substring(rgbStartIdx, color.length - 1).split(', ')
.slice(0, 3).map(s => Math.round(Number(s))).join(', ');
ankiClozeQ = String.raw`\color[RGB]{${rgb}} ${ankiClozeQ}`;
}
const rgb = rgbStartIdx !== -1
? color.substring(rgbStartIdx, color.length - 1).split(', ').map(s => Math.round(+s))
: convertToRgba(color); // Slow path.
ankiClozeQ = String.raw`\color[RGB]{${rgb.slice(0, 3).join(', ')}} ${ankiClozeQ}`;
if (fontStyle === 'italic' || fontStyle.startsWith('oblique')) {
ankiClozeQ = String.raw`\mathit{${ankiClozeQ}}`;
}
Expand Down

0 comments on commit 5e036f6

Please sign in to comment.