Skip to content

Commit

Permalink
resolves #9 use source lines in dynamic blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
ggrossetie committed Sep 14, 2023
1 parent 995dae6 commit ae5a548
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 4 deletions.
123 changes: 122 additions & 1 deletion spec/dynamic-notebook.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ print('hello')
`
const registry = asciidoctor.Extensions.create()
dynamicNotebookExt.register(registry)
const doc = asciidoctor.load(input, {extension_registry: registry})
const doc = asciidoctor.load(input, { extension_registry: registry })
const html = doc.convert()
expect(html).to.equal(`<div class="listingblock">
<div class="content">
Expand Down Expand Up @@ -159,5 +159,126 @@ for fig in figs:
const blocksCount = Array.from(html.matchAll(/<div id="[^"]+" class="plotly-graph-div" .*<\/script>/gm), (m) => m[0]).length
expect(blocksCount).to.eq(2)
})
it('should not substitute < and > characters in Python code', () => {
const input = `
:dynamic-blocks:
[%dynamic,python]
----
x = 15
if x < 10:
print("x is less than 10")
elif x < 20:
print("x is between 10 and 20")
else:
print("x is 20 or greater")
----`
const registry = asciidoctor.Extensions.create()
dynamicNotebookExt.register(registry)
const doc = asciidoctor.load(input, { extension_registry: registry })
const html = doc.convert()
expect(html).to.eq(`<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-python" data-lang="python">x = 15
if x &lt; 10:
print("x is less than 10")
elif x &lt; 20:
print("x is between 10 and 20")
else:
print("x is 20 or greater")</code></pre>
</div>
</div>
<details>
<summary class="title">Results</summary>
<div class="content">
<div class="literalblock dynamic-py-result">
<div class="content">
<pre>x is between 10 and 20</pre>
</div>
</div>
</div>
</details>`)
})
it('should ignore callout in Python code', () => {
const input = `
:dynamic-blocks:
[%dynamic,python]
----
x12 = 1/8
long_name = "A String" <1>
import cmath <2>
# Complex number handling
result = cmath.sqrt(-1) - 1j <3>
import math
x = math.sqrt(2)
value = math.sin(x) / x
print(f"value={value}") <4>
# The next command will display the result
x = math.cos(math.pi); print(f"x={x}") <5>
----
<.> Strings in Python are typically enclosed in double quotes \`"\` or single quotes \`'\`.
<.> Python's standard library \`math\` provides most of the mathematical functions. But for complex numbers, you would use the \`cmath\` module.
<.> For complex numbers, Python uses \`j\` instead of \`i\`.
<.> use \`print\` to display the result of a command in a script. In the interactive interpreter, the result is displayed by default. use \`f\` to format the output.
<.> In Python, there is no need to use \`;\` at the end of a statement unless you want to put multiple statements on a single line.`
const registry = asciidoctor.Extensions.create()
dynamicNotebookExt.register(registry)
const doc = asciidoctor.load(input, { extension_registry: registry })
const html = doc.convert()
expect(html).to.eq(`<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-python" data-lang="python">x12 = 1/8
long_name = "A String" <b class="conum">(1)</b>
import cmath <b class="conum">(2)</b>
# Complex number handling
result = cmath.sqrt(-1) - 1j <b class="conum">(3)</b>
import math
x = math.sqrt(2)
value = math.sin(x) / x
print(f"value={value}") <b class="conum">(4)</b>
# The next command will display the result
x = math.cos(math.pi); print(f"x={x}") <b class="conum">(5)</b></code></pre>
</div>
</div>
<details>
<summary class="title">Results</summary>
<div class="content">
<div class="literalblock dynamic-py-result">
<div class="content">
<pre>value=0.6984559986366083
x=-1.0</pre>
</div>
</div>
</div>
</details>
<div class="colist arabic">
<ol>
<li>
<p>Strings in Python are typically enclosed in double quotes <code>"</code> or single quotes <code>'</code>.</p>
</li>
<li>
<p>Python&#8217;s standard library <code>math</code> provides most of the mathematical functions. But for complex numbers, you would use the <code>cmath</code> module.</p>
</li>
<li>
<p>For complex numbers, Python uses <code>j</code> instead of <code>i</code>.</p>
</li>
<li>
<p>use <code>print</code> to display the result of a command in a script. In the interactive interpreter, the result is displayed by default. use <code>f</code> to format the output.</p>
</li>
<li>
<p>In Python, there is no need to use <code>;</code> at the end of a statement unless you want to put multiple statements on a single line.</p>
</li>
</ol>
</div>`)
})
})
})
7 changes: 4 additions & 3 deletions src/dynamic-notebook-processor.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ const child_process = require('node:child_process')
const fs = require('node:fs')
const ospath = require('node:path')

const conumRx = /\s*<i class="conum" data-value="[0-9]+"><\/i><b>[^>]+<\/b>/g
//const conumRx = /\s*<i class="conum" data-value="[0-9]+"><\/i><b>[^>]+<\/b>/g
const calloutRx = /\s+<(?:[0-9]+|\.)>/g
const figShowRx = /fig.show\(\)/g
const plotterShowRx = /plotter.show\(\)/g
const pyvistaContainerRx = /^var container = document\.querySelector\('.content'\);$/m
Expand Down Expand Up @@ -77,8 +78,8 @@ module.exports.register = function register(registry) {
.filter((b) => b.getAttribute('language') === 'python' && b.isOption('dynamic'))
if (blocks && blocks.length > 0 && doc.getAttribute('dynamic-blocks') !== undefined) {
const ipython = ipythonTemplate(blocks.map((b) => {
const code = b.getContent()
.replaceAll(conumRx, '')
const code = b.getSourceLines().join('\n')
.replaceAll(calloutRx, '')
.replaceAll(figShowRx, `import sys; fig.write_html(file=sys.stdout, include_plotlyjs=False)`)
.replaceAll(plotterShowRx, `import sys; sys.stdout.write(plotter.export_html(None).getvalue())`)
return JSON.stringify(code)
Expand Down

0 comments on commit ae5a548

Please sign in to comment.