Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
1eb3a47c
Commit
1eb3a47c
authored
Jan 04, 2021
by
Justin Boyson
Committed by
Olena Horal-Koretska
Jan 04, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support LaTeX in jupyter notebooks
Add MathJax package as well
parent
8635c0cd
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
139 additions
and
14 deletions
+139
-14
app/assets/javascripts/notebook/cells/output/index.vue
app/assets/javascripts/notebook/cells/output/index.vue
+5
-0
app/assets/javascripts/notebook/cells/output/latex.vue
app/assets/javascripts/notebook/cells/output/latex.vue
+45
-0
changelogs/unreleased/jdb-juptyer-notebooks-latex-support.yml
...gelogs/unreleased/jdb-juptyer-notebooks-latex-support.yml
+5
-0
package.json
package.json
+1
-0
spec/frontend/notebook/cells/output/index_spec.js
spec/frontend/notebook/cells/output/index_spec.js
+33
-9
spec/frontend/notebook/cells/output/latex_spec.js
spec/frontend/notebook/cells/output/latex_spec.js
+40
-0
yarn.lock
yarn.lock
+10
-5
No files found.
app/assets/javascripts/notebook/cells/output/index.vue
View file @
1eb3a47c
...
...
@@ -2,6 +2,7 @@
import
CodeOutput
from
'
../code/index.vue
'
;
import
HtmlOutput
from
'
./html.vue
'
;
import
ImageOutput
from
'
./image.vue
'
;
import
LatexOutput
from
'
./latex.vue
'
;
export
default
{
props
:
{
...
...
@@ -35,6 +36,8 @@ export default {
return
'
image/jpeg
'
;
}
else
if
(
output
.
data
[
'
text/html
'
])
{
return
'
text/html
'
;
}
else
if
(
output
.
data
[
'
text/latex
'
])
{
return
'
text/latex
'
;
}
else
if
(
output
.
data
[
'
image/svg+xml
'
])
{
return
'
image/svg+xml
'
;
}
...
...
@@ -59,6 +62,8 @@ export default {
return
ImageOutput
;
}
else
if
(
output
.
data
[
'
text/html
'
])
{
return
HtmlOutput
;
}
else
if
(
output
.
data
[
'
text/latex
'
])
{
return
LatexOutput
;
}
else
if
(
output
.
data
[
'
image/svg+xml
'
])
{
return
HtmlOutput
;
}
...
...
app/assets/javascripts/notebook/cells/output/latex.vue
0 → 100644
View file @
1eb3a47c
<
script
>
import
'
mathjax/es5/tex-svg
'
;
import
Prompt
from
'
../prompt.vue
'
;
export
default
{
name
:
'
LatexOutput
'
,
components
:
{
Prompt
,
},
props
:
{
count
:
{
type
:
Number
,
required
:
true
,
},
rawCode
:
{
type
:
String
,
required
:
true
,
},
index
:
{
type
:
Number
,
required
:
true
,
},
},
computed
:
{
code
()
{
// MathJax will not parse out the inline delimeters "$$" correctly
// so we remove them from the raw code itself
const
parsedCode
=
this
.
rawCode
.
replace
(
/
\$\$
/g
,
''
);
const
svg
=
window
.
MathJax
.
tex2svg
(
parsedCode
);
// NOTE: This is used with `v-html` and not `v-safe-html` due to an
// issue with dompurify stripping out xlink attributes from use tags
return
svg
.
outerHTML
;
},
},
};
</
script
>
<
template
>
<div
class=
"output"
>
<prompt
type=
"Out"
:count=
"count"
:show-output=
"index === 0"
/>
<!-- eslint-disable -->
<div
ref=
"maths"
v-html=
"code"
></div>
</div>
</
template
>
changelogs/unreleased/jdb-juptyer-notebooks-latex-support.yml
0 → 100644
View file @
1eb3a47c
---
title
:
Add LaTeX support for Jupyter Notebooks
merge_request
:
49497
author
:
type
:
fixed
package.json
View file @
1eb3a47c
...
...
@@ -108,6 +108,7 @@
"
katex
"
:
"
^0.10.0
"
,
"
lodash
"
:
"
^4.17.20
"
,
"
marked
"
:
"
^0.3.12
"
,
"
mathjax
"
:
"
3
"
,
"
mermaid
"
:
"
^8.5.2
"
,
"
mersenne-twister
"
:
"
1.1.0
"
,
"
minimatch
"
:
"
^3.0.4
"
,
...
...
spec/frontend/notebook/cells/output/index_spec.js
View file @
1eb3a47c
...
...
@@ -18,12 +18,14 @@ describe('Output component', () => {
};
beforeEach
(()
=>
{
// This is the output after rendering a jupyter notebook
json
=
getJSONFixture
(
'
blob/notebook/basic.json
'
);
});
describe
(
'
text output
'
,
()
=>
{
beforeEach
((
done
)
=>
{
createComponent
(
json
.
cells
[
2
].
outputs
[
0
]);
const
textType
=
json
.
cells
[
2
];
createComponent
(
textType
.
outputs
[
0
]);
setImmediate
(()
=>
{
done
();
...
...
@@ -41,7 +43,8 @@ describe('Output component', () => {
describe
(
'
image output
'
,
()
=>
{
beforeEach
((
done
)
=>
{
createComponent
(
json
.
cells
[
3
].
outputs
[
0
]);
const
imageType
=
json
.
cells
[
3
];
createComponent
(
imageType
.
outputs
[
0
]);
setImmediate
(()
=>
{
done
();
...
...
@@ -55,23 +58,42 @@ describe('Output component', () => {
describe
(
'
html output
'
,
()
=>
{
it
(
'
renders raw HTML
'
,
()
=>
{
createComponent
(
json
.
cells
[
4
].
outputs
[
0
]);
const
htmlType
=
json
.
cells
[
4
];
createComponent
(
htmlType
.
outputs
[
0
]);
expect
(
vm
.
$el
.
querySelector
(
'
p
'
)).
not
.
toBeNull
();
expect
(
vm
.
$el
.
querySelectorAll
(
'
p
'
)
.
length
).
toBe
(
1
);
expect
(
vm
.
$el
.
querySelectorAll
(
'
p
'
)
).
toHaveLength
(
1
);
expect
(
vm
.
$el
.
textContent
.
trim
()).
toContain
(
'
test
'
);
});
it
(
'
renders multiple raw HTML outputs
'
,
()
=>
{
createComponent
([
json
.
cells
[
4
].
outputs
[
0
],
json
.
cells
[
4
].
outputs
[
0
]]);
const
htmlType
=
json
.
cells
[
4
];
createComponent
([
htmlType
.
outputs
[
0
],
htmlType
.
outputs
[
0
]]);
expect
(
vm
.
$el
.
querySelectorAll
(
'
p
'
).
length
).
toBe
(
2
);
expect
(
vm
.
$el
.
querySelectorAll
(
'
p
'
)).
toHaveLength
(
2
);
});
});
describe
(
'
LaTeX output
'
,
()
=>
{
it
(
'
renders LaTeX
'
,
()
=>
{
const
output
=
{
data
:
{
'
text/latex
'
:
[
'
$$F(k) =
\\
int_{-
\\
infty}^{
\\
infty} f(x) e^{2
\\
pi i k} dx$$
'
],
'
text/plain
'
:
[
'
<IPython.core.display.Latex object>
'
],
},
metadata
:
{},
output_type
:
'
display_data
'
,
};
createComponent
(
output
);
expect
(
vm
.
$el
.
querySelector
(
'
.MathJax
'
)).
not
.
toBeNull
();
});
});
describe
(
'
svg output
'
,
()
=>
{
beforeEach
((
done
)
=>
{
createComponent
(
json
.
cells
[
5
].
outputs
[
0
]);
const
svgType
=
json
.
cells
[
5
];
createComponent
(
svgType
.
outputs
[
0
]);
setImmediate
(()
=>
{
done
();
...
...
@@ -85,7 +107,8 @@ describe('Output component', () => {
describe
(
'
default to plain text
'
,
()
=>
{
beforeEach
((
done
)
=>
{
createComponent
(
json
.
cells
[
6
].
outputs
[
0
]);
const
unknownType
=
json
.
cells
[
6
];
createComponent
(
unknownType
.
outputs
[
0
]);
setImmediate
(()
=>
{
done
();
...
...
@@ -102,7 +125,8 @@ describe('Output component', () => {
});
it
(
"
renders as plain text when doesn't recognise other types
"
,
(
done
)
=>
{
createComponent
(
json
.
cells
[
7
].
outputs
[
0
]);
const
unknownType
=
json
.
cells
[
7
];
createComponent
(
unknownType
.
outputs
[
0
]);
setImmediate
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
pre
'
)).
not
.
toBeNull
();
...
...
spec/frontend/notebook/cells/output/latex_spec.js
0 → 100644
View file @
1eb3a47c
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
LatexOutput
from
'
~/notebook/cells/output/latex.vue
'
;
import
Prompt
from
'
~/notebook/cells/prompt.vue
'
;
describe
(
'
LaTeX output cell
'
,
()
=>
{
beforeEach
(()
=>
{
window
.
MathJax
=
{
tex2svg
:
jest
.
fn
((
code
)
=>
({
outerHTML
:
code
})),
};
});
const
inlineLatex
=
'
$$F(k) =
\\
int_{-
\\
infty}^{
\\
infty} f(x) e^{2
\\
pi i k} dx$$
'
;
const
count
=
12345
;
const
createComponent
=
(
rawCode
,
index
)
=>
shallowMount
(
LatexOutput
,
{
propsData
:
{
count
,
index
,
rawCode
,
},
});
it
.
each
`
index | expectation
${
0
}
|
${
true
}
${
1
}
|
${
false
}
`
(
'
sets `Prompt.show-output` to $expectation when index is $index
'
,
({
index
,
expectation
})
=>
{
const
wrapper
=
createComponent
(
inlineLatex
,
index
);
const
prompt
=
wrapper
.
find
(
Prompt
);
expect
(
prompt
.
props
().
count
).
toEqual
(
count
);
expect
(
prompt
.
props
().
showOutput
).
toEqual
(
expectation
);
});
it
(
'
strips the `$$` delimter from LaTeX
'
,
()
=>
{
createComponent
(
inlineLatex
,
0
);
expect
(
window
.
MathJax
.
tex2svg
).
toHaveBeenCalledWith
(
expect
.
not
.
stringContaining
(
'
$$
'
));
});
});
yarn.lock
View file @
1eb3a47c
...
...
@@ -3057,7 +3057,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
dependencies:
delayed-stream "~1.0.0"
commander@2, commander@^2.10.0, commander@^2.1
6.0, commander@^2.1
8.0, commander@^2.19.0, commander@^2.20.0, commander@~2.20.0:
commander@2, commander@^2.10.0, commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@~2.20.0:
version "2.20.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
...
...
@@ -7476,11 +7476,11 @@ karma@^4.2.0:
useragent "2.3.0"
katex@^0.10.0:
version "0.10.
0
"
resolved "https://registry.yarnpkg.com/katex/-/katex-0.10.
0.tgz#da562e5d0d5cc3aa602e27af8a9b8710bfbce765
"
integrity sha512-
/WRvx+L1eVBrLwX7QzKU1dQuaGnE7E8hDvx3VWfZh9HbMiCfsKWJNnYZ0S8ZMDAfAyDSofdyXIrH/hujF1fYXg
==
version "0.10.
2
"
resolved "https://registry.yarnpkg.com/katex/-/katex-0.10.
2.tgz#39973edbb65eda5b6f9e7f41648781e557dd4932
"
integrity sha512-
cQOmyIRoMloCoSIOZ1+gEwsksdJZ1EW4SWm3QzxSza/QsnZr6D4U1V9S4q+B/OLm2OQ8TCBecQ8MaIfnScI7cw
==
dependencies:
commander "^2.1
6
.0"
commander "^2.1
9
.0"
keyv@^3.0.0:
version "3.1.0"
...
...
@@ -8054,6 +8054,11 @@ marked@^0.3.12, marked@~0.3.6:
resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.19.tgz#5d47f709c4c9fc3c216b6d46127280f40b39d790"
integrity sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==
mathjax@3:
version "3.1.2"
resolved "https://registry.yarnpkg.com/mathjax/-/mathjax-3.1.2.tgz#95c0d45ce2330ef7b6a815cebe7d61ecc26bbabd"
integrity sha512-BojKspBv4nNWzO1wC6VEI+g9gHDOhkaGHGgLxXkasdU4pwjdO5AXD5M/wcLPkXYPjZ/N+6sU8rjQTlyvN2cWiQ==
mathml-tag-names@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.1.tgz#6dff66c99d55ecf739ca53c492e626f1d12a33cc"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment