Jhsmit commited on
Commit
1e69bd6
·
1 Parent(s): e8aa909

feat: monkey-patch mhchem

Browse files
Files changed (3) hide show
  1. app.py +4 -0
  2. mh_chem_markdown.py +156 -0
  3. monomer_dimer.ipynb +1 -2
app.py CHANGED
@@ -3,6 +3,10 @@ from pathlib import Path
3
  import solara
4
  from solara.website.components.notebook import Notebook
5
 
 
 
 
 
6
 
7
  @solara.component
8
  def Page():
 
3
  import solara
4
  from solara.website.components.notebook import Notebook
5
 
6
+ from mh_chem_markdown import _markdown_template
7
+
8
+ solara.components.markdown._markdown_template = _markdown_template
9
+
10
 
11
  @solara.component
12
  def Page():
mh_chem_markdown.py ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def _markdown_template(
2
+ html,
3
+ style="",
4
+ ):
5
+ template = (
6
+ """
7
+ <template>
8
+ <div class="solara-markdown rendered_html jp-RenderedHTMLCommon" style=\""""
9
+ + style
10
+ + """\">"""
11
+ + html
12
+ + r"""</div>
13
+ </template>
14
+
15
+ <script>
16
+ module.exports = {
17
+ async mounted() {
18
+ await this.loadRequire();
19
+ this.mermaid = await this.loadMermaid();
20
+ this.mermaid.init();
21
+ await this.loadMHchem();
22
+ this.latexSettings = {
23
+ delimiters: [
24
+ {left: "$$", right: "$$", display: true},
25
+ {left: "$", right: "$", display: false},
26
+ {left: "\\[", right: "\\]", display: true},
27
+ {left: "\\(", right: "\\)", display: false}
28
+ ]
29
+ };
30
+ if (window.renderMathInElement) {
31
+ window.renderMathInElement(this.$el, this.latexSettings);
32
+ } else if (window.MathJax && MathJax.Hub) {
33
+ MathJax.Hub.Queue(['Typeset', MathJax.Hub, this.$el]);
34
+ } else {
35
+ window.renderMathInElement = await this.loadKatexExt();
36
+ window.renderMathInElement(this.$el, this.latexSettings);
37
+ }
38
+ this.$el.querySelectorAll("a").forEach(a => this.setupRouter(a))
39
+ window.md = this.$el
40
+ },
41
+ methods: {
42
+ setupRouter(a) {
43
+ let href = a.attributes['href'].value;
44
+ if(href.startsWith("./")) {
45
+ // TODO: should we really do this?
46
+ href = location.pathname + href.substr(1);
47
+ a.attributes['href'].href = href;
48
+ }
49
+ if(href.startsWith("./") || href.startsWith("/")) {
50
+ a.onclick = e => {
51
+ console.log("clicked", href)
52
+ if(href.startsWith("./")) {
53
+ solara.router.push(href);
54
+ } else {
55
+ solara.router.push(href);
56
+ }
57
+ e.preventDefault()
58
+ }
59
+ } else if(href.startsWith("#")) {
60
+ href = location.pathname + href;
61
+ a.attributes['href'].value = href;
62
+ } else {
63
+ console.log("href", href, "is not a local link")
64
+ }
65
+ },
66
+ async loadKatex() {
67
+ require.config({
68
+ map: {
69
+ '*': {
70
+ 'katex': `${this.getCdn()}/[email protected]/dist/katex.min.js`,
71
+ }
72
+ }
73
+ });
74
+ const link = document.createElement('link');
75
+ link.type = "text/css";
76
+ link.rel = "stylesheet";
77
+ link.href = `${this.getCdn()}/[email protected]/dist/katex.min.css`;
78
+ document.head.appendChild(link);
79
+ },
80
+ async loadKatexExt() {
81
+ this.loadKatex();
82
+ return (await this.import([`${this.getCdn()}/[email protected]/dist/contrib/auto-render.min.js`]))[0]
83
+ },
84
+ async loadMermaid() {
85
+ return (await this.import([`${this.getCdn()}/[email protected]/dist/mermaid.min.js`]))[0]
86
+ },
87
+ async loadMHchem() {
88
+ await this.loadKatex();
89
+ return (await this.import([`${this.getCdn()}/[email protected]/dist/contrib/mhchem.min.js`]))[0];
90
+ },
91
+
92
+ import(dependencies) {
93
+ return this.loadRequire().then(
94
+ () => {
95
+ if (window.jupyterVue) {
96
+ // in jupyterlab, we take Vue from ipyvue/jupyterVue
97
+ define("vue", [], () => window.jupyterVue.Vue);
98
+ } else {
99
+ define("vue", ['jupyter-vue'], jupyterVue => jupyterVue.Vue);
100
+ }
101
+ return new Promise((resolve, reject) => {
102
+ requirejs(dependencies, (...modules) => resolve(modules));
103
+ })
104
+ }
105
+ );
106
+ },
107
+ loadRequire() {
108
+ if (window.requirejs) {
109
+ return Promise.resolve();
110
+ }
111
+ return new Promise((resolve, reject) => {
112
+ const script = document.createElement('script');
113
+ script.src = `${this.getCdn()}/[email protected]/require.min.js`;
114
+ script.onload = resolve;
115
+ script.onerror = reject;
116
+ document.head.appendChild(script);
117
+ });
118
+ },
119
+ getBaseUrl() {
120
+ if (window.solara && window.solara.rootPath !== undefined) {
121
+ return solara.rootPath + "/";
122
+ }
123
+ // if base url is set, we use ./ for relative paths compared to the base url
124
+ if (document.getElementsByTagName("base").length) {
125
+ return "./";
126
+ }
127
+ const labConfigData = document.getElementById('jupyter-config-data');
128
+ if (labConfigData) {
129
+ /* lab and Voila */
130
+ return JSON.parse(labConfigData.textContent).baseUrl;
131
+ }
132
+ let base = document.body.dataset.baseUrl || document.baseURI;
133
+ if (!base.endsWith('/')) {
134
+ base += '/';
135
+ }
136
+ return base
137
+ },
138
+ getCdn() {
139
+ return this.cdn || (typeof solara_cdn !== "undefined" && solara_cdn) || `${this.getBaseUrl()}_solara/cdn`;
140
+ }
141
+ },
142
+ updated() {
143
+ // if the html gets update, re-run mermaid
144
+ this.mermaid.init();
145
+
146
+ if(window.MathJax && MathJax.Hub) {
147
+ MathJax.Hub.Queue(['Typeset', MathJax.Hub, this.$el]);
148
+ } else {
149
+ window.renderMathInElement(this.$el, this.latexSettings);
150
+ }
151
+ }
152
+ }
153
+ </script>
154
+ """
155
+ )
156
+ return template
monomer_dimer.ipynb CHANGED
@@ -18,10 +18,9 @@
18
  "## Monomer - Dimer kinetics\n",
19
  "\n",
20
  "Lets start with the simple example of dimer formation from two identical protomers:\n",
21
- "(TODO: mhchem package)\n",
22
  "\n",
23
  "$$\n",
24
- "P_1 + P_1 <-> P_2\n",
25
  "$$\n",
26
  "\n",
27
  "From the kinetic scheme above, we can write down the differential equations describing this system. These differential equations tell us how the concentrations of the reaction (in this case dimerization) change in time. \n",
 
18
  "## Monomer - Dimer kinetics\n",
19
  "\n",
20
  "Lets start with the simple example of dimer formation from two identical protomers:\n",
 
21
  "\n",
22
  "$$\n",
23
+ "\\ce{P1 + P1 <=>[k_{on}][k_{off}] P2}\n",
24
  "$$\n",
25
  "\n",
26
  "From the kinetic scheme above, we can write down the differential equations describing this system. These differential equations tell us how the concentrations of the reaction (in this case dimerization) change in time. \n",