Hi I am new to Julia and want to
write latex code like here
md""" Here's some inline maths: $\sqrt[n]{1 + x + x^2 + \ldots}$.
Here's an equation:
$\frac{n!}{k!(n - k)!} = \binom{n}{k}$
This is the binomial coefficient.
"""
Maybe, you have some conflict between PlutoUtils and Pluto, or some other package. The workaround developed by @disberd works immaculately for me. Try inserting these three lines of code into your Pluto notebook:
s(x) = HypertextLiteral.JavaScript(x)
"""
`texeq(code::String)`
Take an input string and renders it inside an equation environemnt (numbered) using KaTeX
Equations can be given labels by adding `"\\\\label{name}"` inside the `code` string and subsequently referenced in other cells using `eqref("name")`
# Note
Unfortunately backward slashes have to be doubled when creating the TeX code to be put inside the equation
When Pluto will support interpretation of string literal macros, this could be made into a macro
"""
function texeq(code,env="equation")
code_escaped = code |>
x -> replace(x,"\\" => "\\\\") |>
x -> replace(x,"\n" => " ")
println(code_escaped)
@htl """
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.min.css" integrity="sha384-Um5gpz1odJg5Z4HAmzPtgZKdTBHZdw8S29IecapCSB31ligYPhHQZMIlWLYQGVoc" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.min.js" integrity="sha384-YNHdsYkH6gMx9y3mRkmcJ2mFUjTd0qNQQvY9VYZgQd7DcN7env35GzlmFaZ23JGp" crossorigin="anonymous"></script>
<script>
katex.render('\\\\begin{$(js(env))} $(js(code_escaped)) \\\\end{$(js(env))}',currentScript.parentElement,{
displayMode: true,
trust: context => [
'\\\\htmlId',
'\\\\href'
].includes(context.command),
macros: {
"\\\\label": "\\\\htmlId{#1}{}"
},
})
</script>
"""
end
"""
`eqref(label::String)`
Function that create an hyperlink pointing to a previously defined labelled equation using `texeq()`
"""
eqref(label) = @htl """
<a eq_id="$label" id="eqref_$label" href="#$label" class="eq_href">(?)</a>
"""
It should work. I am on a Windows 10 machine, using Julia 1.7.0 and Pluto 0.17.3.
@ga72kud, sorry, but in the copy+past exercise, I forgot to include a fourth block with code. As @disberd mentions, you can use his notebook that deals with the texeq function (the notebook has been recently updated). Or, you can open an entirely new notebook and insert the three code blocks I mentioned above, plus the fourth one below (all of them written by @disberd). The only package required for the notebook to run is HypertextLiteral.jl. Many thanks to disberd for this indispensable functionality inside Pluto notebooks, available nowhere else.
It works in a brand new notebook, Windows 10, Julia 1.7.0, Pluto 0.17.3.
The fourth code block that should be inserted into notebook is:
@htl """
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.min.css" integrity="sha384-Um5gpz1odJg5Z4HAmzPtgZKdTBHZdw8S29IecapCSB31ligYPhHQZMIlWLYQGVoc" crossorigin="anonymous">
<style>
a.eq_href {
text-decoration: none;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.min.js" integrity="sha384-YNHdsYkH6gMx9y3mRkmcJ2mFUjTd0qNQQvY9VYZgQd7DcN7env35GzlmFaZ23JGp" crossorigin="anonymous"></script>
<script id="katex-eqnum-script">
const a_vec = [] // This will hold the list of a tags with custom click, used for cleaning listeners up upon invalidation
const eqrefClick = (e) => {
e.preventDefault() // This prevent normal scrolling to link
const a = e.target
const eq_id = a.getAttribute('eq_id')
window.location.hash = 'eqref-' + eq_id // This is to be able to use the back function to resume previous view, 'eqref-' is added in front to avoid the viewport actually going to the equation without having control of the scroll
const eq = document.getElementById(eq_id)
eq.scrollIntoView({
behavior: 'smooth',
block: 'center',
})
}
const checkCounter = (item, i) => {
return item.classList.contains('enclosing') ?
i :
i + 1
}
const updateCallback = () => {
a_vec.splice(0,a_vec.length) // Reset the array
const eqs = document.querySelectorAll('span.enclosing, span.eqn-num')
let i = 0;
eqs.forEach(item => {
i = checkCounter(item,i)
console.log('item',i,'=',item)
if (item.classList.contains('enclosing')) {
const id = item.id
const a_vals = document.querySelectorAll(`[eq_id=\${id}]`)
a_vals !== null && a_vals.forEach(a => {
a_vec.push(a) // Add this to the vector
a.innerText = `(\${i+1})`
a.addEventListener('click',eqrefClick)
})
}
})
}
const notebook = document.querySelector("pluto-notebook")
// We have a mutationobserver for each cell:
const observers = {
current: [],
}
const createCellObservers = () => {
observers.current.forEach((o) => o.disconnect())
observers.current = Array.from(notebook.querySelectorAll("pluto-cell")).map(el => {
const o = new MutationObserver(updateCallback)
o.observe(el, {attributeFilter: ["class"]})
return o
})
}
createCellObservers()
// And one for the notebook's child list, which updates our cell observers:
const notebookObserver = new MutationObserver(() => {
updateCallback()
createCellObservers()
})
notebookObserver.observe(notebook, {childList: true})
invalidation.then(() => {
notebookObserver.disconnect()
observers.current.forEach((o) => o.disconnect())
a_vec.forEach(a => a.removeEventListener('click',eqrefClick))
})
</script>
"""