mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	@@ -1,6 +1,7 @@
 | 
			
		||||
/*global Dict */
 | 
			
		||||
var path = zrequire('path', 'path');
 | 
			
		||||
var fs = zrequire('fs', 'fs');
 | 
			
		||||
 | 
			
		||||
zrequire('hash_util');
 | 
			
		||||
zrequire('katex', 'node_modules/katex/dist/katex.min.js');
 | 
			
		||||
zrequire('marked', 'third/marked/lib/marked');
 | 
			
		||||
@@ -172,18 +173,19 @@ var bugdown_data = JSON.parse(fs.readFileSync(path.join(__dirname, '../../zerver
 | 
			
		||||
 | 
			
		||||
(function test_marked_shared() {
 | 
			
		||||
    var tests = bugdown_data.regular_tests;
 | 
			
		||||
 | 
			
		||||
    tests.forEach(function (test) {
 | 
			
		||||
        var message = {raw_content: test.input};
 | 
			
		||||
        markdown.apply_markdown(message);
 | 
			
		||||
        var output = message.content;
 | 
			
		||||
 | 
			
		||||
        if (test.marked_expected_output) {
 | 
			
		||||
            assert.notEqual(test.expected_output, output);
 | 
			
		||||
            assert.equal(test.marked_expected_output, output);
 | 
			
		||||
            global.bugdown_assert.notEqual(test.expected_output, output);
 | 
			
		||||
            global.bugdown_assert.equal(test.marked_expected_output, output);
 | 
			
		||||
        } else if (test.backend_only_rendering) {
 | 
			
		||||
            assert.equal(markdown.contains_backend_only_syntax(test.input), true);
 | 
			
		||||
        } else {
 | 
			
		||||
            assert.equal(test.expected_output, output);
 | 
			
		||||
            global.bugdown_assert.equal(test.expected_output, output);
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}());
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										179
									
								
								frontend_tests/zjsunit/bugdown_assert.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								frontend_tests/zjsunit/bugdown_assert.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,179 @@
 | 
			
		||||
/**
 | 
			
		||||
 * bugdown_assert.js
 | 
			
		||||
 *
 | 
			
		||||
 * Used to determine whether two Markdown HTML strings are semantically
 | 
			
		||||
 * equivalent. Differs from the naive string-comparison approach in that
 | 
			
		||||
 * differently typed but equivalent HTML fragments, such as '<p>"</p>'
 | 
			
		||||
 * and '<p>\"</p>', and '<span attr1="a" attr2="b"></span>' and
 | 
			
		||||
 * '<span attr2="a" attr1="b"></span>', are still considered equal.
 | 
			
		||||
 *
 | 
			
		||||
 * The exported method equal() serves as a drop-in replacement for
 | 
			
		||||
 * assert.equal().  Likewise, the exported method notEqual() replaces
 | 
			
		||||
 * assert.notEqual().
 | 
			
		||||
 *
 | 
			
		||||
 * There is a default _output_formatter used to create the
 | 
			
		||||
 * AssertionError error message; this function can be overriden using
 | 
			
		||||
 * the exported setFormatter() function below.
 | 
			
		||||
 *
 | 
			
		||||
 * The HTML passed to the _output_formatter is not the original HTML, but
 | 
			
		||||
 * rather a serialized version of a DOM element generated from the original
 | 
			
		||||
 * HTML.  This makes it easier to spot relevant differences.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
const jsdom = require('jsdom');
 | 
			
		||||
const _ = require('underscore');
 | 
			
		||||
 | 
			
		||||
// Module-level global instance of MarkdownComparer, initialized when needed
 | 
			
		||||
let _markdownComparerInstance = null;
 | 
			
		||||
 | 
			
		||||
class MarkdownComparer {
 | 
			
		||||
    constructor(output_formatter) {
 | 
			
		||||
        this._output_formatter = output_formatter || function (actual, expected) {
 | 
			
		||||
            return ["Actual and expected output do not match.",
 | 
			
		||||
                    actual,
 | 
			
		||||
                    "!=",
 | 
			
		||||
                    expected,
 | 
			
		||||
                ].join('\n');
 | 
			
		||||
        };
 | 
			
		||||
        this._document = jsdom.jsdom();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setFormatter(output_formatter) {
 | 
			
		||||
        this._output_formatter = output_formatter || this._output_formatter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _htmlToElement(html, id) {
 | 
			
		||||
        const template = this._document.createElement('template');
 | 
			
		||||
        const id_node = this._document.createAttribute('id');
 | 
			
		||||
        id_node.value = id;
 | 
			
		||||
        template.setAttributeNode(id_node);
 | 
			
		||||
        template.innerHTML = html;
 | 
			
		||||
        return template;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _haveEqualContents(node1, node2) {
 | 
			
		||||
        if (node1.content.childNodes.length !== node2.content.childNodes.length) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return _.reduce(
 | 
			
		||||
            _.zip(node1.content.childNodes, node2.content.childNodes),
 | 
			
		||||
            (prev, nodePair) => { return prev && nodePair[0].isEqualNode(nodePair[1]); },
 | 
			
		||||
            true
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _reorderAttributes(node) {
 | 
			
		||||
        // Sorts every attribute in every element by name.  Ensures consistent diff HTML output
 | 
			
		||||
 | 
			
		||||
        const attributeList = [];
 | 
			
		||||
        _.forEach(node.attributes, (attr) => {
 | 
			
		||||
            attributeList.push(attr);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // If put in above forEach loop, causes issues (possible nodes.attribute invalidation?)
 | 
			
		||||
        attributeList.forEach((attr) => {node.removeAttribute(attr.name);});
 | 
			
		||||
 | 
			
		||||
        attributeList.sort((a, b) => {
 | 
			
		||||
            const name_a = a.name;
 | 
			
		||||
            const name_b = b.name;
 | 
			
		||||
            if (name_a < name_b) {
 | 
			
		||||
                return -1;
 | 
			
		||||
            } else if (name_a > name_b) {
 | 
			
		||||
                return 1;
 | 
			
		||||
            }
 | 
			
		||||
            return 0;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Put them back in, in order
 | 
			
		||||
        attributeList.forEach((attribute) => {
 | 
			
		||||
            node.setAttribute(attribute.name, attribute.value);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (node.hasChildNodes()) {
 | 
			
		||||
            _.forEach(node.children, (childNode) => {
 | 
			
		||||
                this._reorderAttributes(childNode);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        if (node.content && node.content.hasChildNodes()) {
 | 
			
		||||
            _.forEach(node.content.children, (childNode) => {
 | 
			
		||||
                this._reorderAttributes(childNode);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return node;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _compare(actual_markdown, expected_markdown) {
 | 
			
		||||
        const ID_ACTUAL = "0";
 | 
			
		||||
        const ID_EXPECTED = "1";
 | 
			
		||||
 | 
			
		||||
        const element_actual = this._htmlToElement(actual_markdown, ID_ACTUAL);
 | 
			
		||||
        const element_expected = this._htmlToElement(expected_markdown, ID_EXPECTED);
 | 
			
		||||
 | 
			
		||||
        let are_equivalent = false;
 | 
			
		||||
        let html = {};
 | 
			
		||||
 | 
			
		||||
        are_equivalent = this._haveEqualContents(element_actual, element_expected);
 | 
			
		||||
        if (!are_equivalent) {
 | 
			
		||||
            html = {
 | 
			
		||||
                actual : this._reorderAttributes(element_actual).innerHTML,
 | 
			
		||||
                expected : this._reorderAttributes(element_expected).innerHTML,
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        element_actual.remove();
 | 
			
		||||
        element_expected.remove();
 | 
			
		||||
 | 
			
		||||
        return { are_equivalent, html };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    assertEqual(actual, expected, message) {
 | 
			
		||||
        const comparison_results = this._compare(actual, expected);
 | 
			
		||||
 | 
			
		||||
        if (comparison_results.are_equivalent === false) {
 | 
			
		||||
            throw new assert.AssertionError({
 | 
			
		||||
                message : message || this._output_formatter(
 | 
			
		||||
                    comparison_results.html.actual,
 | 
			
		||||
                    comparison_results.html.expected
 | 
			
		||||
                ),
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    assertNotEqual(actual, expected, message) {
 | 
			
		||||
        const comparison_results = this._compare(actual, expected);
 | 
			
		||||
 | 
			
		||||
        if (comparison_results.are_equivalent) {
 | 
			
		||||
            throw new assert.AssertionError({
 | 
			
		||||
                message : message || [
 | 
			
		||||
                    "actual and expected output produce semantially identical HTML",
 | 
			
		||||
                    actual,
 | 
			
		||||
                    "==",
 | 
			
		||||
                    expected,
 | 
			
		||||
                ].join('\n'),
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    equal(expected, actual, message) {
 | 
			
		||||
        if (!_markdownComparerInstance) {
 | 
			
		||||
            _markdownComparerInstance = new MarkdownComparer();
 | 
			
		||||
        }
 | 
			
		||||
        _markdownComparerInstance.assertEqual(actual, expected, message);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    notEqual(expected, actual, message) {
 | 
			
		||||
        if (!_markdownComparerInstance) {
 | 
			
		||||
            _markdownComparerInstance = new MarkdownComparer();
 | 
			
		||||
        }
 | 
			
		||||
        _markdownComparerInstance.assertNotEqual(actual, expected, message);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setFormatter(output_formatter) {
 | 
			
		||||
        if (!_markdownComparerInstance) {
 | 
			
		||||
            _markdownComparerInstance = new MarkdownComparer();
 | 
			
		||||
        }
 | 
			
		||||
        _markdownComparerInstance.setFormatter(output_formatter);
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
@@ -54,6 +54,9 @@ module.prototype.hot = {
 | 
			
		||||
    accept: noop,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Set up bugdown comparison helper
 | 
			
		||||
global.bugdown_assert = require('./bugdown_assert.js');
 | 
			
		||||
 | 
			
		||||
output.start_writing();
 | 
			
		||||
 | 
			
		||||
files.forEach(function (file) {
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,11 @@
 | 
			
		||||
      "expected_output": "<p>Hamlet once said</p>\n<div class=\"codehilite\"><pre><span></span>def func():\n    x = 1\n\n    y = 2\n\n    z = 3\n</pre></div>\n\n\n<p>And all was good.</p>",
 | 
			
		||||
      "text_content": "Hamlet once said\ndef func():\n    x = 1\n\n    y = 2\n\n    z = 3\n\n\n\nAnd all was good."
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "test",
 | 
			
		||||
      "input": "it's lunch time",
 | 
			
		||||
      "expected_output": "<p>it's lunch time</p>"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "codeblock_trailing_whitespace",
 | 
			
		||||
      "input": "Hamlet once said\n~~~~\ndef func():\n    x = 1\n\n    y = 2\t\t\n\n    z = 3       \n~~~~\nAnd all was good.",
 | 
			
		||||
@@ -93,7 +98,6 @@
 | 
			
		||||
      "name": "dangerous_block",
 | 
			
		||||
      "input": "xxxxxx xxxxx xxxxxxxx xxxx. x xxxx xxxxxxxxxx:\n\n```\"xxxx xxxx\\xxxxx\\xxxxxx\"```\n\nxxx xxxx xxxxx:```xx.xxxxxxx(x'^xxxx$', xx.xxxxxxxxx)```\n\nxxxxxxx'x xxxx xxxxxxxxxx ```'xxxx'```, xxxxx xxxxxxxxx xxxxx ^ xxx $ xxxxxx xxxxx xxxxxxxxxxxx xxx xxxx xx x xxxx xx xxxx xx xxx xxxxx xxxxxx?",
 | 
			
		||||
      "expected_output": "<p>xxxxxx xxxxx xxxxxxxx xxxx. x xxxx xxxxxxxxxx:</p>\n<p><code>\"xxxx xxxx\\xxxxx\\xxxxxx\"</code></p>\n<p>xxx xxxx xxxxx:<code>xx.xxxxxxx(x'^xxxx$', xx.xxxxxxxxx)</code></p>\n<p>xxxxxxx'x xxxx xxxxxxxxxx <code>'xxxx'</code>, xxxxx xxxxxxxxx xxxxx ^ xxx $ xxxxxx xxxxx xxxxxxxxxxxx xxx xxxx xx x xxxx xx xxxx xx xxx xxxxx xxxxxx?</p>",
 | 
			
		||||
      "marked_expected_output": "<p>xxxxxx xxxxx xxxxxxxx xxxx. x xxxx xxxxxxxxxx:</p>\n<p><code>"xxxx xxxx\\xxxxx\\xxxxxx"</code></p>\n<p>xxx xxxx xxxxx:<code>xx.xxxxxxx(x'^xxxx$', xx.xxxxxxxxx)</code></p>\n<p>xxxxxxx'x xxxx xxxxxxxxxx <code>'xxxx'</code>, xxxxx xxxxxxxxx xxxxx ^ xxx $ xxxxxx xxxxx xxxxxxxxxxxx xxx xxxx xx x xxxx xx xxxx xx xxx xxxxx xxxxxx?</p>",
 | 
			
		||||
      "text_content": "xxxxxx xxxxx xxxxxxxx xxxx. x xxxx xxxxxxxxxx:\n\"xxxx xxxx\\xxxxx\\xxxxxx\"\nxxx xxxx xxxxx:xx.xxxxxxx(x'^xxxx$', xx.xxxxxxxxx)\nxxxxxxx'x xxxx xxxxxxxxxx 'xxxx', xxxxx xxxxxxxxx xxxxx ^ xxx $ xxxxxx xxxxx xxxxxxxxxxxx xxx xxxx xx x xxxx xx xxxx xx xxx xxxxx xxxxxx?"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
@@ -447,8 +451,7 @@
 | 
			
		||||
    {
 | 
			
		||||
      "name": "safe_html_messed_up_complexly_nested_script_tags",
 | 
			
		||||
      "input": "<scr<script></script>ipt type=\"text/javascript\">alert(\"foo\");</<script></script>script<del></del>>",
 | 
			
		||||
      "expected_output": "<p><scr<script></script>ipt type=\"text/javascript\">alert(\"foo\");</<script></script>script<del></del>></p>",
 | 
			
		||||
      "marked_expected_output": "<p><scr<script></script>ipt type="text/javascript">alert("foo");</<script></script>script<del></del>></p>"
 | 
			
		||||
      "expected_output": "<p><scr<script></script>ipt type=\"text/javascript\">alert(\"foo\");</<script></script>script<del></del>></p>"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "safe_html_unclosed_tag",
 | 
			
		||||
@@ -527,14 +530,12 @@
 | 
			
		||||
    {
 | 
			
		||||
      "name": "tex_inline",
 | 
			
		||||
      "input": "$$1 \\oplus 0 = 1$$",
 | 
			
		||||
      "expected_output": "<p><span class=\"katex\"><span class=\"katex-mathml\"><math><semantics><mrow><mn>1</mn><mo>⊕</mo><mn>0</mn><mo>=</mo><mn>1</mn></mrow><annotation encoding=\"application/x-tex\">1 \\oplus 0 = 1</annotation></semantics></math></span><span aria-hidden=\"true\" class=\"katex-html\"><span class=\"strut\" style=\"height:0.64444em;\"></span><span class=\"strut bottom\" style=\"height:0.72777em;vertical-align:-0.08333em;\"></span><span class=\"base\"><span class=\"mord mathrm\">1</span><span class=\"mbin\">⊕</span><span class=\"mord mathrm\">0</span><span class=\"mrel\">=</span><span class=\"mord mathrm\">1</span></span></span></span></p>",
 | 
			
		||||
      "marked_expected_output": "<p><span class=\"katex\"><span class=\"katex-mathml\"><math><semantics><mrow><mn>1</mn><mo>⊕</mo><mn>0</mn><mo>=</mo><mn>1</mn></mrow><annotation encoding=\"application/x-tex\">1 \\oplus 0 = 1</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"strut\" style=\"height:0.64444em;\"></span><span class=\"strut bottom\" style=\"height:0.72777em;vertical-align:-0.08333em;\"></span><span class=\"base\"><span class=\"mord mathrm\">1</span><span class=\"mbin\">⊕</span><span class=\"mord mathrm\">0</span><span class=\"mrel\">=</span><span class=\"mord mathrm\">1</span></span></span></span></p>"
 | 
			
		||||
      "expected_output": "<p><span class=\"katex\"><span class=\"katex-mathml\"><math><semantics><mrow><mn>1</mn><mo>⊕</mo><mn>0</mn><mo>=</mo><mn>1</mn></mrow><annotation encoding=\"application/x-tex\">1 \\oplus 0 = 1</annotation></semantics></math></span><span aria-hidden=\"true\" class=\"katex-html\"><span class=\"strut\" style=\"height:0.64444em;\"></span><span class=\"strut bottom\" style=\"height:0.72777em;vertical-align:-0.08333em;\"></span><span class=\"base\"><span class=\"mord mathrm\">1</span><span class=\"mbin\">⊕</span><span class=\"mord mathrm\">0</span><span class=\"mrel\">=</span><span class=\"mord mathrm\">1</span></span></span></span></p>"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "tex_complex",
 | 
			
		||||
      "input": "$$\\Phi_E = \\oint E \\cdot dA$$",
 | 
			
		||||
      "expected_output": "<p><span class=\"katex\"><span class=\"katex-mathml\"><math><semantics><mrow><msub><mi mathvariant=\"normal\">Φ</mi><mi>E</mi></msub><mo>=</mo><mo>∮</mo><mi>E</mi><mo>⋅</mo><mi>d</mi><mi>A</mi></mrow><annotation encoding=\"application/x-tex\">\\Phi_E = \\oint E \\cdot dA</annotation></semantics></math></span><span aria-hidden=\"true\" class=\"katex-html\"><span class=\"strut\" style=\"height:0.805em;\"></span><span class=\"strut bottom\" style=\"height:1.11112em;vertical-align:-0.30612em;\"></span><span class=\"base\"><span class=\"mord\"><span class=\"mord mathrm\">Φ</span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.32833099999999993em;\"><span style=\"top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mathit mtight\" style=\"margin-right:0.05764em;\">E</span></span></span></span><span class=\"vlist-s\"></span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.15em;\"></span></span></span></span></span><span class=\"mrel\">=</span><span class=\"mop op-symbol small-op\" style=\"margin-right:0.19445em;position:relative;top:-0.0005599999999999772em;\">∮</span><span class=\"mord mathit\" style=\"margin-right:0.05764em;\">E</span><span class=\"mbin\">⋅</span><span class=\"mord mathit\">d</span><span class=\"mord mathit\">A</span></span></span></span></p>",
 | 
			
		||||
      "marked_expected_output": "<p><span class=\"katex\"><span class=\"katex-mathml\"><math><semantics><mrow><msub><mi mathvariant=\"normal\">Φ</mi><mi>E</mi></msub><mo>=</mo><mo>∮</mo><mi>E</mi><mo>⋅</mo><mi>d</mi><mi>A</mi></mrow><annotation encoding=\"application/x-tex\">\\Phi_E = \\oint E \\cdot dA</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"strut\" style=\"height:0.805em;\"></span><span class=\"strut bottom\" style=\"height:1.11112em;vertical-align:-0.30612em;\"></span><span class=\"base\"><span class=\"mord\"><span class=\"mord mathrm\">Φ</span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.32833099999999993em;\"><span style=\"top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mathit mtight\" style=\"margin-right:0.05764em;\">E</span></span></span></span><span class=\"vlist-s\"></span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.15em;\"></span></span></span></span></span><span class=\"mrel\">=</span><span class=\"mop op-symbol small-op\" style=\"margin-right:0.19445em;position:relative;top:-0.0005599999999999772em;\">∮</span><span class=\"mord mathit\" style=\"margin-right:0.05764em;\">E</span><span class=\"mbin\">⋅</span><span class=\"mord mathit\">d</span><span class=\"mord mathit\">A</span></span></span></span></p>"
 | 
			
		||||
      "expected_output": "<p><span class=\"katex\"><span class=\"katex-mathml\"><math><semantics><mrow><msub><mi mathvariant=\"normal\">Φ</mi><mi>E</mi></msub><mo>=</mo><mo>∮</mo><mi>E</mi><mo>⋅</mo><mi>d</mi><mi>A</mi></mrow><annotation encoding=\"application/x-tex\">\\Phi_E = \\oint E \\cdot dA</annotation></semantics></math></span><span aria-hidden=\"true\" class=\"katex-html\"><span class=\"strut\" style=\"height:0.805em;\"></span><span class=\"strut bottom\" style=\"height:1.11112em;vertical-align:-0.30612em;\"></span><span class=\"base\"><span class=\"mord\"><span class=\"mord mathrm\">Φ</span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.32833099999999993em;\"><span style=\"top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mathit mtight\" style=\"margin-right:0.05764em;\">E</span></span></span></span><span class=\"vlist-s\"></span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.15em;\"></span></span></span></span></span><span class=\"mrel\">=</span><span class=\"mop op-symbol small-op\" style=\"margin-right:0.19445em;position:relative;top:-0.0005599999999999772em;\">∮</span><span class=\"mord mathit\" style=\"margin-right:0.05764em;\">E</span><span class=\"mbin\">⋅</span><span class=\"mord mathit\">d</span><span class=\"mord mathit\">A</span></span></span></span></p>"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "tex_escaped",
 | 
			
		||||
@@ -562,14 +563,12 @@
 | 
			
		||||
    {
 | 
			
		||||
      "name": "tex_money",
 | 
			
		||||
      "input": "Tickets are $5 to $20 for youth, $10-$30 for adults, so we are hoping to bring in $500 from the event ($$x \\approx 500\\$$$)",
 | 
			
		||||
      "expected_output": "<p>Tickets are $5 to $20 for youth, $10-$30 for adults, so we are hoping to bring in $500 from the event (<span class=\"katex\"><span class=\"katex-mathml\"><math><semantics><mrow><mi>x</mi><mo>≈</mo><mn>5</mn><mn>0</mn><mn>0</mn><mi mathvariant=\"normal\">$</mi></mrow><annotation encoding=\"application/x-tex\">x \\approx 500\\$</annotation></semantics></math></span><span aria-hidden=\"true\" class=\"katex-html\"><span class=\"strut\" style=\"height:0.75em;\"></span><span class=\"strut bottom\" style=\"height:0.80556em;vertical-align:-0.05556em;\"></span><span class=\"base\"><span class=\"mord mathit\">x</span><span class=\"mrel\">≈</span><span class=\"mord mathrm\">5</span><span class=\"mord mathrm\">0</span><span class=\"mord mathrm\">0</span><span class=\"mord mathrm\">$</span></span></span></span>)</p>",
 | 
			
		||||
      "marked_expected_output": "<p>Tickets are $5 to $20 for youth, $10-$30 for adults, so we are hoping to bring in $500 from the event (<span class=\"katex\"><span class=\"katex-mathml\"><math><semantics><mrow><mi>x</mi><mo>≈</mo><mn>5</mn><mn>0</mn><mn>0</mn><mi mathvariant=\"normal\">$</mi></mrow><annotation encoding=\"application/x-tex\">x \\approx 500\\$</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"strut\" style=\"height:0.75em;\"></span><span class=\"strut bottom\" style=\"height:0.80556em;vertical-align:-0.05556em;\"></span><span class=\"base\"><span class=\"mord mathit\">x</span><span class=\"mrel\">≈</span><span class=\"mord mathrm\">5</span><span class=\"mord mathrm\">0</span><span class=\"mord mathrm\">0</span><span class=\"mord mathrm\">$</span></span></span></span>)</p>"
 | 
			
		||||
      "expected_output": "<p>Tickets are $5 to $20 for youth, $10-$30 for adults, so we are hoping to bring in $500 from the event (<span class=\"katex\"><span class=\"katex-mathml\"><math><semantics><mrow><mi>x</mi><mo>≈</mo><mn>5</mn><mn>0</mn><mn>0</mn><mi mathvariant=\"normal\">$</mi></mrow><annotation encoding=\"application/x-tex\">x \\approx 500\\$</annotation></semantics></math></span><span aria-hidden=\"true\" class=\"katex-html\"><span class=\"strut\" style=\"height:0.75em;\"></span><span class=\"strut bottom\" style=\"height:0.80556em;vertical-align:-0.05556em;\"></span><span class=\"base\"><span class=\"mord mathit\">x</span><span class=\"mrel\">≈</span><span class=\"mord mathrm\">5</span><span class=\"mord mathrm\">0</span><span class=\"mord mathrm\">0</span><span class=\"mord mathrm\">$</span></span></span></span>)</p>"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "tex_inline_permissive_spacing",
 | 
			
		||||
      "input": "$$    x =  7   $$",
 | 
			
		||||
      "expected_output": "<p><span class=\"katex\"><span class=\"katex-mathml\"><math><semantics><mrow><mi>x</mi><mo>=</mo><mn>7</mn></mrow><annotation encoding=\"application/x-tex\">    x =  7   </annotation></semantics></math></span><span aria-hidden=\"true\" class=\"katex-html\"><span class=\"strut\" style=\"height:0.64444em;\"></span><span class=\"strut bottom\" style=\"height:0.64444em;vertical-align:0em;\"></span><span class=\"base\"><span class=\"mord mathit\">x</span><span class=\"mrel\">=</span><span class=\"mord mathrm\">7</span></span></span></span></p>",
 | 
			
		||||
      "marked_expected_output": "<p><span class=\"katex\"><span class=\"katex-mathml\"><math><semantics><mrow><mi>x</mi><mo>=</mo><mn>7</mn></mrow><annotation encoding=\"application/x-tex\">    x =  7   </annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"strut\" style=\"height:0.64444em;\"></span><span class=\"strut bottom\" style=\"height:0.64444em;vertical-align:0em;\"></span><span class=\"base\"><span class=\"mord mathit\">x</span><span class=\"mrel\">=</span><span class=\"mord mathrm\">7</span></span></span></span></p>"
 | 
			
		||||
      "expected_output": "<p><span class=\"katex\"><span class=\"katex-mathml\"><math><semantics><mrow><mi>x</mi><mo>=</mo><mn>7</mn></mrow><annotation encoding=\"application/x-tex\">    x =  7   </annotation></semantics></math></span><span aria-hidden=\"true\" class=\"katex-html\"><span class=\"strut\" style=\"height:0.64444em;\"></span><span class=\"strut bottom\" style=\"height:0.64444em;vertical-align:0em;\"></span><span class=\"base\"><span class=\"mord mathit\">x</span><span class=\"mrel\">=</span><span class=\"mord mathrm\">7</span></span></span></span></p>"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "tex_inline_prohibited_newline",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user