1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
#pragma once
#include <string>
#include <mutex>
#include "tree.hh"
#include "nlohmann/json.hpp"
namespace cadabra {
/// \ingroup files
///
/// DataCells are the basic building blocks for a document. They
/// represent visual units in the notebook interface. They
/// are stored in a tree inside the client, and can be transmitted
/// over the wire between server and client in JSON format (see the
/// documentation of the cadabra::JSON_serialise and cadabra::JSON_deserialise
/// methods below for details on this representation). The notebook
/// user interface reads these cells and construct corresponding
/// graphical output for them.
///
/// The cadabra.display method of the cadabra python library knows
/// how to turn various Python objects into the corresponding JSON
/// representation of a DataCell.
class DataCell {
public:
/// Cells are labelled with the data type of its contents, which is
/// stored in a textural representation but may need processing for
/// proper display.
enum class CellType {
document, ///< head node, only one per document
python, ///< input : editor cell for code in python
latex, ///< input : editor cell for code in latex
output, ///< output: cell showing python stdout, verbatim
verbatim, ///< output: cell showing other verbatim output
latex_view, ///< output: cell showing LaTeX text formatted using LaTeX
input_form, ///< output: cell containing input form of preceding output cell
image_png, ///< output: cell showing a base64 encoded PNG image
error, ///< output: cell showing LaTeX text for errors
// section
};
/// Each cell is identified by a serial number 'id' which is used
/// to keep track of it across network calls, and a bool indicating
/// whether the client or the server has created this cell.
class id_t {
public:
id_t();
uint64_t id;
bool created_by_client;
bool operator<(const id_t& other) const;
};
/// Standard constructor, generates a new unique id for this DataCell.
DataCell(CellType t=CellType::python, const std::string& str="", bool hidden=false);
/// Initialise a cell with an already determined id (it is the caller's responsibility
/// to ensure that this id does not clash with any other DataCell's id).
DataCell(id_t, CellType t=CellType::python, const std::string& str="", bool hidden=false);
/// Copy constructor; preserves all information including id.
DataCell(const DataCell&);
CellType cell_type;
/// Textual representation of the cell content. For e.g. latex cells it is a bit of a
/// waste to store this representation both in the input and in the output cell.
/// However, this gives us the flexibility to do manipulations on the input (e.g.
/// resolving equation references) before feeding it to LaTeX.
std::string textbuf;
/// Flag indicating whether this cell should be hidden from
/// view. The GUI should have a way to bring the cells back
/// into view, typically by clicking on the output cell
/// corresponding to the input cell.
bool hidden;
bool sensitive;
/// Flag indicating whether this cell should be ignored in case the
/// notebook is imported. Essentially the equivalent of `if __name__=="__main__"`.
bool ignore_on_import;
/// Indicator whether this cell is currently being evaluated by the server.
/// Currently only has a meaning for cells of type 'python'.
/// This flag is set/reset using the ActionSetRunStatus action.
bool running;
id_t id() const;
private:
id_t serial_number;
};
typedef tree<DataCell> DTree;
/// Serialise a document into .cj format, which is a JSON version of
/// the document tree.
std::string JSON_serialise(const DTree&);
void JSON_recurse(const DTree&, DTree::iterator, nlohmann::json&);
/// Load a document from .cnb format, i.e. the inverse of the above.
void JSON_deserialise(const std::string&, DTree&);
void JSON_in_recurse(DTree& doc, DTree::iterator loc, const nlohmann::json& cells);
/// Export a document to a single self-contained HTML file containing inline CSS.
std::string export_as_HTML(const DTree& doc, bool for_embedding=false, bool
strip_code=false, std::string title="");
void HTML_recurse(const DTree& doc, DTree::iterator it, std::ostringstream& str,
const std::string& preamble_string,
bool for_embedding=false, bool strip_code=false, std::string title="");
/// Convert various LaTeX constructions to HTML-with-Mathjax, e.g. \\section{...},
/// \\begin{verbatim}...\\end{verbatim}, \\verb.
std::string latex_to_html(const std::string&);
/// Export a document to a single self-contained LaTeX file, with the exception of
/// images which get saved as separate numbered files.
std::string export_as_LaTeX(const DTree& doc, const std::string& image_file_base, bool for_embedding=false);
void LaTeX_recurse(const DTree& doc, DTree::iterator it, std::ostringstream& str,
const std::string& preamble_string, const std::string& image_file_base,
int& image_num, bool for_embedding);
/// Export a document to a python-like file (converting text cells to comments
/// and python cells to python code, dropping output cells).
std::string export_as_python(const DTree& doc);
void python_recurse(const DTree& doc, DTree::iterator it, std::ostringstream& str);
/// Replace all occurrences of a substring in the original string.
// std::string replace_all(std::string, const std::string& old, const std::string& nw);
/// Convert the JSON of a Jupyter notebook (with Cadabra contents)
/// to the JSON of a Cadabra notebook.
nlohmann::json ipynb2cnb(const nlohmann::json&);
/// Convert the JSON of a Cadabra notebook to a Jupyter notebook.
nlohmann::json cnb2ipynb(const nlohmann::json&);
}
|