UNPKG

yarle-evernote-to-md

Version:

Yet Another Rope Ladder from Evernote

157 lines 8.54 kB
"use strict"; 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.prepareContentByExtractingDataUrlResources = exports.processResources = void 0; const lodash_1 = require("lodash"); const fs_1 = __importDefault(require("fs")); const md5_file_1 = __importDefault(require("md5-file")); const path = __importStar(require("path")); const fs_extra_1 = __importDefault(require("fs-extra")); const utils = __importStar(require("./utils")); const yarle_1 = require("./yarle"); const output_format_1 = require("./output-format"); const getResourceWorkDirs = (note) => { const pathSepRegExp = new RegExp(`\\${path.sep}`, 'g'); const relativeResourceWorkDir = utils.getRelativeResourceDir(note).replace(pathSepRegExp, yarle_1.yarleOptions.pathSeparator); const absoluteResourceWorkDir = utils.getAbsoluteResourceDir(note); // .replace(pathSepRegExp,yarleOptions.pathSeparator) return { absoluteResourceWorkDir, relativeResourceWorkDir }; }; const processResources = (note) => { let resourceHashes = {}; let updatedContent = (0, lodash_1.cloneDeep)(note.content); const { absoluteResourceWorkDir, relativeResourceWorkDir } = getResourceWorkDirs(note); utils.loggerInfo(`relative resource work dir: ${relativeResourceWorkDir}`); utils.loggerInfo(`absolute resource work dir: ${absoluteResourceWorkDir}`); utils.clearResourceDir(note); if (Array.isArray(note.resource)) { for (const resource of note.resource) { resourceHashes = Object.assign(Object.assign({}, resourceHashes), processResource(absoluteResourceWorkDir, resource)); } } else { resourceHashes = Object.assign(Object.assign({}, resourceHashes), processResource(absoluteResourceWorkDir, note.resource)); } for (const hash of Object.keys(resourceHashes)) { updatedContent = addMediaReference(updatedContent, resourceHashes, hash, relativeResourceWorkDir); } return updatedContent; }; exports.processResources = processResources; const addMediaReference = (content, resourceHashes, hash, workDir) => { const src = `${workDir}${yarle_1.yarleOptions.pathSeparator}${resourceHashes[hash].fileName.replace(/ /g, '\ ')}`; utils.loggerInfo(`mediaReference src ${src} added`); let updatedContent = (0, lodash_1.cloneDeep)(content); const replace = `<en-media ([^>]*)hash="${hash}".([^>]*)>`; const re = new RegExp(replace, 'g'); const matchedElements = content.match(re); const mediaType = matchedElements && matchedElements.length > 0 && matchedElements[0].split('type='); if (mediaType && mediaType.length > 1 && mediaType[1].startsWith('"image')) { const width = matchedElements[0].match(/width="(\w+)"/); const widthParam = width ? ` width="${width[1]}"` : ''; const height = matchedElements[0].match(/height="(\w+)"/); const heightParam = height ? ` height="${height[1]}"` : ''; updatedContent = content.replace(re, `<img src="${src}"${widthParam}${heightParam} alt="${resourceHashes[hash].fileName}">`); } else { updatedContent = content.replace(re, `<a href="${src}" type="file">${resourceHashes[hash].fileName}</a>`); } return updatedContent; }; const processResource = (workDir, resource) => { var _a; const resourceHash = {}; const data = ((_a = resource.data) === null || _a === void 0 ? void 0 : _a.$text) || ''; const accessTime = utils.getTimeStampMoment(resource); const resourceFileProps = utils.getResourceFileProperties(workDir, resource); let fileName = resourceFileProps.fileName; // add time to ease the same name issue if (yarle_1.yarleOptions.outputFormat === output_format_1.OutputFormat.LogSeqMD) { fileName = `${accessTime.toDate().getTime()}_${fileName}`; } const absFilePath = `${workDir}${path.sep}${fileName}`; fs_1.default.writeFileSync(absFilePath, data, 'base64'); const atime = accessTime.valueOf() / 1000; fs_1.default.utimesSync(absFilePath, atime, atime); if (resource.recognition && fileName) { const hashIndex = resource.recognition.match(/[a-f0-9]{32}/); utils.loggerInfo(`resource ${fileName} addid in hash ${hashIndex}`); resourceHash[hashIndex] = { fileName, alreadyUsed: false }; } else { const md5Hash = md5_file_1.default.sync(absFilePath); resourceHash[md5Hash] = { fileName, alreadyUsed: false }; } return resourceHash; }; const prepareContentByExtractingDataUrlResources = (note, content) => { if (content.indexOf('src="data:') < 0 && content.indexOf('href="data:') < 0) { return content; // no data urls } const { absoluteResourceWorkDir, relativeResourceWorkDir } = getResourceWorkDirs(note); fs_extra_1.default.mkdirsSync(absoluteResourceWorkDir); // change links hrefs content = content.replace(/ (href)="data:([^;,]*)(;base64)?,([^"]*)"(.*?)<\/a>/g, (match, argument, mediatype, encoding, data, postfix) => { const fileName = createResourceFromData(argument, match, mediatype, encoding === ';base64', data, absoluteResourceWorkDir, note); const argValue = `${relativeResourceWorkDir}${yarle_1.yarleOptions.pathSeparator}${fileName}`; return `yarle-file-resource="true" ${argument}="${argValue}"${postfix}`; }); // src|href="data:image/svg+xml;base64,..." --> src="resourceDir/fileName" return content.replace(/(src)="data:([^;,]*)(;base64)?,([^"]*)"/g, (match, argument, mediatype, encoding, data) => { const fileName = createResourceFromData(argument, match, mediatype, encoding === ';base64', data, absoluteResourceWorkDir, note); const argValue = `${relativeResourceWorkDir}${yarle_1.yarleOptions.pathSeparator}${fileName}`; return `yarle-file-resource="true" ${argument}="${argValue}"`; }); }; exports.prepareContentByExtractingDataUrlResources = prepareContentByExtractingDataUrlResources; // returns filename of new resource const createResourceFromData = (argument, match, mediatype, base64, data, absoluteResourceWorkDir, note) => { var _a; const baseName = 'embedded'; // data doesn't seem to include useful base filename const extension = extensionForMimeType(mediatype) || '.dat'; const index = utils.getFileIndex(absoluteResourceWorkDir, baseName); let fileName = index < 1 ? `${baseName}.${extension}` : `${baseName}.${index}.${extension}`; if (argument === 'href') { const baseNameCandidate = (_a = match.split("alt=\"")[1]) === null || _a === void 0 ? void 0 : _a.split("\"")[0]; if (baseNameCandidate) fileName = baseNameCandidate; } const absFilePath = `${absoluteResourceWorkDir}${path.sep}${fileName}`; if (!base64 && !data.startsWith('&lt;svg')) { // TODO: handle <svg, tags, they may be checkboxes data = decodeURIComponent(data); } fs_1.default.writeFileSync(absFilePath, data, base64 ? 'base64' : undefined); utils.setFileDates(absFilePath, note.created, note.updated); utils.loggerInfo(`data url resource ${fileName} added`); return fileName; }; const extensionForMimeType = (mediatype) => { // image/jpeg or image/svg+xml or audio/wav or ... const subtype = mediatype.split('/').pop(); // jpeg or svg+xml or wav return subtype.split('+')[0]; // jpeg or svg or wav }; //# sourceMappingURL=process-resources.js.map