Search in sources :

Example 1 with ExecutableCodeDef

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);
                    }
                }
            }
        }
    }
}
Also used : ST(org.stringtemplate.v4.ST) STGroup(org.stringtemplate.v4.STGroup) ArrayList(java.util.ArrayList) BookishParser(us.parr.bookish.parse.BookishParser) PyFigDef(us.parr.bookish.model.entity.PyFigDef) MultiMap(org.antlr.v4.runtime.misc.MultiMap) ExecutableCodeDef(us.parr.bookish.model.entity.ExecutableCodeDef) STGroupFile(org.stringtemplate.v4.STGroupFile) File(java.io.File) STGroupFile(org.stringtemplate.v4.STGroupFile)

Aggregations

File (java.io.File)1 ArrayList (java.util.ArrayList)1 MultiMap (org.antlr.v4.runtime.misc.MultiMap)1 ST (org.stringtemplate.v4.ST)1 STGroup (org.stringtemplate.v4.STGroup)1 STGroupFile (org.stringtemplate.v4.STGroupFile)1 ExecutableCodeDef (us.parr.bookish.model.entity.ExecutableCodeDef)1 PyFigDef (us.parr.bookish.model.entity.PyFigDef)1 BookishParser (us.parr.bookish.parse.BookishParser)1