mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
Add import option to replace underscores with spaces in note names (#1064)
This commit is contained in:
parent
c0cd321118
commit
ac10701b55
@ -12,6 +12,7 @@ const $shrinkImagesCheckbox = $("#shrink-images-checkbox");
|
|||||||
const $textImportedAsTextCheckbox = $("#text-imported-as-text-checkbox");
|
const $textImportedAsTextCheckbox = $("#text-imported-as-text-checkbox");
|
||||||
const $codeImportedAsCodeCheckbox = $("#code-imported-as-code-checkbox");
|
const $codeImportedAsCodeCheckbox = $("#code-imported-as-code-checkbox");
|
||||||
const $explodeArchivesCheckbox = $("#explode-archives-checkbox");
|
const $explodeArchivesCheckbox = $("#explode-archives-checkbox");
|
||||||
|
const $replaceUnderscoresWithSpacesCheckbox = $("#replace-underscores-with-spaces-checkbox");
|
||||||
|
|
||||||
let parentNoteId = null;
|
let parentNoteId = null;
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ export async function showDialog(noteId) {
|
|||||||
$textImportedAsTextCheckbox.prop("checked", true);
|
$textImportedAsTextCheckbox.prop("checked", true);
|
||||||
$codeImportedAsCodeCheckbox.prop("checked", true);
|
$codeImportedAsCodeCheckbox.prop("checked", true);
|
||||||
$explodeArchivesCheckbox.prop("checked", true);
|
$explodeArchivesCheckbox.prop("checked", true);
|
||||||
|
$replaceUnderscoresWithSpacesCheckbox.prop("checked", true);
|
||||||
|
|
||||||
parentNoteId = noteId;
|
parentNoteId = noteId;
|
||||||
|
|
||||||
@ -48,7 +50,8 @@ async function importIntoNote(parentNoteId) {
|
|||||||
shrinkImages: boolToString($shrinkImagesCheckbox),
|
shrinkImages: boolToString($shrinkImagesCheckbox),
|
||||||
textImportedAsText: boolToString($textImportedAsTextCheckbox),
|
textImportedAsText: boolToString($textImportedAsTextCheckbox),
|
||||||
codeImportedAsCode: boolToString($codeImportedAsCodeCheckbox),
|
codeImportedAsCode: boolToString($codeImportedAsCodeCheckbox),
|
||||||
explodeArchives: boolToString($explodeArchivesCheckbox)
|
explodeArchives: boolToString($explodeArchivesCheckbox),
|
||||||
|
replaceUnderscoresWithSpaces: boolToString($replaceUnderscoresWithSpacesCheckbox)
|
||||||
};
|
};
|
||||||
|
|
||||||
$dialog.modal('hide');
|
$dialog.modal('hide');
|
||||||
|
@ -96,7 +96,8 @@ export default class NoteDetailWidget extends TabAwareWidget {
|
|||||||
shrinkImages: true,
|
shrinkImages: true,
|
||||||
textImportedAsText: true,
|
textImportedAsText: true,
|
||||||
codeImportedAsCode: true,
|
codeImportedAsCode: true,
|
||||||
explodeArchives: true
|
explodeArchives: true,
|
||||||
|
replaceUnderscoresWithSpaces: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -300,7 +300,8 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
|||||||
shrinkImages: true,
|
shrinkImages: true,
|
||||||
textImportedAsText: true,
|
textImportedAsText: true,
|
||||||
codeImportedAsCode: true,
|
codeImportedAsCode: true,
|
||||||
explodeArchives: true
|
explodeArchives: true,
|
||||||
|
replaceUnderscoresWithSpaces: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -21,7 +21,8 @@ async function importToBranch(req) {
|
|||||||
shrinkImages: req.body.shrinkImages !== 'false',
|
shrinkImages: req.body.shrinkImages !== 'false',
|
||||||
textImportedAsText: req.body.textImportedAsText !== 'false',
|
textImportedAsText: req.body.textImportedAsText !== 'false',
|
||||||
codeImportedAsCode: req.body.codeImportedAsCode !== 'false',
|
codeImportedAsCode: req.body.codeImportedAsCode !== 'false',
|
||||||
explodeArchives: req.body.explodeArchives !== 'false'
|
explodeArchives: req.body.explodeArchives !== 'false',
|
||||||
|
replaceUnderscoresWithSpaces: req.body.replaceUnderscoresWithSpaces !== 'false'
|
||||||
};
|
};
|
||||||
|
|
||||||
const file = req.file;
|
const file = req.file;
|
||||||
|
@ -4,8 +4,8 @@ const noteService = require('../../services/notes');
|
|||||||
const imageService = require('../../services/image');
|
const imageService = require('../../services/image');
|
||||||
const protectedSessionService = require('../protected_session');
|
const protectedSessionService = require('../protected_session');
|
||||||
const commonmark = require('commonmark');
|
const commonmark = require('commonmark');
|
||||||
const path = require('path');
|
|
||||||
const mimeService = require('./mime');
|
const mimeService = require('./mime');
|
||||||
|
const utils = require('../../services/utils');
|
||||||
|
|
||||||
async function importSingleFile(taskContext, file, parentNote) {
|
async function importSingleFile(taskContext, file, parentNote) {
|
||||||
const mime = mimeService.getMime(file.originalname) || file.mimetype;
|
const mime = mimeService.getMime(file.originalname) || file.mimetype;
|
||||||
@ -59,7 +59,7 @@ async function importFile(taskContext, file, parentNote) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function importCodeNote(taskContext, file, parentNote) {
|
async function importCodeNote(taskContext, file, parentNote) {
|
||||||
const title = getFileNameWithoutExtension(file.originalname);
|
const title = utils.getNoteTitle(file.originalname, taskContext.data.replaceUnderscoresWithSpaces);
|
||||||
const content = file.buffer.toString("UTF-8");
|
const content = file.buffer.toString("UTF-8");
|
||||||
const detectedMime = mimeService.getMime(file.originalname) || file.mimetype;
|
const detectedMime = mimeService.getMime(file.originalname) || file.mimetype;
|
||||||
const mime = mimeService.normalizeMimeType(detectedMime);
|
const mime = mimeService.normalizeMimeType(detectedMime);
|
||||||
@ -79,7 +79,7 @@ async function importCodeNote(taskContext, file, parentNote) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function importPlainText(taskContext, file, parentNote) {
|
async function importPlainText(taskContext, file, parentNote) {
|
||||||
const title = getFileNameWithoutExtension(file.originalname);
|
const title = utils.getNoteTitle(file.originalname, taskContext.data.replaceUnderscoresWithSpaces);
|
||||||
const plainTextContent = file.buffer.toString("UTF-8");
|
const plainTextContent = file.buffer.toString("UTF-8");
|
||||||
const htmlContent = convertTextToHtml(plainTextContent);
|
const htmlContent = convertTextToHtml(plainTextContent);
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ async function importMarkdown(taskContext, file, parentNote) {
|
|||||||
const parsed = reader.parse(markdownContent);
|
const parsed = reader.parse(markdownContent);
|
||||||
const htmlContent = writer.render(parsed);
|
const htmlContent = writer.render(parsed);
|
||||||
|
|
||||||
const title = getFileNameWithoutExtension(file.originalname);
|
const title = utils.getNoteTitle(file.originalname, taskContext.data.replaceUnderscoresWithSpaces);
|
||||||
|
|
||||||
const {note} = await noteService.createNewNote({
|
const {note} = await noteService.createNewNote({
|
||||||
parentNoteId: parentNote.noteId,
|
parentNoteId: parentNote.noteId,
|
||||||
@ -141,7 +141,7 @@ async function importMarkdown(taskContext, file, parentNote) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function importHtml(taskContext, file, parentNote) {
|
async function importHtml(taskContext, file, parentNote) {
|
||||||
const title = getFileNameWithoutExtension(file.originalname);
|
const title = utils.getNoteTitle(file.originalname, taskContext.data.replaceUnderscoresWithSpaces);
|
||||||
const content = file.buffer.toString("UTF-8");
|
const content = file.buffer.toString("UTF-8");
|
||||||
|
|
||||||
const {note} = await noteService.createNewNote({
|
const {note} = await noteService.createNewNote({
|
||||||
@ -158,12 +158,6 @@ async function importHtml(taskContext, file, parentNote) {
|
|||||||
return note;
|
return note;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFileNameWithoutExtension(filePath) {
|
|
||||||
const extension = path.extname(filePath);
|
|
||||||
|
|
||||||
return filePath.substr(0, filePath.length - extension.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
importSingleFile
|
importSingleFile
|
||||||
};
|
};
|
@ -102,19 +102,8 @@ async function importTar(taskContext, fileBuffer, importRootNote) {
|
|||||||
return parentNoteId;
|
return parentNoteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNoteTitle(filePath, noteMeta) {
|
|
||||||
if (noteMeta) {
|
|
||||||
return noteMeta.title;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const basename = path.basename(filePath);
|
|
||||||
|
|
||||||
return getTextFileWithoutExtension(basename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNoteId(noteMeta, filePath) {
|
function getNoteId(noteMeta, filePath) {
|
||||||
const filePathNoExt = getTextFileWithoutExtension(filePath);
|
const filePathNoExt = utils.removeTextFileExtension(filePath);
|
||||||
|
|
||||||
if (filePathNoExt in createdPaths) {
|
if (filePathNoExt in createdPaths) {
|
||||||
return createdPaths[filePathNoExt];
|
return createdPaths[filePathNoExt];
|
||||||
@ -168,7 +157,7 @@ async function importTar(taskContext, fileBuffer, importRootNote) {
|
|||||||
const { parentNoteMeta, noteMeta } = getMeta(filePath);
|
const { parentNoteMeta, noteMeta } = getMeta(filePath);
|
||||||
|
|
||||||
const noteId = getNoteId(noteMeta, filePath);
|
const noteId = getNoteId(noteMeta, filePath);
|
||||||
const noteTitle = getNoteTitle(filePath, noteMeta);
|
const noteTitle = utils.getNoteTitle(filePath, taskContext.data.replaceUnderscoresWithSpaces, noteMeta);
|
||||||
const parentNoteId = await getParentNoteId(filePath, parentNoteMeta);
|
const parentNoteId = await getParentNoteId(filePath, parentNoteMeta);
|
||||||
|
|
||||||
let note = await repository.getNote(noteId);
|
let note = await repository.getNote(noteId);
|
||||||
@ -198,17 +187,6 @@ async function importTar(taskContext, fileBuffer, importRootNote) {
|
|||||||
return noteId;
|
return noteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTextFileWithoutExtension(filePath) {
|
|
||||||
const extension = path.extname(filePath).toLowerCase();
|
|
||||||
|
|
||||||
if (extension === '.md' || extension === '.markdown' || extension === '.html') {
|
|
||||||
return filePath.substr(0, filePath.length - extension.length);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNoteIdFromRelativeUrl(url, filePath) {
|
function getNoteIdFromRelativeUrl(url, filePath) {
|
||||||
while (url.startsWith("./")) {
|
while (url.startsWith("./")) {
|
||||||
url = url.substr(2);
|
url = url.substr(2);
|
||||||
@ -267,7 +245,7 @@ async function importTar(taskContext, fileBuffer, importRootNote) {
|
|||||||
content = mdWriter.render(parsed);
|
content = mdWriter.render(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
const noteTitle = getNoteTitle(filePath, noteMeta);
|
const noteTitle = utils.getNoteTitle(filePath, taskContext.data.replaceUnderscoresWithSpaces, noteMeta);
|
||||||
|
|
||||||
if (type === 'text') {
|
if (type === 'text') {
|
||||||
function isUrlAbsolute(url) {
|
function isUrlAbsolute(url) {
|
||||||
@ -348,7 +326,7 @@ async function importTar(taskContext, fileBuffer, importRootNote) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'text') {
|
if (type === 'text') {
|
||||||
filePath = getTextFileWithoutExtension(filePath);
|
filePath = utils.removeTextFileExtension(filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,23 +100,12 @@ async function importZip(taskContext, fileBuffer, importRootNote) {
|
|||||||
return parentNoteId;
|
return parentNoteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNoteTitle(filePath, noteMeta) {
|
|
||||||
if (noteMeta) {
|
|
||||||
return noteMeta.title;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const basename = path.basename(filePath);
|
|
||||||
|
|
||||||
return getTextFileWithoutExtension(basename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNoteId(noteMeta, filePath) {
|
function getNoteId(noteMeta, filePath) {
|
||||||
if (noteMeta) {
|
if (noteMeta) {
|
||||||
return getNewNoteId(noteMeta.noteId);
|
return getNewNoteId(noteMeta.noteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const filePathNoExt = getTextFileWithoutExtension(filePath);
|
const filePathNoExt = utils.removeTextFileExtension(filePath);
|
||||||
|
|
||||||
if (filePathNoExt in createdPaths) {
|
if (filePathNoExt in createdPaths) {
|
||||||
return createdPaths[filePathNoExt];
|
return createdPaths[filePathNoExt];
|
||||||
@ -170,7 +159,7 @@ async function importZip(taskContext, fileBuffer, importRootNote) {
|
|||||||
const { parentNoteMeta, noteMeta } = getMeta(filePath);
|
const { parentNoteMeta, noteMeta } = getMeta(filePath);
|
||||||
|
|
||||||
const noteId = getNoteId(noteMeta, filePath);
|
const noteId = getNoteId(noteMeta, filePath);
|
||||||
const noteTitle = getNoteTitle(filePath, noteMeta);
|
const noteTitle = utils.getNoteTitle(filePath, taskContext.data.replaceUnderscoresWithSpaces, noteMeta);
|
||||||
const parentNoteId = await getParentNoteId(filePath, parentNoteMeta);
|
const parentNoteId = await getParentNoteId(filePath, parentNoteMeta);
|
||||||
|
|
||||||
let note = await repository.getNote(noteId);
|
let note = await repository.getNote(noteId);
|
||||||
@ -202,17 +191,6 @@ async function importZip(taskContext, fileBuffer, importRootNote) {
|
|||||||
return noteId;
|
return noteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTextFileWithoutExtension(filePath) {
|
|
||||||
const extension = path.extname(filePath).toLowerCase();
|
|
||||||
|
|
||||||
if (extension === '.md' || extension === '.markdown' || extension === '.html') {
|
|
||||||
return filePath.substr(0, filePath.length - extension.length);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNoteIdFromRelativeUrl(url, filePath) {
|
function getNoteIdFromRelativeUrl(url, filePath) {
|
||||||
while (url.startsWith("./")) {
|
while (url.startsWith("./")) {
|
||||||
url = url.substr(2);
|
url = url.substr(2);
|
||||||
@ -275,7 +253,7 @@ async function importZip(taskContext, fileBuffer, importRootNote) {
|
|||||||
content = mdWriter.render(parsed);
|
content = mdWriter.render(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
const noteTitle = getNoteTitle(filePath, noteMeta);
|
const noteTitle = utils.getNoteTitle(filePath, taskContext.data.replaceUnderscoresWithSpaces, noteMeta);
|
||||||
|
|
||||||
if (type === 'text') {
|
if (type === 'text') {
|
||||||
function isUrlAbsolute(url) {
|
function isUrlAbsolute(url) {
|
||||||
@ -368,7 +346,7 @@ async function importZip(taskContext, fileBuffer, importRootNote) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'text') {
|
if (type === 'text') {
|
||||||
filePath = getTextFileWithoutExtension(filePath);
|
filePath = utils.removeTextFileExtension(filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ const unescape = require('unescape');
|
|||||||
const escape = require('escape-html');
|
const escape = require('escape-html');
|
||||||
const sanitize = require("sanitize-filename");
|
const sanitize = require("sanitize-filename");
|
||||||
const mimeTypes = require('mime-types');
|
const mimeTypes = require('mime-types');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
function newEntityId() {
|
function newEntityId() {
|
||||||
return randomString(12);
|
return randomString(12);
|
||||||
@ -209,6 +210,29 @@ function formatDownloadTitle(filename, type, mime) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeTextFileExtension(filePath) {
|
||||||
|
const extension = path.extname(filePath).toLowerCase();
|
||||||
|
|
||||||
|
if (extension === '.md' || extension === '.markdown' || extension === '.html') {
|
||||||
|
return filePath.substr(0, filePath.length - extension.length);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNoteTitle(filePath, replaceUnderscoresWithSpaces, noteMeta) {
|
||||||
|
if (noteMeta) {
|
||||||
|
return noteMeta.title;
|
||||||
|
} else {
|
||||||
|
const basename = path.basename(removeTextFileExtension(filePath));
|
||||||
|
if(replaceUnderscoresWithSpaces) {
|
||||||
|
return basename.replace(/_/g, ' ').trim();
|
||||||
|
}
|
||||||
|
return basename;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
randomSecureToken,
|
randomSecureToken,
|
||||||
randomString,
|
randomString,
|
||||||
@ -237,5 +261,7 @@ module.exports = {
|
|||||||
isStringNote,
|
isStringNote,
|
||||||
quoteRegex,
|
quoteRegex,
|
||||||
replaceAll,
|
replaceAll,
|
||||||
formatDownloadTitle
|
formatDownloadTitle,
|
||||||
|
getNoteTitle,
|
||||||
|
removeTextFileExtension,
|
||||||
};
|
};
|
||||||
|
@ -53,6 +53,14 @@
|
|||||||
<input id="code-imported-as-code-checkbox" value="1" type="checkbox" checked> Import recognized code files (e.g. <code>.json</code>) as code notes if it's unclear from metadata
|
<input id="code-imported-as-code-checkbox" value="1" type="checkbox" checked> Import recognized code files (e.g. <code>.json</code>) as code notes if it's unclear from metadata
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input id="replace-underscores-with-spaces-checkbox" value="1" type="checkbox" checked>
|
||||||
|
|
||||||
|
Replace underscores with spaces in imported note names
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user