use of us.parr.bookish.model.entity.ExecutableCodeDef in project bookish by parrt.
the class Tool method executeCodeSnippets.
/**
* generate python files to execute \pyfig, \pyeval blocks
*/
public void executeCodeSnippets(Book book, String buildDir, List<List<ExecutableCodeDef>> codeBlocks) {
String snippetsDir = buildDir + "/snippets";
// combine list of code snippets for each label into file
STGroup pycodeTemplates = new STGroupFile("templates/pyeval.stg");
for (int i = 0; i < book.filenames.size(); i++) {
// for each chapter
List<ExecutableCodeDef> codeDefs = codeBlocks.get(i);
if (codeDefs.size() == 0) {
continue;
}
String basename = stripFileExtension(codeDefs.get(0).inputFilename);
// prepare directories
String chapterSnippetsDir = snippetsDir + "/" + basename;
ParrtIO.mkdir(chapterSnippetsDir);
ParrtIO.mkdir(outputDir + "/images/" + basename);
// every chapter snippets dir gets a data link to book data directory
if (!new File(chapterSnippetsDir + "/data").exists()) {
execCommandLine("ln -s " + dataDir + " " + chapterSnippetsDir + "/data");
}
// get mapping from label (or index if no label) to list of snippets
MultiMap<String, ExecutableCodeDef> labelToDefs = new MultiMap<>();
List<String> labels = new ArrayList<>();
for (ExecutableCodeDef codeDef : codeDefs) {
// for each code blob
String label = codeDef.label != null ? codeDef.label : String.valueOf(codeDef.index);
if (!labels.contains(label))
labels.add(label);
labelToDefs.map(label, codeDef);
}
// track snippet label order
for (String label : labels) {
// for each group of code with same label
List<ExecutableCodeDef> defs = labelToDefs.get(label);
String snippetFilename = basename + "_" + label + ".py";
List<ST> snippets = new ArrayList<>();
for (ExecutableCodeDef def : defs) {
String tname = def.isOutputVisible ? "pyeval" : "pyfig";
ST snippet = pycodeTemplates.getInstanceOf(tname);
snippet.add("def", def);
// Don't allow "plt.show()" to execute, strip it
String code = null;
if (def.code != null) {
code = def.code.replace("plt.show()", "");
}
if (code != null && code.trim().length() == 0) {
code = null;
}
snippet.add("code", code);
snippets.add(snippet);
}
ST file = pycodeTemplates.getInstanceOf("pyfile");
file.add("snippets", snippets);
file.add("buildDir", buildDir);
file.add("outputDir", outputDir);
// file.add("imagesDir", inputDir+"/images");
file.add("basename", basename);
file.add("label", label);
String pycode = file.render();
String snippetHashFilename = chapterSnippetsDir + "/" + basename + "_" + label + "-" + md5hash(pycode) + ".hash";
if (!Files.exists(Paths.get(snippetHashFilename))) {
System.err.println("BUILDING " + snippetFilename);
// save empty hash marker file
ParrtIO.save(snippetHashFilename, "");
ParrtIO.save(chapterSnippetsDir + "/" + snippetFilename, pycode);
// EXEC!
String[] result = ParrtSys.execInDir(chapterSnippetsDir, "pythonw", snippetFilename);
if (result[1] != null && result[1].length() > 0) {
// errors during python compilation not running
System.err.println(result[1]);
}
}
for (ExecutableCodeDef def : defs) {
String stderr = ParrtIO.load(chapterSnippetsDir + "/" + basename + "_" + label + "_" + def.index + ".err");
if (def instanceof PyFigDef) {
((PyFigDef) def).generatedFilenameNoSuffix = outputDir + "/images/" + basename + "/" + basename + "_" + label + "_" + def.index;
}
if (stderr.trim().length() > 0) {
System.err.println(stderr);
}
if (def.isOutputVisible) {
if (def.tree instanceof BookishParser.PyevalContext) {
BookishParser.PyevalContext tree = (BookishParser.PyevalContext) def.tree;
tree.stdout = ParrtIO.load(chapterSnippetsDir + "/" + basename + "_" + label + "_" + def.index + ".out");
tree.stderr = stderr.trim();
if (tree.stdout.length() == 0)
tree.stdout = null;
if (tree.stderr.length() == 0)
tree.stderr = null;
// System.out.println("stderr: "+stderr);
if (def.displayExpr != null) {
String dataFilename = basename + "_" + label + "_" + def.index + ".csv";
tree.displayData = ParrtIO.load(chapterSnippetsDir + "/" + dataFilename);
// System.out.println("data: "+tree.displayData);
}
} else {
BookishParser.Inline_pyevalContext tree = (BookishParser.Inline_pyevalContext) def.tree;
tree.stdout = ParrtIO.load(chapterSnippetsDir + "/" + basename + "_" + label + "_" + def.index + ".out");
tree.stderr = stderr.trim();
if (tree.stdout.length() == 0)
tree.stdout = null;
if (tree.stderr.length() == 0)
tree.stderr = null;
String dataFilename = basename + "_" + label + "_" + def.index + ".csv";
tree.displayData = ParrtIO.load(chapterSnippetsDir + "/" + dataFilename);
}
}
}
}
}
}
Aggregations