Skip to content

Commit

Permalink
convert file URLs to Markdown links while pasting
Browse files Browse the repository at this point in the history
  • Loading branch information
Kamil Łopuszański committed May 10, 2024
1 parent 36c25fd commit 124bcae
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
3 changes: 3 additions & 0 deletions packages/app-desktop/gui/NoteEditor/utils/contextMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import ItemChange from '@joplin/lib/models/ItemChange';
import { HtmlToMarkdownHandler, MarkupToHtmlHandler } from './types';
import shim from '@joplin/lib/shim';
import { openFileWithExternalEditor } from '@joplin/lib/services/ExternalEditWatcher/utils';
import enhancePastedText from './textPasteEnhancer';
const fs = require('fs-extra');
const { writeFile } = require('fs-extra');
const { clipboard } = require('electron');
Expand Down Expand Up @@ -201,6 +202,8 @@ export function menuItems(dispatch: Function, htmlToMd: HtmlToMarkdownHandler, m
content = await processPastedHtml(pastedHtml, htmlToMd, mdToHtml);
}

content = enhancePastedText(content);

options.insertContent(content);
},
isActive: (_itemType: ContextMenuItemType, options: ContextMenuOptions) => !options.isReadOnly && (!!clipboard.readText() || !!clipboard.readHTML()),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import enhancePastedText from './textPasteEnhancer';

describe('enhancePastedText', () => {
it('should replace spaces with "%20" in file paths', () => {
const input = 'This is a file path: file:///Users/john/Documents/file with spaces.txt';
const expectedOutput = 'This is a file path: file:///Users/john/Documents/file%20with%20spaces.txt';
const output = enhancePastedText(input);
expect(output).toEqual(expectedOutput);
});

it('should not modify non-file paths', () => {
const input = 'This is not a file path: https://example.com/file.txt';
const expectedOutput = 'This is not a file path: https://example.com/file.txt';
const output = enhancePastedText(input);
expect(output).toEqual(expectedOutput);
});

it('should modify multiple file URLs', () => {
const input = 'This is a file path: file:///Users/john/Documents/file with spaces.txt\nThis is another file path: file:///Users/john/Documents/file with spaces.txt';
const expectedOutput = 'This is a file path: file:///Users/john/Documents/file%20with%20spaces.txt\nThis is another file path: file:///Users/john/Documents/file%20with%20spaces.txt';
const output = enhancePastedText(input);
expect(output).toEqual(expectedOutput);
});

describe('toMarkdownLink is true', () => {
it('should convert to markdown link', () => {
const input = 'This is a file path: file:///Users/john/Documents/file with spaces.txt';
const expectedOutput = 'This is a file path: [file with spaces.txt](file:///Users/john/Documents/file%20with%20spaces.txt)';
const output = enhancePastedText(input, true);
expect(output).toEqual(expectedOutput);
});

it('should convert images to markdown image links', () => {
const input = 'This is a file path: file:///Users/john/Documents/file with spaces.png';
const expectedOutput = 'This is a file path: ![file with spaces.png](file:///Users/john/Documents/file%20with%20spaces.png)';
const output = enhancePastedText(input, true);
expect(output).toEqual(expectedOutput);
});
});
});
25 changes: 25 additions & 0 deletions packages/app-desktop/gui/NoteEditor/utils/textPasteEnhancer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
function enhancePastedText(text: string, toMarkdownLink = false): string {
const FILE_PATH_REGEX = /file:\/\/(\/([\w.]+ ?)+)+/g;

return text.replace(FILE_PATH_REGEX, (match) => {
const fileName = extractFileName(match);
const enhancedText = match.replace(/\s/g, '%20');
if (toMarkdownLink) {
return isImage(fileName) ? `![${fileName}](${enhancedText})` : `[${fileName}](${enhancedText})`;
}
return enhancedText;
});
}

function extractFileName(filePath: string): string {
return filePath.split('/').pop();
}

function isImage(fileName: string): boolean {
const IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp', 'tiff', 'avif', 'pjp'];

const extension = fileName.split('.').pop().toLowerCase();
return IMAGE_EXTENSIONS.includes(extension);
}

export default enhancePastedText;

0 comments on commit 124bcae

Please sign in to comment.