Giter VIP home page Giter VIP logo

Comments (5)

pkra avatar pkra commented on June 18, 2024 3

While I personally think that design and implementation of font tooling should be prioritized, I have to admit (as a former team member) that few things are as annoying in OSS development as members of large, well funded organizations complaining about OSS they heavily use but do not to support.

from mathjax-src.

dpvc avatar dpvc commented on June 18, 2024

The groundwork is in place to make this possible, but we don't yet have good tools for generating the needed data. MathJax needs to have information about the bounding boxes (and potentially some other stuff) about each glyph in each font. It is possible to generate that information by hand if you only need a few glyphs, but handling whole fonts requires automated tools. There are mechanisms for merging new data about glyphs into the existing font tables, and that is how you would be able to override or extend the characters in the font.

Can you be more specific about your needs? I may be able to suggest what will be needed for your situation (and having actual use cases will help us develop the right tools).

from mathjax-src.

drochgenius avatar drochgenius commented on June 18, 2024

Thanks for your answer, and I'm happy to hear there's ongoing work to improve font integration with MathJax.

My use case is that I want to render math for young kids, and I have some pedagogical constraints on e.g. the shape of the digits. Also, I can't have serifs on numbers.

Example: I need to display open 4, and the number one without the arrow-like top, to avoid children confusing the shape with number 7.
screen shot 2018-10-17 at 10 10 53 am

In additional to that, I want to display equations along with other non-math content, and I want the fonts to be consistent.

We have been able to setup something with MathJax 2 last year.
We used the SVG output jax, and cracked open the Latin Modern SVG glyphs to customize the digits. Basically, we modified the SVG paths, keeping the bounding boxes identical so we can leverage MathJax with Latin Modern metrics.

Ideally, I was hoping we could use HTML output jax with our own Math font in MathJax 3.
I understsand that we need to provide font metrics to Mathjax, and @pkra pointed me to some Perl tools to do this at the time. But we were not able to use them to compute our font metrics. At the same time, he told me that MathJax 3 would aim to ease the font customization process. However, I was just trying out the beta lately, and did not find anything related to that, that's why I'm asking this question now.

I think it would be useful if you could describe what kind of metrics Mathjax is expecting, and even better, if your team could define a clear format for font metrics ingestion. If this is possible, I'm keen to look at contributing some tooling for the community to help automate font metrics computation for MathJax.

Regards

from mathjax-src.

drochgenius avatar drochgenius commented on June 18, 2024

Hi @pkra , I understand and agree with you. I am convinced that organizations like ours would gain a lot from contributing more to OSS development and am advocating it internally.

Thank you

from mathjax-src.

dpvc avatar dpvc commented on June 18, 2024

@drochgenius, thanks for your advocacy, and your interest in helping with MathJax.

You ask about the information needed by MathJax, and the font API. The v3 beta already has mechanisms for declaring changes to the font information, and I have put together a couple of examples showing how this is done. They are in my MathJax v3 repository in the extend-fonts branch.

There are two HTML files, one for SVG and one for CHTML output, that each call in a customization file that replaces the number 1 in the "normal" math variant (which is where the digits usually come from). There customization files are in the samples directory as font-extend-svn.js and font-extend-chtml.js. The SVG version is

import {MathJax} from '../mathjax3/mathjax.js';

import {TeX} from '../mathjax3/input/tex.js';
import {SVG} from '../mathjax3/output/svg.js';
import {RegisterHTMLHandler} from '../mathjax3/handlers/html.js';
import {browserAdaptor} from '../mathjax3/adaptors/browserAdaptor.js';

import '../mathjax3/input/tex/base/BaseConfiguration.js';
import '../mathjax3/input/tex/ams/AmsConfiguration.js';
import '../mathjax3/input/tex/boldsymbol/BoldsymbolConfiguration.js';
import '../mathjax3/input/tex/newcommand/NewcommandConfiguration.js';

RegisterHTMLHandler(browserAdaptor());

const tex = new TeX({packages: ['base', 'ams', 'newcommand', 'boldsymbol']});
const svg = new SVG();

//
//  Modify the normal variant glyphs for the number 1.
//
//  The 0x31 is the charater number (unicode position) of the number 1.
//
//  The data are [height, depth, width, {p: path}]
//
//  The height, depth and width are in ems.
//  The 'p' value is the path without the initial M and final Z.
//    In this case, it is just a thin vertical box.
//    The units of the path are 1000th of an em.
//
//  You can set as many characters as you need in a given variant in one call to defineChars().
//
svg.font.defineChars('normal', {
    0x31: [.666, 0, .5, {p: '220 0L220 666L280 666L280 0'}]
});
           

const html = MathJax.document(document, {InputJax: tex, OutputJax: svg});

MathJax.handleRetriesFor(() => {

    html.findMath()
        .compile()
        .getMetrics()
        .typeset()
        .updateDocument();
        
}).catch(err => console.log(err.stack));

so you can see there is not really much to it: most of the code is the standard stuff needed to load and initialize the MathJax components, and there is a single call to customize the font used for the normal variant. You would want similar calls for bold and any other variants that you need, and of course you would need to use the correct path for your "1", and include whatever other characters you need to replace.

The CHTML case is similar:

import {MathJax} from '../mathjax3/mathjax.js';

import {TeX} from '../mathjax3/input/tex.js';
import {CHTML} from '../mathjax3/output/chtml.js';
import {RegisterHTMLHandler} from '../mathjax3/handlers/html.js';
import {browserAdaptor} from '../mathjax3/adaptors/browserAdaptor.js';

import '../mathjax3/input/tex/base/BaseConfiguration.js';
import '../mathjax3/input/tex/ams/AmsConfiguration.js';
import '../mathjax3/input/tex/boldsymbol/BoldsymbolConfiguration.js';
import '../mathjax3/input/tex/newcommand/NewcommandConfiguration.js';

RegisterHTMLHandler(browserAdaptor());

const tex = new TeX({packages: ['base', 'ams', 'newcommand', 'boldsymbol']});
const chtml = new CHTML();

//
//  Modify the normal variant for the number 1 to come from a custom font.
//
//  The 0x31 is the charater number (unicode position) of the number 1.
//
//  The data are [height, depth, width, {c: string, f: font, css: flags}]
//
//  The height, depth, and width are in em's.
//  The 'c' string is the string in the custom font to use for this character.
//  The 'f' string is the suffix for the font to use (it refer to MJXTEX-CUSTOM in this case).
//  The 'css' value is a set of bit flags indicating what cusomt CSS needs to be
//    set, in this case it is the width (0x01), the height and depth (0x02), and the
//    text string for the character (0x04).  (Some variants may not need to set all of
//    these in the CSS, as they can be inherited from other fonts; e.g., the bold "1"
//    need not set the character string, since it will inherit that from the normal "1".)
//
//  You can set as many characters as you need in a given variant in one call to defineChars().
//
chtml.font.defineChars('normal', {
    0x31: [.82, 0, .569, {c: '1', f: 'CUSTOM', css: 7}]
});

//
// Define the font used for the custom characters
//
chtml.font.constructor.defaultFonts['@font-face /* CUSTOM */'] = {
    'font-family': 'MJXTEX-CUSTOM',
    'src': 'local(\'Arial\')'
};

const html = MathJax.document(document, {InputJax: tex, OutputJax: chtml});

MathJax.handleRetriesFor(() => {

    html.findMath()
        .compile()
        .getMetrics()
        .typeset()
        .updateDocument();
        
}).catch(err => console.log(err.stack));

Here, we need to set the data for the character, as well as specify the font that will be used.

These sample files simply typeset the page when loaded (technically, you don't need the MathJax.handleRetriesFor() wrapper since we no longer use any of the asynchronous version 2 code, but it does let you trap errors, and could be used with future dynamic loading options.

To use the demos, clone dpvc/mathjax-v3, cd to the cloned directory, check out the extend-fonts branch, use npm to install the dependencies, run typescript to compile MathJax v3, and open one of the sample HTML files:

git clone https://github.com/dpvc/mathjax-v3.git mj3
cd mj3
git checkout extend-fonts
npm install
npx tsc

then open sample-svn.html or sample-chtml.html in a browser.

The sample HTML files are set to load the configuration files using System.js so you don't need to webpack anything to do the testing. But if you want to make a combined file, you can use the examples in the mathjax/mj3-demos repository and incorporate the font changes to get your custom single-file build. In that case, you can remove all the scripts in the sample HTML files and just include your combined file instead.

from mathjax-src.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.