Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/jupyter/ipynb/parse.ts
Views: 687
/*1This is a very lightweight ipynb parser in pure javascript.23It's used, e.g., in our analogue of nbviewer.4*/56import { IPynbImporter } from "@cocalc/jupyter/ipynb/import-from-ipynb";7import { JUPYTER_MIMETYPES } from "@cocalc/jupyter/util/misc";8import { field_cmp } from "@cocalc/util/misc";910export interface KernelSpec {11language?: string;12display_name: string;13name: string;14}1516interface Parsed {17cellList: string[];18cells: { [id: string]: object };19cmOptions: { [field: string]: any };20kernelspec: KernelSpec;21}2223export default function parse(content: string): Parsed {24const ipynb = JSON.parse(content);25const importer = new IPynbImporter();26importer.import({27ipynb,28output_handler: (cell) => {29let k: number = 0;30return {31message: (content) => {32process(content);33cell.output[`${k}`] = content;34k += 1;35},36};37},38});3940const cells = importer.cells();41const cellList = sortedCellList(cells);42const cmOptions = getCMOptions(getMode(ipynb));43const kernelspec = ipynb.metadata?.kernelspec ?? {44display_name: "Unknown Kernel",45};46return { cells, cellList, cmOptions, kernelspec };47}4849export function getMode(ipynb): string {50return (51ipynb.metadata?.language_info?.codemirror_mode ??52ipynb.metadata?.language_info?.name ??53ipynb.metadata?.kernelspec?.language?.toLowerCase() ??54"python"55);56}5758export function getCMOptions(mode: string | { name: string } | undefined | null) {59if (mode == null) {60mode = { name: "python" };61}62if (typeof mode === "string") {63mode = { name: mode };64}65if (mode.name.includes("python") || mode.name.includes("sage")) {66mode.name = "python";67} else if (mode.name === "gp") {68mode.name = "pari";69} else if (mode.name === "singular") {70mode.name = "clike"; // better than nothing71} else if (mode.name === "ihaskell") {72mode.name = "haskell";73}7475return {76mode,77showTrailingSpace: true,78tabSize: 4,79lineWrapping: true,80readOnly: true,81};82}8384function process(content): void {85if (content?.data == null) {86return;87}88for (const type of JUPYTER_MIMETYPES) {89if (90content.data[type] != null &&91(type.split("/")[0] === "image" || type === "application/pdf")92) {93content.data[type] = { value: content.data[type] };94}95}96}9798function sortedCellList(cells): string[] {99// Given map from id's to cells, returns an list of ids in correct order,100// as defined by pos field.101const v: { id: string; pos: number }[] = [];102for (const id in cells) {103v.push({ id, pos: cells[id]?.pos ?? -1 });104}105v.sort(field_cmp("pos"));106const a: string[] = [];107for (const { id } of v) {108a.push(id);109}110return a;111}112113114