<commit_before>define(['mathlive/core/mathAtom'],
    function(MathAtom) {


/**
 * Give an atom or an array of atoms, return a LaTeX string representation
 * @return {string}
 * @param {string|MathAtom|MathAtom[]} value 
 * @private
 */
function latexify(value, expandMacro) {
    let result = '';
    if (Array.isArray(value)) {
        for (const child of value) {
            result += latexify(child, expandMacro);
        }
    } else if (typeof value === 'number' || typeof value === 'boolean') {
        result = value.toString();
    } else if (typeof value === 'string') {
        result = value.replace(/\s/g, '~');
    } else if (value && typeof value.toLatex === 'function') {
        result = value.toLatex(expandMacro);
    }
    return result;
}



/**
 * Return a LaTeX representation of the atom
 * 
 * @param {boolean} expandMacro - If true, macros are fully expanded. This will
 * no longer round-trip.
 * 
 * @return {string}
 */
MathAtom.MathAtom.prototype.toLatex = function(expandMacro) {
    expandMacro = expandMacro === undefined ? false : expandMacro;
    let result = '';
    let col, row = 0;
    let i = 0;
    const command = this.latex ? this.latex.trim() : null;
    switch(this.type) {
        case 'group':
            result += this.latexOpen || '{';
            result += expandMacro ? latexify(this.body, true) : 
                (this.latex || latexify(this.body, false)); 
            result += this.latexClose || '}';
            break;

        case 'array':
            result += '\\begin{' + this.env.name + '}';
            if (this.env.name === 'array') {
                result += '{';
                if (this.colFormat) {
                    for (i = 0; i < this.colFormat.length; i++) {
                        if (this.colFormat[i].align) {
                            result += this.colFormat[i].align;
                        } else if (this.colFormat[i].rule) {
                            result += '|';
                        }
                    }
                }
                result += '}';
            }
            for (row = 0; row < this.array.length; row++) {
                for (col = 0; col < this.array[row].length; col++) {
                    if (col > 0) result += ' & ';
                    result += latexify(this.array[row][col], expandMacro);
                }
                // Adds a separator between rows (but not after the last row)
                if (row < this.array.length - 1) {
                    result += ' \\\\ ';
                }
            }
            result += '\\end{' + this.env.name + '}';
            break;

        case 'root':
            result = latexify(this.body, expandMacro);
            break;

        case 'genfrac':
            if (this.body === 'choose' || this.body === 'atop') {
                // Infix commands.
                result += '{';
                result += latexify(this.numer, expandMacro)
                result += '\\' + this.body + ' ';
                result += latexify(this.denom, expandMacro);
                result += '}';
            } else {
                // @todo: deal with fracs delimiters
                result += this.latex;
                result += `{${latexify(this.numer, expandMacro)}}{${latexify(this.denom, expandMacro)}}`;
            }
            break;

        case 'surd':
            result += '\\sqrt';
            if (this.index) {
                result += '[';
                result += latexify(this.index, expandMacro);
                result += ']';
            }
            result += `{${latexify(this.body, expandMacro)}}`;
            break;

        case 'leftright':
            if (this.inner) {
                result += '\\left' + (this.leftDelim || '.');
                if (this.leftDelim && this.leftDelim.length > 1) result += ' ';
                result += latexify(this.body, expandMacro);<commit_msg>Correctly output \over command<commit_after>define(['mathlive/core/mathAtom'],
    function(MathAtom) {


/**
 * Give an atom or an array of atoms, return a LaTeX string representation
 * @return {string}
 * @param {string|MathAtom|MathAtom[]} value 
 * @private
 */
function latexify(value, expandMacro) {
    let result = '';
    if (Array.isArray(value)) {
        for (const child of value) {
            result += latexify(child, expandMacro);
        }
    } else if (typeof value === 'number' || typeof value === 'boolean') {
        result = value.toString();
    } else if (typeof value === 'string') {
        result = value.replace(/\s/g, '~');
    } else if (value && typeof value.toLatex === 'function') {
        result = value.toLatex(expandMacro);
    }
    return result;
}



/**
 * Return a LaTeX representation of the atom
 * 
 * @param {boolean} expandMacro - If true, macros are fully expanded. This will
 * no longer round-trip.
 * 
 * @return {string}
 */
MathAtom.MathAtom.prototype.toLatex = function(expandMacro) {
    expandMacro = expandMacro === undefined ? false : expandMacro;
    let result = '';
    let col, row = 0;
    let i = 0;
    const command = this.latex ? this.latex.trim() : null;
    switch(this.type) {
        case 'group':
            result += this.latexOpen || '{';
            result += expandMacro ? latexify(this.body, true) : 
                (this.latex || latexify(this.body, false)); 
            result += this.latexClose || '}';
            break;

        case 'array':
            result += '\\begin{' + this.env.name + '}';
            if (this.env.name === 'array') {
                result += '{';
                if (this.colFormat) {
                    for (i = 0; i < this.colFormat.length; i++) {
                        if (this.colFormat[i].align) {
                            result += this.colFormat[i].align;
                        } else if (this.colFormat[i].rule) {
                            result += '|';
                        }
                    }
                }
                result += '}';
            }
            for (row = 0; row < this.array.length; row++) {
                for (col = 0; col < this.array[row].length; col++) {
                    if (col > 0) result += ' & ';
                    result += latexify(this.array[row][col], expandMacro);
                }
                // Adds a separator between rows (but not after the last row)
                if (row < this.array.length - 1) {
                    result += ' \\\\ ';
                }
            }
            result += '\\end{' + this.env.name + '}';
            break;

        case 'root':
            result = latexify(this.body, expandMacro);
            break;

        case 'genfrac':
            if (/^(choose|atop|over)$/.test(this.body)) {
                // Infix commands.
                result += '{';
                result += latexify(this.numer, expandMacro)
                result += '\\' + this.body + ' ';
                result += latexify(this.denom, expandMacro);
                result += '}';
            } else {
                // @todo: deal with fracs delimiters
                result += this.latex;
                result += `{${latexify(this.numer, expandMacro)}}{${latexify(this.denom, expandMacro)}}`;
            }
            break;

        case 'surd':
            result += '\\sqrt';
            if (this.index) {
                result += '[';
                result += latexify(this.index, expandMacro);
                result += ']';
            }
            result += `{${latexify(this.body, expandMacro)}}`;
            break;

        case 'leftright':
            if (this.inner) {
                result += '\\left' + (this.leftDelim || '.');
                if (this.leftDelim && this.leftDelim.length > 1) result += ' ';
                result += latexify(this.body, expandMacro);
{'fraction_non_alphanumeric': 0.15010896038969362, 'fraction_numerical': 0.00205101910011537, 'mean_word_length': 1.4465349639385388, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1174653', 'n_tokens_mistral': 2328, 'n_tokens_neox': 2174, 'n_words': 509}