The code defines a function importNotebook to import a notebook, which interprets the notebook using the interpret function from the Core module, and then makes a module based on the notebook's language.
npm run import -- "import notebook"var path = require('path');
// TODO: combine with id2 from rpc and nicename from notebook export
// TODO: insert niceName and getExports here?
// must have a unique id for each unique cell so that
// individual cells can serve as modules as well as notebooks
// adding the cell id as a part of the filename
function getCellPath(cell) {
var question = cell.questions && cell.questions[0]
? (' aka ' + cell.questions[0].substr(0, 50))
: ''
return path.join(path.dirname(path.resolve(cell.filename)), cell.id) + question
}
const ACCUMULATOR = {
info: [],
error: [],
log: [],
}
const CONSOLE = {
info: function (...args) {
ACCUMULATOR.info.push(args.map(a => String(a)).join(' '))
console.info(...args)
},
error: function (...args) {
ACCUMULATOR.error.push(args.map(a => String(a)).join(' '))
console.error(...args)
},
log: function (...args) {
ACCUMULATOR.log.push(args.map(a => String(a)).join(' '))
console.log(...args)
},
}
// How to test if a notebook has already been imported
function importNotebook("notebook",
"ctx = {}") {
var {interpret, makeModule, makeESModule, makeDylib, makeDLL, makePythonModule} = require('../Core')
// accept all arguments as the list of queries
if(arguments.length > 2) {
notebook = Array.from(arguments)
if(typeof arugments[arguments.length - 1] === 'object'
&& !Array.isArray(arugments[arguments.length - 1])) {
notebook = notebook.slice(0, arguments.length - 1)
ctx = arugments[arguments.length - 1]
}
}
if (typeof notebook === 'undefined') {
return Promise.resolve({})
}
// TODO: move this sort of thing to cache
var cells = interpret(notebook)
if(typeof cells.code !== 'undefined') {
if(!cells.filename.includes('Core')) {
CONSOLE.log(`importing ${notebook} - 1 cell - ${cells.id}`)
}
if(cells.language == 'python') {
return makePythonModule(cells.source.join(''),
cells.id,
ctx)
} else
if(cells.language == 'csharp') {
return makeDLL(cells.source.join(''), cells.id)
} else
if(cells.language == 'c' || cells.language == 'cpp' || cells.language == 'objective-c') {
return makeDylib(cells.source.join(''), cells.id)
} else
if (!cells.filename.match(/Core\//gi) && !cells.filename.match(/cache/gi)
&& cells.source.join('').match(/^import\s|^export\s/gmi)
) {
CONSOLE.error('ES module matched')
return Promise.resolve(makeESModule(cells.source.join(''), cells.filename, ctx))
} else
return makeModule(cells.source.join(''),
getCellPath(cells),
ctx)
}
CONSOLE.log(`importing ${notebook} - ${cells.length} cells - ${cells.map(c => c.id)}`)
var package = {}
for(let i = 0; i < cells.length; i++) {
let result
if(cells.language == 'python') {
result = makePythonModule(cells[i].source.join(''),
cells[i].id,
ctx)
} else
if(cells[i].language == 'csharp') {
result = makeDLL(cells[i].source.join(''), cells[i].id)
} else
if(cells[i].language == 'c' || cells[i].language == 'cpp' || cells[i].language == 'objective-c') {
result = makeDylib(cells[i].source.join(''), cells[i].id)
} else
if (!cells[i].filename.match(/Core\//gi) && !cells[i].filename.match(/cache/gi)
&& cells[i].source.join('').match(/^import\s|^export\s/gi)
) {
result = Promise.resolve(makeESModule(cells[i].source.join(''), cells[i].filename, ctx))
} else
result = makeModule(cells[i].source.join(''),
getCellPath(cells[i]),
ctx)
if(typeof result === 'object') {
// TODO: handle promises and merge them if they are objects?
if(typeof result[Object.keys(result)[0]] === 'function') {
const func = result[Object.keys(result)[0]]
package[cells[i].id] = func
package[func.name] = func
}
Object.assign(package, result)
}
if (typeof result === 'function') {
package[cells[i].id] = result
package[result.name] = result
}
package[i] = result
Object.assign(ctx, package)
}
return package
}
module.exports.importNotebook = importNotebook;
module.exports.import = importNotebook;
module.exports.CONSOLE = CONSOLE
module.exports.ACCUMULATOR = ACCUMULATOR
const path = require('path');
const { interpret, makeModule, makeESModule, makeDylib, makeDLL, makePythonModule } = require('../Core');
class Accumulator {
constructor() {
this.info = [];
this.error = [];
this.log = [];
}
info(...args) {
this.info.push(args.map(a => String(a)).join(' '));
console.info(...args);
}
error(...args) {
this.error.push(args.map(a => String(a)).join(' '));
console.error(...args);
}
log(...args) {
this.log.push(args.map(a => String(a)).join(' '));
console.log(...args);
}
}
const console = new Accumulator();
const getCellPath = (cell) => {
const { questions, filename, id } = cell;
const question = questions && questions[0]? ` aka ${questions[0].substr(0, 50)}` : '';
return path.join(path.dirname(path.resolve(filename)), id) + question;
};
const isESModule = (source) => /^import\s|^export\s/gi.test(source.join(''));
const getModuleMaker = (language, makeDylib, makeDLL, makePythonModule) => {
switch (language) {
case 'csharp':
return makeDLL;
case 'c':
case 'cpp':
case 'objective-c':
return makeDylib;
case 'python':
return makePythonModule;
default:
return makeModule;
}
};
const importNotebook = async (notebook, ctx = {}) => {
if (arguments.length > 2) {
notebook = Array.from(arguments);
if (typeof notebook[notebook.length - 1] === 'object' &&!Array.isArray(notebook[notebook.length - 1])) {
notebook = notebook.slice(0, notebook.length - 1);
ctx = notebook[notebook.length - 1];
}
}
if (typeof notebook === 'undefined') {
return Promise.resolve({});
}
const cells = await interpret(notebook);
const package = {};
const moduleMakers = {};
for (const cell of cells) {
const { source, language, id, filename } = cell;
const { make } = getModuleMaker(language, makeDylib, makeDLL, makePythonModule);
if (isESModule(source)) {
await console.log(`importing ${filename} - ES module`);
moduleMakers[id] = makeESModule(source.join(''), filename, ctx);
} else {
await console.log(`importing ${filename} - ${cells.length} cell - ${id}`);
moduleMakers[id] = await make(source.join(''), getCellPath(cell), ctx);
}
Object.assign(package, moduleMakers[id]);
Object.assign(ctx, package);
}
return package;
};
module.exports = {
importNotebook,
console,
package: {}
};Importing Modules and Functions
The code starts by importing the path module and defining a function getCellPath to construct a file path from a cell object.
var path = require('path');
function getCellPath(cell) {
//...
}
Defining Accumulator and Console Objects
It then defines two objects: ACCUMULATOR and CONSOLE. ACCUMULATOR is an object that accumulates log messages, and CONSOLE is an object that provides wrapper functions for console.log, console.info, and console.error. These wrapper functions add log messages to the ACCUMULATOR object.
const ACCUMULATOR = {
info: [],
error: [],
log: [],
}
const CONSOLE = {
info: function (...args) {
//...
},
error: function (...args) {
//...
},
log: function (...args) {
//...
},
}
Defining the ImportNotebook Function
The importNotebook function is defined to import a notebook. It takes a notebook parameter, which can be either a single value or an array of values, and an optional ctx parameter.
function importNotebook(notebook, ctx = {}) {
//...
}
Interpreting and Making Modules
The function uses the interpret function from the Core module to interpret the notebook. It then checks the language of the notebook and makes a module using the corresponding function (e.g., makePythonModule for Python notebooks).
var cells = interpret(notebook)
if (typeof cells.code!== 'undefined') {
if (!cells.filename.includes('Core')) {
CONSOLE.log(`importing ${notebook} - 1 cell - ${cells.id}`)
}
if (cells.language == 'python') {
return makePythonModule(cells.code, ctx)
}
}
Incomplete Documentation
The code snippet appears to be incomplete, as there are several TODO comments and some functions are not fully defined. Additionally, the importNotebook function seems to return a Promise, but it is not clear what the resolution value is.