How: latex > python > django-rest > js mathjax > html

hello there!

I’m trying to make a interactive engineering mechanics book using django and sphinx. I have set up an api which triggers the generation of some formulas in latex code.

For example:

\begin{table}
\caption{Point loads}
\label{F-loads}
\begin{tabular}{|c|c|c|}
\toprule
\midrule
$F_{x0}$ & {:0,2f} & N \\
$F_{y0}$ & {:0,2f} & N \\
\bottomrule
\end{tabular}
\end{table}

now what I’m doing now is adding this (and other latex code) to a python dict.
which results in:

{'pointloads': '\\begin{table}\n\\caption{Point loads}\n\\label{F-loads}\n\\begin{tabular}{|c|c|c|}\n\\toprule\n\\midrule\n$F_{x0}$ & {:0,2f} & N \\\\\n$F_{y0}$ & {:0,2f} & N \\\\\n\\bottomrule\n\\end{tabular}\n\\end{table}\n'}

I do understand why all these backlashes and enter notations arise. But this is problematic since its not readable latex code for mathjax anymore.

now I send this from the back-end to the front end using django-rest:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .serializers import DatasetSerializer

from solver.model import solver_js

class DatasetAPIView(APIView):
    def post(self, request):
        serializer = DatasetSerializer(data=request.data)
        if serializer.is_valid():
            dataset = serializer.validated_data

            # Call a function to perform random alterations
            altered_dataset = alter_dataset(dataset)

            return Response(altered_dataset, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

def alter_dataset(dataset):

    altered_dataset = solver_js.main(dataset)
    # if result dictionary has a key 'error', return the error message
    return altered_dataset

and then paste it ob my website using javascript:

function apicall () {
    const dataset = modelClicker;

    fetch('/api/', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(dataset),
    })
      .then(response => response.json())
      .then(data => {
        if (data.message && data.message.error) {
            // An error occurred, display the error message
            alert(data.message.error);
          } else {
            // No error, display the regular message (if any)
            if (data.message.info !== null) {
                console.log('info:',data.message.info);
            }
            if (data.message.warning !== null) {
                console.log('warning:',data.message.warning);
            }
            // remove hidden container solutionCard
            // Select the element with the id "solutionCard"
            const solutionCard = document.getElementById('solutionCard');

            // Remove the 'hidden' attribute
            solutionCard.removeAttribute('hidden');

            console.log('data:',data);

            // Extract the altered dataset from the response
            const alteredDataset = data.sympy;

            // Update the "solutionBody" div with the altered dataset
            document.getElementById('solutionBody').textContent = JSON.stringify(alteredDataset, null, 2);
          }
      })
      .catch(error => {
        console.error('Error:', error);
      });
  };

now after some django templating i’m currently just putting the code on my website as text:

{ "pointloads": "\\begin{table}\n\\caption{Point loads}\n\\label{F-loads}\n\\begin{tabular}{|c|c|c|}\n\\toprule\n\\midrule\n$F_{x0}$ & {:0,2f} & N \\\\\n$F_{y0}$ & {:0,2f} & N \\\\\n\\bottomrule\n\\end{tabular}\n\\end{table}\n" }

However what I would like to do is use mathjax to render the latex code on my web page for each key/value pair in the dict. Unfortunately because the code is ‘sanitized’ i’m left with a lot of unwanted backslashes (\) and enter signs (\n). My question is, what is a best practice to do such I thing ? I guess this kind of problem should be something that is very general when working with dictionaries. However I have problems wrapping my head around finding the correct approach to tackle this problem. I’ve tried looking in converting the latex to json rather than a python dict, which did not work. I’ve also tried to fiddle around with bleach and nh3 to find a solution but nothing seemed to be fitting.

Thank you in advance.

To clarify the scope, this is the current dict that is returned in the complete api call for a small engineering mechanics exersize:

{ "variables": { "NL": "Gebruikte variabelen:", "EN": "Used variables:", "DE": "Verwendete Variablen:", "ES": "Variables usadas:" }, "reactions": "\\begin{table}\n\\caption{Reaction loads}\n\\label{R-loads}\n\\begin{tabular}{|c|c|c|}\n\\toprule\n\\midrule\n$M_{r2}$ & - & Nm \\\\\n$R_{x0}$ & - & N \\\\\n$R_{y1}$ & - & N \\\\\n\\bottomrule\n\\end{tabular}\n\\end{table}\n", "lengths": "\\begin{table}\n\\caption{Lengths}\n\\label{Lengths}\n\\begin{tabular}{|c|c|c|}\n\\toprule\n\\midrule\n$L_{x0}$ & {:0,2f} & m \\\\\n$L_{x2y}$ & {:0,2f} & m \\\\\n$L_{y0}$ & {:0,2f} & m \\\\\n$L_{y2x}$ & {:0,2f} & m \\\\\n$W_{x2y}$ & {:0,2f} & m \\\\\n$W_{y2x}$ & {:0,2f} & m \\\\\n\\bottomrule\n\\end{tabular}\n\\end{table}\n", "distributions": "\\begin{table}\n\\caption{Distributed load}\n\\label{q-loads}\n\\begin{tabular}{|c|c|c|}\n\\toprule\n\\midrule\n$q_{2x}$ & {:0,2f} & N/m \\\\\n$q_{2y}$ & {:0,2f} & N/m \\\\\n\\bottomrule\n\\end{tabular}\n\\end{table}\n", "pointloads": "\\begin{table}\n\\caption{Point loads}\n\\label{F-loads}\n\\begin{tabular}{|c|c|c|}\n\\toprule\n\\midrule\n$F_{x0}$ & {:0,2f} & N \\\\\n$F_{y0}$ & {:0,2f} & N \\\\\n\\bottomrule\n\\end{tabular}\n\\end{table}\n", "moments": "\\begin{table}\n\\caption{Moments}\n\\label{M-loads}\n\\begin{tabular}{|c|c|c|}\n\\toprule\n\\midrule\n$M_{1}$ & {:0,2f} & Nm \\\\\n\\bottomrule\n\\end{tabular}\n\\end{table}\n", "base_equations": { "NL": "Vergelijkingen zoals overgenomen uit VLS:", "EN": "Equations as copied from VLS:", "DE": "Gleichungen wie aus VLS kopiert:", "ES": "Ecuaciones como copiadas de VLS:" }, "Sfx0": "\\sum F_{x} = 0 \\rightarrow 0 = R_{x0}- F_{x0}+ q_{2x}\\cdot W_{y2x}", "Sfy0": "\\sum F_{y} = 0 \\rightarrow 0 = R_{y1}- F_{y0}+ q_{2y}\\cdot W_{x2y}", "SM0": "\\sum M_{[0.0, 0.0]} = 0 \\rightarrow 0 = M_{r2}+ F_{x0}\\cdot L_{y0}- F_{y0}\\cdot L_{x0}+ M_{1}-( q_{2x}\\cdot W_{y2x})\\cdot L_{y2x}+( q_{2y}\\cdot W_{x2y})\\cdot L_{x2y}", "simplified_equations": { "NL": "Wiskundige versimpeling van vergelijkingen:", "EN": "Mathematical simplification of equations:", "DE": "Mathematische Vereinfachung von Gleichungen:", "ES": "Simplificación matemática de ecuaciones:" }, "Sfx0_simp": "\\sum F_{x} = 0 \\rightarrow 0 = - F_{x0} + R_{x0} + W_{y2x} \\cdot q_{2x}", "Sfy0_simp": "\\sum F_{y} = 0 \\rightarrow 0 = - F_{y0} + R_{y1} + W_{x2y} \\cdot q_{2y}", "SM0_simp": "\\sum M_{[0.0, 0.0]} = 0 \\rightarrow 0 = F_{x0} \\cdot L_{y0} - F_{y0} \\cdot L_{x0} + L_{x2y} \\cdot W_{x2y} \\cdot q_{2y} - L_{y2x} \\cdot W_{y2x} \\cdot q_{2x} + M_{1} + M_{r2}", "Fx_text1": { "NL": "Vergelijking oplossen voor lrachten in x-richting:", "EN": "Solving equation for forces in x-direction:", "DE": "Gleichung lösen für Kräfte in x-Richtung:", "ES": "Resolviendo ecuación para fuerzas en dirección x:" }, "Fx_eq1": "0 = - F_{x0} + R_{x0} + W_{y2x} \\cdot q_{2x}", "Fx_text2": { "NL": "We vullen de bekende waarden in in de vergelijking:", "EN": "We fill in the known values in the equation:", "DE": "Wir füllen die bekannten Werte in die Gleichung ein:", "ES": "Rellenamos los valores conocidos en la ecuación:" }, "Fx_eq2": "0 = - 1.0 + R_{x0} + 0.5 \\cdot 10.0", "Fx_text3": { "NL": "We isoleren de onbekende \\(R_{x0}\\) in de vergelijking.", "EN": "We isolate the unknown \\(R_{x0}\\) in the equation.", "DE": "Wir isolieren die unbekannte \\(R_{x0}\\) in der Gleichung.", "ES": "Aislamos la desconocida \\(R_{x0}\\) en la ecuación." }, "Fx_eq3": "R_{x0} = F_{x0} - W_{y2x} \\cdot q_{2x}", "Fx_text4": { "NL": "We vullen de bekende waarden in in de vergelijking.", "EN": "We fill in the known values in the equation.", "DE": "Wir füllen die bekannten Werte in die Gleichung ein.", "ES": "Rellenamos los valores conocidos en la ecuación." }, "Fx_eq4": "R_{x0} = 1.0 - 0.5 \\cdot 10.0", "Fx_text5": { "NL": "De oplossing is:", "EN": "The solution is:", "DE": "Die Lösung ist:", "ES": "La solución es:" }, "Fx_eq5": "R_{x0}=-4.0 N", "r-loads": "\\begin{table}\n\\caption{Reaction loads}\n\\label{R-loads}\n\\begin{tabular}{|c|c|c|}\n\\toprule\n\\midrule\n$M_{r2}$ & -7.00000000000000 & Nm \\\\\n$R_{x0}$ & -4.00000000000000 & N \\\\\n$R_{y1}$ & -4.00000000000000 & N \\\\\n\\bottomrule\n\\end{tabular}\n\\end{table}\n", "Fx_text6": { "NL": "Update van variabelen:", "EN": "Update of variables:", "DE": "Aktualisierung der Variablen:", "ES": "Actualización de variables:" }, "Fy_text1": { "NL": "Vergelijking oplossen voor lrachten in y-richting:", "EN": "Solving equation for forces in y-direction:", "DE": "Gleichung lösen für Kräfte in y-Richtung:", "ES": "Resolviendo ecuación para fuerzas en dirección y:" }, "Fy_eq1": "0 = - F_{y0} + R_{y1} + W_{x2y} \\cdot q_{2y}", "Fy_text2": { "NL": "We vullen de bekende waarden in in de vergelijking:", "EN": "We fill in the known values in the equation:", "DE": "Wir füllen die bekannten Werte in die Gleichung ein:", "ES": "Rellenamos los valores conocidos en la ecuación:" }, "Fy_eq2": "0 = - 1.0 + R_{y1} + 0.5 \\cdot 10.0", "Fy_text3": { "NL": "We isoleren de onbekende \\(R_{y1}\\) in de vergelijking.", "EN": "We isolate the unknown \\(R_{y1}\\) in the equation.", "DE": "Wir isolieren die unbekannte \\(R_{y1}\\) in der Gleichung.", "ES": "Aislamos la desconocida \\(R_{y1}\\) en la ecuación." }, "Fy_eq3": "R_{y1} = F_{y0} - W_{x2y} \\cdot q_{2y}", "Fy_text4": { "NL": "We vullen de bekende waarden in in de vergelijking.", "EN": "We fill in the known values in the equation.", "DE": "Wir füllen die bekannten Werte in die Gleichung ein.", "ES": "Rellenamos los valores conocidos en la ecuación." }, "Fy_eq4": "R_{y1} = 1.0 - 0.5 \\cdot 10.0", "Fy_text5": { "NL": "De oplossing is:", "EN": "The solution is:", "DE": "Die Lösung ist:", "ES": "La solución es:" }, "Fy_eq5": "R_{y1}=-4.0 N", "Fy_text6": { "NL": "Update van variabelen:", "EN": "Update of variables:", "DE": "Aktualisierung der Variablen:", "ES": "Actualización de variables:" }, "M_text1": { "NL": "Vergelijking oplossen voor momenten:", "EN": "Solving equation for moments:", "DE": "Gleichung lösen für Momente:", "ES": "Resolviendo ecuación para momentos:" }, "M_eq1": "0 = F_{x0} \\cdot L_{y0} - F_{y0} \\cdot L_{x0} + L_{x2y} \\cdot W_{x2y} \\cdot q_{2y} - L_{y2x} \\cdot W_{y2x} \\cdot q_{2x} + M_{1} + M_{r2}", "M_text2": { "NL": "We vullen de bekende waarden in in de vergelijking:", "EN": "We fill in the known values in the equation:", "DE": "Wir füllen die bekannten Werte in die Gleichung ein:", "ES": "Rellenamos los valores conocidos en la ecuación:" }, "M_eq2": "0 = 1.0 \\cdot 0.5 - 1.0 \\cdot 0.5 + 1.5 \\cdot 0.5 \\cdot 10.0 - 0.5 \\cdot 0.5 \\cdot 10.0 + 2.0 + M_{r2}", "M_text3": { "NL": "We isoleren de onbekende \\(M_{r2}\\) in de vergelijking.", "EN": "We isolate the unknown \\(M_{r2}\\) in the equation.", "DE": "Wir isolieren die unbekannte \\(M_{r2}\\) in der Gleichung.", "ES": "Aislamos la desconocida \\(M_{r2}\\) en la ecuación." }, "M_eq3": "M_{r2} = - F_{x0} \\cdot L_{y0} + F_{y0} \\cdot L_{x0} - L_{x2y} \\cdot W_{x2y} \\cdot q_{2y} + L_{y2x} \\cdot W_{y2x} \\cdot q_{2x} - M_{1}", "M_text4": { "NL": "We vullen de bekende waarden in in de vergelijking.", "EN": "We fill in the known values in the equation.", "DE": "Wir füllen die bekannten Werte in die Gleichung ein.", "ES": "Rellenamos los valores conocidos en la ecuación." }, "M_eq4": "M_{r2} = - 1.0 \\cdot 0.5 + 1.0 \\cdot 0.5 - 1.5 \\cdot 0.5 \\cdot 10.0 + 0.5 \\cdot 0.5 \\cdot 10.0 - 2.0", "M_text5": { "NL": "De oplossing is:", "EN": "The solution is:", "DE": "Die Lösung ist:", "ES": "La solución es:" }, "M_eq5": "M_{r2}=-7.0 Nm", "M_text6": { "NL": "Update van variabelen:", "EN": "Update of variables:", "DE": "Aktualisierung der Variablen:", "ES": "Actualización de variables:" } }

You can use raw multiline strings to help with making the code more readable.

raw = “” \begin{table}
\caption{Point loads}
“””

Beware that when printing python strings if you use repr a single \ in the stribg is doubled up. But it is still a single \ in the actual string.

1 Like

Hi there Barry,

Thank you for the reply! I will try that!

Do the multiple backslashes that indicate a single backslash also translate to JavaScript? And does that also hold for code indentation?

Thank you!

Do you mean does JavaScript also double up \ in its code for strings? Yes.
If you are sending the data to JavaScript using JSON then the json module will handle this for you.

1 Like

Ah that is good to know thank you! I did not know that!