#pragma once #include #include #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 image_svg, ///< output: cell showing an SVG 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 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&); }