Skip to content

Commit

Permalink
Merge pull request #17 from jesper-bylund/logseq-converter
Browse files Browse the repository at this point in the history
Logseq converter
  • Loading branch information
eirikhm authored Aug 11, 2023
2 parents f40cbc3 + d89970c commit ad16c8b
Show file tree
Hide file tree
Showing 20 changed files with 1,392 additions and 136 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"build": "yarn prepare",
"convert:roam": "yarn build && node --experimental-modules --es-module-specifier-resolution=node dist/runner.js roam",
"convert:workflowy": "yarn build && node --experimental-modules --es-module-specifier-resolution=node dist/runner.js workflowy",
"convert:logseq": "yarn build && node --experimental-modules --es-module-specifier-resolution=node dist/runner.js logseq",
"test": "jest"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { expect, test } from '@jest/globals';
import {
findPreceedingAlias,
getAttributeDefintionsFromName,
getAttributeDefinitionsFromName,
getValueForAttribute,
hasImages,
dateStringToRoamDateUID,
dateStringToUSDateUID,
dateStringToYMD,
} from './roamUtils';
} from './common';

test('getAttributeDefintions', () => {
expect(getAttributeDefintionsFromName('foo::bar')).toEqual(['foo']);
expect(getAttributeDefintionsFromName('[[foo]]::bar')).toEqual(['foo']);
expect(getAttributeDefintionsFromName('**foo:**')).toEqual([]);
expect(getAttributeDefintionsFromName('**foo:**\nbam::bim')).toEqual(['bam']);
expect(getAttributeDefinitionsFromName('foo::bar')).toEqual(['foo']);
expect(getAttributeDefinitionsFromName('[[foo]]::bar')).toEqual(['foo']);
expect(getAttributeDefinitionsFromName('**foo:**')).toEqual([]);
expect(getAttributeDefinitionsFromName('**foo:**\nbam::bim')).toEqual(['bam']);
});

test('findPreceedingAlias', () => {
Expand All @@ -26,18 +26,19 @@ test('getValueForAttribute', () => {
expect(getValueForAttribute('bam', '**foo:**\nbam::bim')).toEqual('bim');
});

test('hasImages', () => {
expect(hasImages('![](https://tana.inc/photo/1)')).toBeTruthy();
expect(hasImages('![](https://tana.inc/photo/1) ![](https://tana.inc/photo/2)')).toBeTruthy();
expect(hasImages('bar ![](https://tana.inc/photo/1) foo ![](https://tana.inc/photo/2) bam')).toBeTruthy();
expect(hasImages('nope')).toBeFalsy();
test('dateStringToUSDateUID', () => {
expect(dateStringToUSDateUID('June 1st, 2021')).toBe('06-01-2021');
expect(dateStringToUSDateUID('August 14th, 2021')).toBe('08-14-2021');
});

test('dateStringToRoamDateUID', () => {
expect(dateStringToRoamDateUID('June 1st, 2021')).toBe('06-01-2021');
expect(dateStringToRoamDateUID('August 14th, 2021')).toBe('08-14-2021');
});
test('dateStringToYMD', () => {
expect(dateStringToYMD('June 1st, 2021')).toBe('2021-06-01');
expect(dateStringToYMD('August 14th, 2021')).toBe('2021-08-14');
});

test('hasImages', () => {
expect(hasImages('![](https://tana.inc/photo/1)')).toBeTruthy();
expect(hasImages('![](https://tana.inc/photo/1) ![](https://tana.inc/photo/2)')).toBeTruthy();
expect(hasImages('bar ![](https://tana.inc/photo/1) foo ![](https://tana.inc/photo/2) bam')).toBeTruthy();
expect(hasImages('nope')).toBeFalsy();
});
109 changes: 109 additions & 0 deletions src/converters/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
export function hasField(node: string) {
return node.includes('::');
}

export function hasImages(name: string) {
return name.includes('![](https://');
}

const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
];

const monthPrefixes = months.map((m) => m.slice(0, 3))

// Convert 'June 1st, 2021' and 'Jun 1st, 2021' to 'MM-DD-YYYY' without dealing with timezones, etc.
export function dateStringToUSDateUID(str: string) {
str = str.replace(/(^\w+\s\d{1,2})(\w{2}),(\s\d+)/, '$1$3');
const pieces = str.split(' ');

const monthMatch = months.indexOf(pieces[0]);
const monthPrefixMatch = monthPrefixes.indexOf(pieces[0]);
let month
if (monthMatch !== -1) {
month = monthMatch + 1
} else if (monthPrefixMatch !== -1) {
month = monthPrefixMatch + 1
} else {
return str
}

return `${month.toString().padStart(2, '0')}-${pieces[1].toString().padStart(2, '0')}-${pieces[2]
.toString()
.padStart(4, '0')}`;
}

// Convert 'June 1st, 2021' to 'YYYY-MM-DD' without dealing with timezones etc
export function dateStringToYMD(str: string) {
str = str.replace(/(^\w+\s\d{1,2})(\w{2}),(\s\d+)/, '$1$3');
const pieces = str.split(' ');
const month = months.indexOf(pieces[0]) + 1;
return `${pieces[2].toString().padStart(4, '0')}-${month.toString().padStart(2, '0')}-${pieces[1]
.toString()
.padStart(2, '0')}`;
}

export function getValueForAttribute(fieldName: string, node: string): string | undefined {
if (!node.includes('::')) {
return undefined;
}
for (const line of node.split('\n')) {
// foo::bar
if (line.startsWith(`${fieldName}::`)) {
return line.split(`${fieldName}::`)[1].trim();
} else if (line.startsWith(`[[${fieldName}]]:`)) {
return line.split(`[[${fieldName}]]::`)[1].trim();
}
}
}

// Finds attribute defintions like Foo::
export function getAttributeDefinitionsFromName(node: string): string[] {
// quicker than regex
if (!node.includes('::')) {
return [];
}

const attrDefs: string[] = [];
for (const line of node.split('\n')) {
if (line.startsWith('`')) {
continue;
}
const attrMatch = line.match(/^(.+)::/i);
if (attrMatch && attrMatch[1]) {
attrDefs.push(attrMatch[1].replace('[[', '').replace(']]', ''));
continue;
}
}

return attrDefs;
}

export function findPreceedingAlias(nodeName: string, aliasEndIndex: number): string | undefined {
let alias = undefined;
let aliasStartIndex = undefined;
if (nodeName[aliasEndIndex] === ']') {
for (let i = aliasEndIndex; i >= 0; i--) {
if (nodeName[i] === '[') {
aliasStartIndex = i + 1; // skip the '['
break;
}
}

if (aliasStartIndex) {
alias = nodeName.substring(aliasStartIndex, aliasEndIndex);
}
}
return alias;
}
Loading

0 comments on commit ad16c8b

Please sign in to comment.