yarle-evernote-to-md
Version:
Yet Another Rope Ladder from Evernote
201 lines • 10.1 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.dropTheRope = exports.parseStream = exports.yarleOptions = exports.defaultYarleOptions = void 0;
// tslint:disable:no-console
const fs_1 = __importDefault(require("fs"));
const lodash_1 = require("lodash");
const path = __importStar(require("path"));
const xml_flow_1 = __importDefault(require("xml-flow"));
const utils = __importStar(require("./utils"));
const process_node_1 = require("./process-node");
const note_utils_1 = require("./utils/note-utils");
const loggerInfo_1 = require("./utils/loggerInfo");
const checker_functions_1 = require("./utils/templates/checker-functions");
const default_template_1 = require("./utils/templates/default-template");
const output_format_1 = require("./output-format");
const clearLogFile_1 = require("./utils/clearLogFile");
const runtime_properties_1 = require("./runtime-properties");
const process_tasks_1 = require("./process-tasks");
const EvernoteTask_1 = require("./models/EvernoteTask");
const task_output_format_1 = require("./task-output-format");
const is_tana_output_1 = require("./utils/tana/is-tana-output");
const LanguageFactory_1 = require("./outputLanguages/LanguageFactory");
exports.defaultYarleOptions = {
enexSources: ['notebook.enex'],
outputDir: './mdNotes',
keepOriginalHtml: false,
posixHtmlPath: false,
isMetadataNeeded: false,
isNotebookNameNeeded: false,
isZettelkastenNeeded: false,
useZettelIdAsFilename: false,
plainTextNotesOnly: false,
skipWebClips: true,
useHashTags: true,
trimStartingTabs: false,
convertPlainHtmlNewlines: false,
encryptionPasswords: [],
nestedTags: {
separatorInEN: '_',
replaceSeparatorWith: '/',
replaceSpaceWith: '-',
},
outputFormat: output_format_1.OutputFormat.StandardMD,
taskOutputFormat: task_output_format_1.TaskOutputFormat.StandardMD,
obsidianTaskTag: '',
urlEncodeFileNamesAndLinks: false,
sanitizeResourceNameSpaces: false,
replacementChar: '_',
replacementCharacterMap: {},
globalReplacementSettings: [],
pathSeparator: '/',
resourcesDir: '_resources',
turndownOptions: {
headingStyle: 'atx',
},
};
exports.yarleOptions = Object.assign({}, exports.defaultYarleOptions);
const setOptions = (options) => {
exports.yarleOptions = (0, lodash_1.merge)({}, exports.defaultYarleOptions, options);
let template = (exports.yarleOptions.templateFile) ? fs_1.default.readFileSync(exports.yarleOptions.templateFile, 'utf-8') : default_template_1.defaultTemplate;
template = exports.yarleOptions.currentTemplate ? exports.yarleOptions.currentTemplate : template;
/*if (yarleOptions.templateFile) {*/
// todo: handle file not exists error
exports.yarleOptions.skipCreationTime = !(0, checker_functions_1.hasCreationTimeInTemplate)(template);
exports.yarleOptions.skipLocation = !(0, checker_functions_1.hasLocationInTemplate)(template);
exports.yarleOptions.skipSourceUrl = !(0, checker_functions_1.hasSourceURLInTemplate)(template);
exports.yarleOptions.skipTags = !(0, checker_functions_1.hasAnyTagsInTemplate)(template) && !(0, is_tana_output_1.isTanaOutput)();
exports.yarleOptions.skipUpdateTime = !(0, checker_functions_1.hasUpdateTimeInTemplate)(template);
exports.yarleOptions.isNotebookNameNeeded = (0, checker_functions_1.hasNotebookInTemplate)(template);
exports.yarleOptions.keepOriginalHtml = (0, checker_functions_1.hasLinkToOriginalInTemplate)(template);
exports.yarleOptions.currentTemplate = template;
(0, loggerInfo_1.loggerInfo)(`Current config is: ${JSON.stringify(exports.yarleOptions, null, 4)}`);
(0, loggerInfo_1.loggerInfo)(`Path separator:${path.sep}`);
/*}*/
};
const parseStream = async (options, enexSource) => {
(0, loggerInfo_1.loggerInfo)(`Getting stream from ${enexSource}`);
const stream = fs_1.default.createReadStream(enexSource);
// const xml = new XmlStream(stream);
let noteNumber = 0;
let failed = 0;
let skipped = 0;
const tasks = {}; // key: taskId value: generated md text
const notebookName = utils.getNotebookName(enexSource);
const processTaskFn = (0, process_tasks_1.processTaskFactory)(exports.yarleOptions.taskOutputFormat);
return new Promise((resolve, reject) => {
const logAndReject = (error) => {
(0, loggerInfo_1.loggerInfo)(`Could not convert ${enexSource}:\n${error.message}`);
++failed;
return reject();
};
if (!fs_1.default.existsSync(enexSource)) {
return (0, loggerInfo_1.loggerInfo)(JSON.stringify({ name: 'NoSuchFileOrDirectory', message: 'source Enex file does not exists' }));
}
const xml = (0, xml_flow_1.default)(stream);
let noteAttributes = null;
xml.on('tag:note-attributes', (na) => {
noteAttributes = na;
});
xml.on('tag:note', (note) => {
var _a;
if (options.skipWebClips && (0, note_utils_1.isWebClip)(note)) {
++skipped;
(0, loggerInfo_1.loggerInfo)(`Notes skipped: ${skipped}`);
}
else {
if (noteAttributes) {
// make sure single attributes are not collapsed
note['note-attributes'] = noteAttributes;
}
note.noteName = (_a = note.title) === null || _a === void 0 ? void 0 : _a.slice();
(0, process_node_1.processNode)(note, notebookName);
++noteNumber;
(0, loggerInfo_1.loggerInfo)(`Notes processed: ${noteNumber}\n\n`);
}
noteAttributes = null;
const runtimeProps = runtime_properties_1.RuntimePropertiesSingleton.getInstance();
const currentNotePath = runtimeProps.getCurrentNotePath();
if (currentNotePath) {
for (const task of Object.keys(tasks)) {
const taskPlaceholder = `<YARLE-EN-V10-TASK>${task}</YARLE-EN-V10-TASK>`;
const fileContent = fs_1.default.readFileSync(currentNotePath, 'UTF-8');
const sortedTasks = new Map([...tasks[task]].sort());
let updatedContent = fileContent.replace(taskPlaceholder, [...sortedTasks.values()].join('\n'));
const languageFactory = new LanguageFactory_1.LanguageFactory();
const language = languageFactory.createLanguage(exports.yarleOptions.outputFormat);
updatedContent = language.tagProcess(fileContent, sortedTasks, taskPlaceholder, updatedContent);
fs_1.default.writeFileSync(currentNotePath, updatedContent);
}
}
});
xml.on('tag:task', (pureTask) => {
const task = (0, EvernoteTask_1.mapEvernoteTask)(pureTask);
if (!tasks[task.taskgroupnotelevelid]) {
tasks[task.taskgroupnotelevelid] = new Map();
}
tasks[task.taskgroupnotelevelid].set(task.sortweight, processTaskFn(task, notebookName));
});
xml.on('end', () => {
const success = noteNumber - failed;
const totalNotes = noteNumber + skipped;
(0, loggerInfo_1.loggerInfo)('==========================');
(0, loggerInfo_1.loggerInfo)(`Conversion finished: ${success} succeeded, ${skipped} skipped, ${failed} failed. Total notes: ${totalNotes}`);
return resolve();
});
xml.on('error', logAndReject);
stream.on('error', logAndReject);
});
};
exports.parseStream = parseStream;
const saveOptionsAsConfig = (options) => {
const now = new Date();
const formattedDateString = `${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')}_${String(now.getHours()).padStart(2, '0')}${String(now.getMinutes()).padStart(2, '0')}${String(now.getSeconds()).padStart(2, '0')}`;
const yarleConfigName = `yarle_${formattedDateString}.config`;
const encoded = Buffer.from(JSON.stringify(options));
fs_1.default.writeFileSync(path.join(options.outputDir, yarleConfigName), encoded);
};
const dropTheRope = async (options) => {
(0, clearLogFile_1.clearLogFile)();
setOptions(options);
utils.createRootOutputDir();
saveOptionsAsConfig(options);
const outputNotebookFolders = [];
for (const enex of options.enexSources) {
utils.setPaths(enex);
const runtimeProps = runtime_properties_1.RuntimePropertiesSingleton.getInstance();
runtimeProps.setCurrentNotebookName(utils.getNotebookName(enex));
await (0, exports.parseStream)(options, enex);
outputNotebookFolders.push(utils.getNotesPath());
}
return outputNotebookFolders;
};
exports.dropTheRope = dropTheRope;
// tslint:enable:no-console
//# sourceMappingURL=yarle.js.map