Skip to content

Commit

Permalink
Merge pull request #1 from hereistheusername/test/modify-createUpdate…
Browse files Browse the repository at this point in the history
…LinkEdit-accomplish-convert

modify createUpdateLinkEdit to accomplish convert
  • Loading branch information
hereistheusername authored Jul 4, 2024
2 parents 18dbbb5 + 7af316b commit e8e3c2a
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ describe('generateStdMdLink', () => {
'[first-document](first-document.md)',
'[second-document](second-document.md)',
'[[non-exist-file]]',
'[#one section](<#one section>)',
'[another name](<#one section>)',
'[#one section](<file-with-different-link-formats.md#one section>)',
'[another name](<file-with-different-link-formats.md#one section>)',
'[an alias](first-document.md)',
'[first-document](first-document.md)',
];
Expand Down
44 changes: 12 additions & 32 deletions packages/foam-vscode/src/core/janitor/convert-links-format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ export function convertLinkFormat(

let { target, section, alias } = MarkdownLink.analyzeLink(link);
let sectionDivider = section ? '#' : '';
let aliasDivider = alias ? '|' : '';
let embed = link.isEmbed ? '!' : '';

if (isNone(targetUri)) {
throw new Error(
Expand All @@ -53,16 +51,10 @@ export function convertLinkFormat(
let relativeUri = targetRes.uri.relativeTo(resource.uri.getDirectory());

if (targetFormat === 'wikilink') {
/* remove extension if possible, then get the basename to prevent from filename conflict */
if (relativeUri.path.endsWith(workspace.defaultExtension)) {
relativeUri = relativeUri.changeExtension('*', '');
}
target = relativeUri.getBasename();

return {
newText: `${embed}[[${target}${sectionDivider}${section}${aliasDivider}${alias}]]`,
range: link.range,
};
return MarkdownLink.createUpdateLinkEdit(link, {
target: workspace.getIdentifier(relativeUri),
type: 'wikilink',
});
}

if (targetFormat === 'link') {
Expand All @@ -75,27 +67,15 @@ export function convertLinkFormat(
alias = `${target}${sectionDivider}${section}`;
}

/* construct url */
let url = relativeUri.path;
/* in page anchor have no filename */
if (relativeUri.getBasename() === resource.uri.getBasename()) {
url = '';
}
if (sectionDivider === '#') {
url = `${url}${sectionDivider}${section}`;
}
if (url.indexOf(' ') > 0) {
url = `<${url}>`;
}

/* if it's originally an embedded note, the markdown link shouldn't be embedded */
if (embed && targetRes.type === 'note') {
embed = '';
}
return {
newText: `${embed}[${alias}](${url})`,
range: link.range,
};
const isEmbed = targetRes.type === 'image' ? link.isEmbed : false;

return MarkdownLink.createUpdateLinkEdit(link, {
alias: alias,
target: relativeUri.path,
isEmbed: isEmbed,
type: 'link',
});
}
throw new Error(
`Unexpected state: targetFormat: ${targetFormat} is not supported`
Expand Down
181 changes: 181 additions & 0 deletions packages/foam-vscode/src/core/services/markdown-link.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,4 +254,185 @@ describe('MarkdownLink', () => {
expect(edit.range).toEqual(link.range);
});
});

describe('convert wikilink to link', () => {
it('should generate default alias if no one', () => {
const wikilink = parser.parse(getRandomURI(), `[[wikilink]]`).links[0];
const wikilinkEdit = MarkdownLink.createUpdateLinkEdit(wikilink, {
type: 'link',
});
expect(wikilinkEdit.newText).toEqual(`[wikilink](wikilink)`);
expect(wikilinkEdit.range).toEqual(wikilink.range);

const wikilinkWithSection = parser.parse(
getRandomURI(),
`[[wikilink#section]]`
).links[0];
const wikilinkWithSectionEdit = MarkdownLink.createUpdateLinkEdit(
wikilinkWithSection,
{
type: 'link',
}
);
expect(wikilinkWithSectionEdit.newText).toEqual(
`[wikilink#section](wikilink#section)`
);
expect(wikilinkWithSectionEdit.range).toEqual(wikilinkWithSection.range);
});

it('should use alias in the wikilik the if there has one', () => {
const wikilink = parser.parse(
getRandomURI(),
`[[wikilink#section|alias]]`
).links[0];
const wikilinkEdit = MarkdownLink.createUpdateLinkEdit(wikilink, {
type: 'link',
});
expect(wikilinkEdit.newText).toEqual(`[alias](wikilink#section)`);
expect(wikilinkEdit.range).toEqual(wikilink.range);
});
});

describe('convert link to wikilink', () => {
it('should reorganize target, section, and alias in wikilink manner', () => {
const link = parser.parse(getRandomURI(), `[link](to/path.md)`).links[0];
const linkEdit = MarkdownLink.createUpdateLinkEdit(link, {
type: 'wikilink',
});
expect(linkEdit.newText).toEqual(`[[to/path.md|link]]`);
expect(linkEdit.range).toEqual(link.range);

const linkWithSection = parser.parse(
getRandomURI(),
`[link](to/path.md#section)`
).links[0];
const linkWithSectionEdit = MarkdownLink.createUpdateLinkEdit(
linkWithSection,
{
type: 'wikilink',
}
);
expect(linkWithSectionEdit.newText).toEqual(
`[[to/path.md#section|link]]`
);
expect(linkWithSectionEdit.range).toEqual(linkWithSection.range);
});

it('should use alias in the wikilik the if there has one', () => {
const wikilink = parser.parse(
getRandomURI(),
`[[wikilink#section|alias]]`
).links[0];
const wikilinkEdit = MarkdownLink.createUpdateLinkEdit(wikilink, {
type: 'link',
});
expect(wikilinkEdit.newText).toEqual(`[alias](wikilink#section)`);
expect(wikilinkEdit.range).toEqual(wikilink.range);
});
});

describe('convert to its original type', () => {
it('should remaind unchanged', () => {

Check warning on line 335 in packages/foam-vscode/src/core/services/markdown-link.test.ts

View workflow job for this annotation

GitHub Actions / Spell Check with Typos

"remaind" should be "remained".
const link = parser.parse(getRandomURI(), `[link](to/path.md#section)`)
.links[0];
const linkEdit = MarkdownLink.createUpdateLinkEdit(link, {
type: 'link',
});
expect(linkEdit.newText).toEqual(`[link](to/path.md#section)`);
expect(linkEdit.range).toEqual(link.range);

const wikilink = parser.parse(
getRandomURI(),
`[[wikilink#section|alias]]`
).links[0];
const wikilinkEdit = MarkdownLink.createUpdateLinkEdit(wikilink, {
type: 'wikilink',
});
expect(wikilinkEdit.newText).toEqual(`[[wikilink#section|alias]]`);
expect(wikilinkEdit.range).toEqual(wikilink.range);
});
});

describe('change isEmbed property', () => {
it('should change isEmbed only', () => {
const wikilink = parser.parse(getRandomURI(), `[[wikilink]]`).links[0];
const wikilinkEdit = MarkdownLink.createUpdateLinkEdit(wikilink, {
isEmbed: true,
});
expect(wikilinkEdit.newText).toEqual(`![[wikilink]]`);
expect(wikilinkEdit.range).toEqual(wikilink.range);

const link = parser.parse(getRandomURI(), `![link](to/path.md)`).links[0];
const linkEdit = MarkdownLink.createUpdateLinkEdit(link, {
isEmbed: false,
});
expect(linkEdit.newText).toEqual(`[link](to/path.md)`);
expect(linkEdit.range).toEqual(link.range);
});

it('should be unchanged if the update value is the same as the original one', () => {
const embeddedWikilink = parser.parse(getRandomURI(), `![[wikilink]]`)
.links[0];
const embeddedWikilinkEdit = MarkdownLink.createUpdateLinkEdit(
embeddedWikilink,
{
isEmbed: true,
}
);
expect(embeddedWikilinkEdit.newText).toEqual(`![[wikilink]]`);
expect(embeddedWikilinkEdit.range).toEqual(embeddedWikilink.range);

const link = parser.parse(getRandomURI(), `[link](to/path.md)`).links[0];
const linkEdit = MarkdownLink.createUpdateLinkEdit(link, {
isEmbed: false,
});
expect(linkEdit.newText).toEqual(`[link](to/path.md)`);
expect(linkEdit.range).toEqual(link.range);
});
});

describe('insert angles', () => {
it('should insert angles when meeting space in links', () => {
const link = parser.parse(getRandomURI(), `![link](to/path.md)`).links[0];
const linkAddSection = MarkdownLink.createUpdateLinkEdit(link, {
section: 'one section',
});
expect(linkAddSection.newText).toEqual(
`![link](<to/path.md#one section>)`
);
expect(linkAddSection.range).toEqual(link.range);

const linkChangingTarget = parser.parse(
getRandomURI(),
`[link](to/path.md#one-section)`
).links[0];
const linkEdit = MarkdownLink.createUpdateLinkEdit(linkChangingTarget, {
target: 'to/another path.md',
});
expect(linkEdit.newText).toEqual(
`[link](<to/another path.md#one-section>)`
);
expect(linkEdit.range).toEqual(linkChangingTarget.range);

const wikilink = parser.parse(getRandomURI(), `[[wikilink#one section]]`)
.links[0];
const wikilinkEdit = MarkdownLink.createUpdateLinkEdit(wikilink, {
type: 'link',
});
expect(wikilinkEdit.newText).toEqual(
`[wikilink#one section](<wikilink#one section>)`
);
expect(wikilinkEdit.range).toEqual(wikilink.range);
});

it('should not insert angles in wikilink', () => {
const wikilink = parser.parse(getRandomURI(), `[[wikilink#one section]]`)
.links[0];
const wikilinkEdit = MarkdownLink.createUpdateLinkEdit(wikilink, {
target: 'another wikilink',
});
expect(wikilinkEdit.newText).toEqual(`[[another wikilink#one section]]`);
expect(wikilinkEdit.range).toEqual(wikilink.range);
});
});
});
28 changes: 20 additions & 8 deletions packages/foam-vscode/src/core/services/markdown-link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,41 @@ export abstract class MarkdownLink {

public static createUpdateLinkEdit(
link: ResourceLink,
delta: { target?: string; section?: string; alias?: string }
delta: {
target?: string;
section?: string;
alias?: string;
type?: 'wikilink' | 'link';
isEmbed?: boolean;
}
) {
const { target, section, alias } = MarkdownLink.analyzeLink(link);
const newTarget = delta.target ?? target;
const newSection = delta.section ?? section ?? '';
const newAlias = delta.alias ?? alias ?? '';
const sectionDivider = newSection ? '#' : '';
const aliasDivider = newAlias ? '|' : '';
const embed = link.isEmbed ? '!' : '';
if (link.type === 'wikilink') {
const embed = delta.isEmbed ?? link.isEmbed ? '!' : '';
const type = delta.type ?? link.type;
if (type === 'wikilink') {
return {
newText: `${embed}[[${newTarget}${sectionDivider}${newSection}${aliasDivider}${newAlias}]]`,
range: link.range,
};
}
if (link.type === 'link') {
if (type === 'link') {
const defaultAlias = () => {
return `${newTarget}${sectionDivider}${newSection}`;
};
const useAngles =
newTarget.indexOf(' ') > 0 || newSection.indexOf(' ') > 0;
return {
newText: `${embed}[${newAlias}](${newTarget}${sectionDivider}${newSection})`,
newText: `${embed}[${newAlias ? newAlias : defaultAlias()}](${
useAngles ? '<' : ''
}${newTarget}${sectionDivider}${newSection}${useAngles ? '>' : ''})`,
range: link.range,
};
}
throw new Error(
`Unexpected state: link of type ${link.type} is not supported`
);
throw new Error(`Unexpected state: link of type ${type} is not supported`);
}
}

0 comments on commit e8e3c2a

Please sign in to comment.