yarle-evernote-to-md
Version:
Yet Another Rope Ladder from Evernote
170 lines (139 loc) • 6 kB
text/typescript
import uniqueFilename from 'unique-filename';
import sanitize from 'sanitize-filename';
import * as fs from 'fs';
import Moment from 'moment';
import * as path from 'path';
import * as mime from 'mime-types';
import { nanoid } from 'nanoid';
import { yarleOptions } from '../yarle';
import { ResourceFileProperties } from './../models/ResourceFileProperties';
import { OutputFormat } from './../output-format';
import { getCreationTime } from './content-utils';
import { escapeStringRegexp } from './escape-string-regexp';
import { isLogseqJournal } from './is-logseq-journal';
import { closest } from 'fastest-levenshtein';
import { EvernoteNoteData } from '../models';
const applyCharacterMapSafely = (title: string): string => {
return applyCharacterMap(title).replace(/[/\\?%*:|"<>\[\]\+]/g, '-');
}
const applyCharacterMap = (title: string): string => {
let appliedTitle = title;
try{
for (const key of Object.keys(yarleOptions.replacementCharacterMap)){
const replacement = yarleOptions.replacementCharacterMap[key as any];
const regex: RegExp = new RegExp(escapeStringRegexp(key), 'g');
appliedTitle = appliedTitle.replace(regex, replacement)
}
}catch(e){
console.log(e)
}
console.log(appliedTitle)
return appliedTitle;
}
export const normalizeFilenameString = (title: string) => {
// Allow setting a specific replacement character for file and resource names
// Default to a retrocompatible value
const normalizedTitle = sanitize(applyCharacterMap(title), {replacement: yarleOptions.replacementChar || '_'}).replace(/[\[\]\#\^]/g, '')
console.log(normalizedTitle)
return normalizedTitle;
;
};
export const getFileIndex = (dstPath: string, fileNamePrefix: string): number | string => {
const index = fs
.readdirSync(dstPath)
.filter(file => {
// make sure we get the first copy with no count suffix or the copies whose filename changed
// drop the extension to compare with filename prefix
const filePrefix = file.split('.').slice(0, -1).join('.');
return filePrefix.toLowerCase().startsWith(fileNamePrefix.toLowerCase());
})
.length;
return index;
};
export const getResourceFileProperties = (workDir: string, resource: any): ResourceFileProperties => {
const UNKNOWNFILENAME = yarleOptions.useUniqueUnknownFileNames ? uniqueFilename('', 'unknown_filename') : 'unknown_filename';
let extension = getExtension(resource);
let fileName = UNKNOWNFILENAME;
if (resource['resource-attributes'] && resource['resource-attributes']['file-name']) {
const fileNamePrefix = resource['resource-attributes']['file-name'].substr(0, 50);
const lastIdx = fileNamePrefix.lastIndexOf('.');
fileName = lastIdx !== -1
? fileNamePrefix.slice(0, lastIdx)
: fileNamePrefix;fileNamePrefix.includes('.') ? fileNamePrefix.split('.').slice(0, -1).join('.') : fileNamePrefix;
}
fileName = applyCharacterMapSafely(fileName);
extension = applyCharacterMapSafely(extension);
if (yarleOptions.sanitizeResourceNameSpaces) {
fileName = fileName.replace(/ /g, yarleOptions.replacementChar);
}
if (yarleOptions.urlEncodeFileNamesAndLinks && yarleOptions.outputFormat === OutputFormat.ObsidianMD) {
fileName = encodeURI(fileName);
}
const index = getFileIndex(workDir, fileName);
const fileNameWithIndex = index > 0 ? `${fileName}.${index}` : fileName;
return {
fileName: `${fileNameWithIndex}.${extension}`,
extension,
index,
};
};
export const getFilePrefix = (note: EvernoteNoteData): string => {
return normalizeFilenameString(note['noteName'] ? `${note['noteName'].toString()}` : 'Untitled');
};
export const getNoteFileName = (dstPath: string, note: EvernoteNoteData, extension: string = 'md'): string => {
return `${getNoteName(dstPath, note)}.${extension}`;
};
export const getExtensionFromResourceFileName = (resource: any): string => {
if (!(resource['resource-attributes'] &&
resource['resource-attributes']['file-name'])) {
return undefined;
}
const splitFileName = resource['resource-attributes']['file-name'].split('.');
return splitFileName.length > 1 ? splitFileName[splitFileName.length - 1] : undefined;
};
export const getExtensionFromMime = (resource: any): string => {
const mimeType = resource.mime;
if (!mimeType) {
return undefined;
}
return mime.extension(mimeType);
};
export const getExtension = (resource: any): string => {
const UNKNOWNEXTENSION = 'dat';
return getExtensionFromResourceFileName(resource) || getExtensionFromMime(resource) || UNKNOWNEXTENSION;
};
export const getZettelKastelId = (note: EvernoteNoteData, dstPath: string): string => {
return Moment(note['created']).format('YYYYMMDDHHmm');
};
export const getUniqueId = (): string => {
return nanoid(5);
};
export const getNoteName = (dstPath: string, note: EvernoteNoteData): string => {
let noteName;
if (yarleOptions.isZettelkastenNeeded || yarleOptions.useZettelIdAsFilename) {
const zettelPrefix = getZettelKastelId(note, dstPath);
const nextIndex = getFileIndex(dstPath, zettelPrefix);
const separator = ' ';
noteName = (nextIndex !== 0) ?
`${zettelPrefix}.${nextIndex}` :
zettelPrefix;
if (!yarleOptions.useZettelIdAsFilename) {
noteName += getFilePrefix(note) !== 'Untitled' ? `${separator}${getFilePrefix(note)}` : '';
}
} else {
const fileNamePrefix = getFilePrefix(note);
const nextIndex = getFileIndex(dstPath, fileNamePrefix);
noteName = (nextIndex === 0) ? fileNamePrefix : `${fileNamePrefix}.${nextIndex}`;
}
if (isLogseqJournal(yarleOptions)) {
return getCreationTime(note);
}
return noteName;
};
export const getNotebookName = (enexFile: string): string => {
const notebookName = normalizeFilenameString(path.basename(enexFile, '.enex'));
return notebookName;
};
export const getClosestFileName = (text: string ,allconvertedFiles: string[]): string => {
return closest(text, allconvertedFiles);
}