Skip to content

Commit

Permalink
Upgrade to MathJax v3 (#7076)
Browse files Browse the repository at this point in the history
- Switch from bundling MathJax files to using npm
- Needed to create new webpack entrypoint for Jupyter notebook inclusion
of MathJax
- Fix preview of markdown/MathJax in annotations for annotation
categories view and dropdown menus in grading view
  • Loading branch information
david-yz-liu authored May 15, 2024
1 parent 7c5a14f commit 36dc406
Show file tree
Hide file tree
Showing 1,327 changed files with 120 additions and 235,957 deletions.
3 changes: 3 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@

### 🐛 Bug fixes

- Ensure annotation previews are rendered on annotations page and in annotation category dropdown menus when grading (#7073)

### 🔧 Internal changes

- Fixed login_spec.rb flaky test on GitHub Actions run (#6966)
- Minor improvements in assignment association options (#6989)
- Update changelog and pull request template formats (#7041)
- Upgrade to MathJax version 3, with packaging from npm (#7073)

## [v2.4.10]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class AnnotationTextDisplayer {
// Show the displayer
show() {
this.display_node.style.display = "block";
MathJax.Hub.Queue(["Typeset", MathJax.Hub, this.display_node]);
MathJax.typeset([this.display_node]);
}

// Set the parent element of the display node
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export class AnnotationManager extends React.Component {
componentDidUpdate() {
this.props.categories.forEach(cat => {
new DropDownMenu($(`#annotation_category_${cat.id}`), $(`#annotation_text_list_${cat.id}`));
MathJax.typeset([`#annotation_text_list_${cat.id}`]);
});
}

Expand Down Expand Up @@ -37,7 +38,10 @@ export class AnnotationManager extends React.Component {
onMouseDown={e => e.preventDefault()}
title={text.content}
>
<span className={"text-content"}>{text.content.slice(0, 70)}</span>
<span
className={"text-content"}
dangerouslySetInnerHTML={{__html: safe_marked(text.content).slice(0, 70)}}
/>
<span className={"red-text"}>
{!text.deduction ? "" : "-" + text.deduction}
</span>
Expand Down
4 changes: 2 additions & 2 deletions app/assets/javascripts/Components/Result/annotation_table.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,11 @@ export class AnnotationTable extends React.Component {
};

componentDidMount() {
MathJax.Hub.Queue(["Typeset", MathJax.Hub, "annotation_table"]);
MathJax.typeset(["#annotation_table"]);
}

componentDidUpdate() {
MathJax.Hub.Queue(["Typeset", MathJax.Hub, "annotation_table"]);
MathJax.typeset(["#annotation_table"]);
}

render() {
Expand Down
6 changes: 3 additions & 3 deletions app/assets/javascripts/Components/Result/remark_panel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ export class RemarkPanel extends React.Component {
const comment = this.props.overallComment;
let target_id = "overall_remark_comment";
document.getElementById(target_id).innerHTML = safe_marked(comment);
MathJax.Hub.Queue(["Typeset", MathJax.Hub, target_id]);
MathJax.typeset([`#${target_id}`]);
}

if (this.props.remarkSubmitted) {
const target_id = "remark_request_text";
document.getElementById(target_id).innerHTML = safe_marked(this.props.remarkRequestText);
MathJax.Hub.Queue(["Typeset", MathJax.Hub, "submitted_remark_request_text"]);
MathJax.typeset(["#submitted_remark_request_text"]);
}
}

Expand Down Expand Up @@ -124,7 +124,7 @@ class RemarkRequestForm extends React.Component {
renderPreview = () => {
let target_id = "remark-request-preview";
document.getElementById(target_id).innerHTML = safe_marked(this.state.value);
MathJax.Hub.Queue(["Typeset", MathJax.Hub, target_id]);
MathJax.typeset([`#${target_id}`]);
};

updateValue = event => {
Expand Down
3 changes: 0 additions & 3 deletions app/assets/javascripts/Components/Result/result.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,6 @@ class Result extends React.Component {
if (typeof window.annotation_manager.hide_selection_box === "function") {
window.annotation_manager.hide_selection_box();
}
reloadDOM();
};

addExistingAnnotation = annotation_text_id => {
Expand Down Expand Up @@ -508,7 +507,6 @@ class Result extends React.Component {
if (typeof window.annotation_manager.hide_selection_box === "function") {
window.annotation_manager.hide_selection_box();
}
reloadDOM();
};

/**
Expand Down Expand Up @@ -540,7 +538,6 @@ class Result extends React.Component {
if (typeof annotation_manager.hide_selection_box === "function") {
annotation_manager.hide_selection_box();
}
reloadDOM();
// Need to remove data attribute from highlight elements - must be last.
$("span").removeAttr(`data-annotationid${annotation_id}`);
}
Expand Down
4 changes: 2 additions & 2 deletions app/assets/javascripts/Components/markdown_preview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import PropTypes from "prop-types";

export default class MarkdownPreview extends React.Component {
componentDidMount = () => {
const target_id = "annotation_preview";
MathJax.Hub.Queue(["Typeset", MathJax.Hub, target_id]);
const target_id = "#annotation-preview";
MathJax.typeset([target_id]);
};

render() {
Expand Down
38 changes: 25 additions & 13 deletions app/assets/javascripts/Components/one_time_annotations_table.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,23 @@ class OneTimeAnnotationsTable extends React.Component {
}
})
.then(res => {
this.setState({
data: res,
loading: false,
});
this.setState(
{
data: res,
},
// A separate setState call seems to be required to get the MathJax.typeset
// call in componentDidUpdate to correctly transform the annotation texts.
() => this.setState({loading: false})
);
});
};

componentDidUpdate(_prevProps, prevState) {
if (prevState.loading && !this.state.loading) {
MathJax.typeset(["#one_time_annotations_table_wrapper"]);
}
}

editAnnotation = (annot_id, content) => {
$.ajax({
url: Routes.update_annotation_text_course_assignment_annotation_categories_path(
Expand Down Expand Up @@ -137,15 +147,17 @@ class OneTimeAnnotationsTable extends React.Component {

render() {
return (
<ReactTable
key="one_time_annotations_table"
data={this.state.data}
columns={this.columns}
filterable
defaultSorted={[{id: "group_name"}]}
loading={this.state.loading}
noDataText={I18n.t("annotations.empty_uncategorized")}
/>
<div id="one_time_annotations_table_wrapper">
<ReactTable
key="one_time_annotations_table"
data={this.state.data}
columns={this.columns}
filterable
defaultSorted={[{id: "group_name"}]}
loading={this.state.loading}
noDataText={I18n.t("annotations.empty_uncategorized")}
/>
</div>
);
}
}
Expand Down
35 changes: 0 additions & 35 deletions app/assets/javascripts/MathJax/mathjax_helpers.js

This file was deleted.

1 change: 0 additions & 1 deletion app/assets/javascripts/mathjax.js

This file was deleted.

5 changes: 5 additions & 0 deletions app/assets/stylesheets/common/_markus.scss
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,11 @@ ul.tags {
}
}
}

&.annotation_category p {
margin-bottom: 0.1em;
margin-top: 0.1em;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions app/javascript/application_webpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//
// To reference this file, add <%= javascript_include_tag 'application_webpack' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb
import "mathjax/es5/tex-svg";

// jquery (should be the first to be loaded, as many other libs depend on it)
import $ from "jquery/src/jquery";
Expand Down
9 changes: 9 additions & 0 deletions app/javascript/markus_notebook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* eslint no-console:0 */
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
//
// To reference this file, add <%= javascript_include_tag 'markus_notebook' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb
import "mathjax/es5/tex-svg";
3 changes: 0 additions & 3 deletions app/views/annotation_categories/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
<%= render partial: 'boot',
formats: [:js],
handlers: [:erb] %>
<%= render partial: 'layouts/mathjax_config' %>
<%= javascript_include_tag 'MathJax_lib/MathJax.js?config=TeX-AMS-MML_HTMLorMML', nonce: true %>
<%= javascript_include_tag 'MathJax/mathjax_helpers', nonce: true %>
<%= javascript_tag nonce: true do %>
document.addEventListener("DOMContentLoaded", function() {
$('#add-annotation-category').click(function(e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ $('#annotation_category_' + <%= @annotation_category.id %>).replaceWith(
"<%= escape_javascript(render partial: 'annotation_category',
locals: { annotation_category: @annotation_category }).html_safe %>");

reloadDOM();
MathJax.typeset(['#annotation_text_<%= @text[:id] %>']);
3 changes: 2 additions & 1 deletion app/views/annotation_categories/show.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ $('#annotation_list_holder').replaceWith(
"<%= escape_javascript(render partial: 'annotation_list',
locals: { annotation_texts: @annotation_texts,
annotation_category: @annotation_category }).html_safe %>");
reloadDOM();

MathJax.typeset(['#annotation_list_holder']);
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
$('#annotation_list_holder').replaceWith(
"<%= escape_javascript(render partial: 'uncategorized_annotations_list',
locals: { texts: @texts }).html_safe %>");
reloadDOM();
makeOneTimeAnnotationsTable(
document.getElementById('one_time_annotations_table'),
{
course_id: <%= @current_course.id %>,
assignment_id: <%= @assignment.id %>
}
);
MathJax.typeset(['#one_time_annotations_table'])
5 changes: 3 additions & 2 deletions app/views/annotation_categories/update_annotation_text.js.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
$('#annotation_text_' + <%= @text['id'] %>).replaceWith(
let target_id = '#annotation_text_' + <%= @text['id'] %>;
$(target_id).replaceWith(
"<%= escape_javascript(render partial: 'annotation_text',
locals: { annotation_text: @text }).html_safe %>");
reloadDOM();
MathJax.typeset([target_id]);
1 change: 0 additions & 1 deletion app/views/automated_tests/student_interface.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<% content_for :title, t('automated_tests.title') %>
<%= stylesheet_link_tag 'result_main' %>
<%= stylesheet_link_tag 'result' %>
<%= javascript_include_tag 'mathjax', nonce: true %>
<%= javascript_include_tag 'result', nonce: true %>
<%= javascript_include_tag 'Results/main', nonce: true %>
Expand Down
3 changes: 3 additions & 0 deletions app/views/layouts/_head.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
<%= javascript_tag nonce: true do %>
const MARKUS_VERSION = '<%= Rails.configuration.markus_version %>';
<% end %>
<%= javascript_tag nonce: true do %>
<%= render partial: 'layouts/mathjax_config', formats: :js %>
<% end %>
17 changes: 0 additions & 17 deletions app/views/layouts/_mathjax_config.html.erb

This file was deleted.

21 changes: 21 additions & 0 deletions app/views/layouts/_mathjax_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
window.MathJax = {
startup: {
typeset: false,
},
tex: {
// Allow inline single dollar sign notation
inlineMath: [
["$", "$"],
["\\(", "\\)"],
],
processEnvironments: true,
processRefs: false,
},
options: {
ignoreHtmlClass: "tex2jax_ignore",
processHtmlClass: "tex2jax_process",
},
svg: {
fontCache: "global",
},
};
31 changes: 19 additions & 12 deletions app/views/layouts/notebook.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,30 @@
<% end %>
<%= javascript_include_tag 'require', nonce: true %>
<%= javascript_tag nonce: true do %>
// Same as mathjax_config.js except skipStartupTypeset is false
// Same as mathjax_config.js except startup.typeset is true
window.MathJax = {
root: '<%= File.dirname(asset_path 'MathJax_lib/MathJax') %>',
messageStyle: 'none',
skipStartupTypeset: false,
ShowMathMenu: false,
tex2jax: {
inlineMath: [['$', '$'], ['\\(', '\\)']],
preview: 'none',
startup: {
typeset: true
},
tex: {
// Allow inline single dollar sign notation
inlineMath: [
["$", "$"],
["\\(", "\\)"]
],
processEnvironments: true,
processRefs: false,
processRefs: false
},
jax: ["input/TeX", "input/MathML", "input/AsciiMath", "output/CommonHTML"],
extensions: ['tex2jax.js'],
options: {
ignoreHtmlClass: "tex2jax_ignore",
processHtmlClass: "tex2jax_process"
},
svg: {
fontCache: "global"
}
};
<% end %>
<%= javascript_include_tag 'MathJax_lib/MathJax', nonce: true %>
<%= javascript_include_tag 'markus_notebook', nonce: true %>
<%= javascript_include_tag 'plotly', nonce: true %>
<% end %>
</head>
Expand Down
2 changes: 0 additions & 2 deletions app/views/layouts/result_content.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
<% unless session[:auth_type] == 'remote'%>
<%= javascript_include_tag 'check_timeout', nonce: true %>
<% end %>
<%= render partial: 'layouts/mathjax_config' %>
<%= javascript_include_tag 'MathJax_lib/MathJax', nonce: true %>
<%= render partial: 'layouts/jsroutes_config' %>
<%= render partial: 'layouts/i18n_config' %>
<%= yield :head %>
Expand Down
1 change: 0 additions & 1 deletion app/views/results/edit.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<% content_for :head do %>
<%= stylesheet_link_tag 'result_main' %>
<%= stylesheet_link_tag 'result' %>
<%= javascript_include_tag 'mathjax', nonce: true %>
<%= javascript_include_tag 'result', nonce: true %>
<%= javascript_include_tag 'Results/main', nonce: true %>
<%= javascript_tag nonce: true do %>
Expand Down
Loading

0 comments on commit 36dc406

Please sign in to comment.