Skip to content

Commit b5733a9

Browse files
committed
added offline python to js conversion.
1 parent 3500af9 commit b5733a9

File tree

3 files changed

+145
-54
lines changed

3 files changed

+145
-54
lines changed

batch_convert.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import argparse
2+
import os
3+
import subprocess
4+
5+
def convert_file(input_path, output_path):
6+
"""Converts a single Python file to an HTML snippet."""
7+
try:
8+
converter_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'convert.js')
9+
result = subprocess.run(
10+
['node', converter_path, input_path],
11+
capture_output=True,
12+
text=True,
13+
check=True
14+
)
15+
with open(output_path, 'w') as f:
16+
f.write(result.stdout)
17+
print(f"Successfully converted {input_path} to {output_path}")
18+
except subprocess.CalledProcessError as e:
19+
print(f"Error converting {input_path}: {e.stderr}")
20+
except Exception as e:
21+
print(f"An error occurred: {e}")
22+
23+
def main():
24+
parser = argparse.ArgumentParser(description="Convert Python files to HTML snippets.")
25+
parser.add_argument("input_dir", help="The input directory containing Python files.")
26+
parser.add_argument("output_dir", help="The output directory for the HTML files.")
27+
args = parser.parse_args()
28+
29+
if not os.path.isdir(args.input_dir):
30+
print(f"Error: Input directory not found at {args.input_dir}")
31+
return
32+
33+
if not os.path.exists(args.output_dir):
34+
os.makedirs(args.output_dir)
35+
36+
for filename in os.listdir(args.input_dir):
37+
if filename.endswith(".py"):
38+
input_path = os.path.join(args.input_dir, filename)
39+
output_filename = os.path.splitext(filename)[0] + ".html"
40+
output_path = os.path.join(args.output_dir, output_filename)
41+
convert_file(input_path, output_path)
42+
43+
if __name__ == "__main__":
44+
main()

convert.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
2+
const fs = require('fs');
3+
4+
/*
5+
** Stand alone nodejs script to compile a GlowScript program and output the HTML
6+
*/
7+
8+
global.window = {}
9+
global.RS = require('./package/RScompiler.3.2.min.js')
10+
global.RapydScript = RS.RapydScript; // script assumes RapydScript is gobal for some reason
11+
//debugger;
12+
13+
function inlineHTML(source) {
14+
// This function is used to inline the source code in the HTML
15+
// It replaces newlines with <br> and escapes double quotes
16+
// source = "Web VPython 3.2\n\n\nball=sphere()"
17+
18+
var header = {
19+
"version": "3.2",
20+
"lang": "vpython",
21+
"nodictionary": false,
22+
"source": source,
23+
"ok": "3.2",
24+
"unpackaged": false,
25+
"isCurrent": true
26+
}
27+
28+
var embedHTML = '' // Will be an ampty string if there is a compile error
29+
var embedScript = window.glowscript_compile(header.source,
30+
{lang: header.lang, version: header.version.substr(0,3),
31+
run: false, nodictionary: header.nodictionary})
32+
// console.log('ide 1343', embedScript)
33+
var divid = "glowscript"
34+
var main
35+
var v = Number(header.version.substr(0,3))
36+
if (v >= 2.9) main = '__main__()' // Starting August 2019, no longer using Streamine
37+
var remove = header.version==='0.3' ? '' : '.removeAttr("id")'
38+
39+
embedScript = ";(function() {" + embedScript + '\n;$(function(){ window.__context = { glowscript_container: $("#' + divid + '")'+remove+' }; '+main+' })})()'
40+
embedScript = embedScript.replace("</", "<\/") // escape anything that could be a close script tag... hopefully this sequence only occurs in strings!
41+
var verdir = "bef1.1"
42+
if (v == 1.1) verdir = "1.1"
43+
else if (v >= 2.2) verdir = "2.1"
44+
else verdir = header.version.substr(0,3)
45+
var runner = ''
46+
var exporturl = "https://www.glowscript.org/"
47+
if (v >= 2.5 && v < 3.0) exporturl = "https://s3.amazonaws.com/glowscript/"
48+
// Note: some already exported 3.0 programs contain references to s3.amazonaws.com
49+
if (header.lang == 'vpython')
50+
runner = '<script type="text/javascript" src="'+exporturl+'package/RSrun.' + header.version + '.min.js"></script>\n'
51+
embedHTML = ( // embedHTML is a var introduced above to make it easy for downloadHTML
52+
'<div id="' + divid + '" class="glowscript">\n' +
53+
'<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n' +
54+
'<link type="text/css" href="'+exporturl+'css/redmond/' + verdir + '/jquery-ui.custom.css" rel="stylesheet" />\n' +
55+
'<link type="text/css" href="'+exporturl+'css/ide.css" rel="stylesheet" />\n' +
56+
'<script type="text/javascript" src="'+exporturl+'lib/jquery/' + verdir + '/jquery.min.js"></script>\n' +
57+
'<script type="text/javascript" src="'+exporturl+'lib/jquery/' + verdir + '/jquery-ui.custom.min.js"></script>\n' +
58+
'<script type="text/javascript" src="'+exporturl+'package/glow.' + header.version + '.min.js"></script>\n' +
59+
runner +
60+
'<script type="text/javascript"><!--//--><![CDATA[//><!--\n\n// START JAVASCRIPT\n' +
61+
embedScript + '\n// END JAVASCRIPT\n' +
62+
'\n//--><!]]></script>' +
63+
'\n</div>');
64+
65+
return embedHTML
66+
}
67+
68+
function doCheck(source) {
69+
// This function checks the source code and returns an object with the result
70+
var result = {ok: true, message: '', html: ''};
71+
try {
72+
var html = inlineHTML(source);
73+
result.html = html;
74+
} catch (e) {
75+
result.ok = false;
76+
result.message = e.message;
77+
}
78+
return result;
79+
}
80+
81+
const filePath = process.argv[2];
82+
if (!filePath) {
83+
console.error('Usage: node convert.js <path_to_python_file>');
84+
process.exit(1);
85+
}
86+
87+
fs.readFile(filePath, 'utf8', (err, source) => {
88+
if (err) {
89+
console.error(`Error reading file: ${err}`);
90+
process.exit(1);
91+
}
92+
93+
const result = doCheck(source);
94+
95+
if (result.ok) {
96+
console.log(result.html);
97+
} else {
98+
console.error(result.message);
99+
process.exit(1);
100+
}
101+
});

examples/doCheck.js

Lines changed: 0 additions & 54 deletions
This file was deleted.

0 commit comments

Comments
 (0)