forked from Yukaii/quiver-markdown-exporter
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from blue-monk/feature/enhancement
Enhancements, Bug Fixes, Add Testing Environment, and Miscellaneous Improvements
- Loading branch information
Showing
24 changed files
with
1,181 additions
and
557 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -130,4 +130,6 @@ dist | |
.pnp.* | ||
|
||
output/* | ||
!output/.gitkeep | ||
!output/.gitkeep | ||
|
||
testdata/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
FROM node:latest | ||
|
||
ENV SUT=quiver-to-obsidian-exporter-1.1.0.tgz | ||
|
||
RUN apt-get update && apt-get install -y \ | ||
less \ | ||
&& rm -rf /var/lib/apt/lists/* | ||
|
||
COPY testenv/.bashrc /root/.bashrc | ||
|
||
WORKDIR /app | ||
|
||
COPY $SUT /app | ||
|
||
RUN npm install -g /app/$SUT | ||
|
||
CMD ["/bin/bash"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
services: | ||
app: | ||
image: quiver-to-obsidian-exporter | ||
build: | ||
context: . | ||
dockerfile: Dockerfile | ||
volumes: | ||
- ./testdata:/app/testdata | ||
command: tail -f /dev/null |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,44 @@ | ||
{ | ||
"name": "quiver-markdown-exporter", | ||
"version": "1.0.1", | ||
"name": "quiver-to-obsidian-exporter", | ||
"version": "1.1.0", | ||
"description": "Export Quiver library to Obsidian markdown files", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/blue-monk/quiver-to-obsidian-exporter" | ||
}, | ||
"homepage": "https://github.com/blue-monk/quiver-to-obsidian-exporter", | ||
"main": "dist/index.mjs", | ||
"files": [ | ||
"dist" | ||
], | ||
"type": "module", | ||
"bin": { | ||
"quiver-markdown": "dist/index.mjs" | ||
"qvr2obs": "dist/index.mjs" | ||
}, | ||
"engines": { | ||
"node": ">=21.7.3" | ||
}, | ||
"scripts": { | ||
"build": "tsc", | ||
"build": "rm -rf ./dist && tsc", | ||
"prepublishOnly": "npm run build" | ||
}, | ||
"keywords": [], | ||
"author": "", | ||
"license": "ISC", | ||
"license": "MIT", | ||
"devDependencies": { | ||
"@types/node": "^17.0.32", | ||
"@types/turndown": "^5.0.1", | ||
"ts-node": "^10.7.0", | ||
"typescript": "^4.8.0-dev.20220512" | ||
"@types/node": "^20.12.7", | ||
"@types/turndown": "^5.0.4", | ||
"ts-node": "^10.9.2", | ||
"typescript": "^5.4.5" | ||
}, | ||
"dependencies": { | ||
"fast-glob": "^3.2.11", | ||
"fs-extra": "^10.1.0", | ||
"meow": "^10.1.2", | ||
"turndown": "^7.1.1" | ||
"chalk": "^5.3.0", | ||
"cli-progress": "^3.12.0", | ||
"dayjs": "^1.11.10", | ||
"fast-glob": "^3.3.2", | ||
"fs-extra": "^11.2.0", | ||
"meow": "^13.2.0", | ||
"turndown": "^7.1.3", | ||
"utimes": "^5.2.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import fs from "fs-extra"; | ||
|
||
import { getLogger } from './logger.mjs'; | ||
|
||
|
||
const logger = getLogger(); | ||
|
||
|
||
export function assertValidQvlibraryPath(qvlibraryPath: string) { | ||
|
||
if (!fs.existsSync(qvlibraryPath)) { | ||
logger.error(`The specified qvlibraryPath does not exist. [qvlibraryPath=${qvlibraryPath}]`); | ||
process.exit(2); | ||
} | ||
|
||
if (!fs.statSync(qvlibraryPath).isDirectory()) { | ||
logger.error(`The specified qvlibraryPath is not a directory. [qvlibraryPath=${qvlibraryPath}]`); | ||
process.exit(2); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
|
||
|
||
declare global { | ||
interface String { | ||
lastPathComponent(): string; | ||
} | ||
} | ||
|
||
|
||
if (!String.prototype.lastPathComponent) { | ||
String.prototype.lastPathComponent = function () { | ||
|
||
const pathComponents = this.split('/'); | ||
return pathComponents[pathComponents.length - 1]; | ||
}; | ||
} | ||
|
||
export {}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,107 @@ | ||
#!/usr/bin/env node | ||
import meow from 'meow'; | ||
import { convert } from './quiver-markdown.mjs'; | ||
|
||
const cli = meow(` | ||
Usage | ||
$ quiver-markdown <input.qvlibrary> -o <output folder> | ||
import { getLogger } from './logger.mjs'; | ||
import { assertValidQvlibraryPath } from './assertions.mjs'; | ||
import { exportQvlibrary } from './quiver-to-obsidian-exporter.mjs'; | ||
import { AttachmentFolderPolicy, createAttachmentFolderPolicyWithSubfolder, createAttachmentFolderPolicyWithoutSubfolder } from './migration-support/attachment-folder-treatment.mjs'; | ||
|
||
Options | ||
--output, -o Output folder | ||
|
||
Examples | ||
$ quiver-markdown MyLibrary.qvlibrary -o dist | ||
`, { | ||
const logger = getLogger(); | ||
|
||
|
||
const helpText = ` | ||
Usage | ||
$ qvr2obs <input.qvlibrary> -o <output folder> -a <Attachment folder policy> | ||
or | ||
$ qvr2obs <input.qvlibrary> -o <output folder> -a <Attachment folder policy> -n <Attachment subfolder name if needed> | ||
Options | ||
--output, -o: Output folder | ||
--attachmentFolderPolicy, -a: Attachment folder policy (vaultFolder, subfolderUnderVault, sameFolderAsEachFile, subfolderUnderEachFolder). 'subfolderUnderVault' and 'subfolderUnderEachFolder' require subfolder name. | ||
--attachmentSubfolderName, -n: Specify the subfolder name if 'subfolderUnderVault' or 'subfolderUnderEachFolder' is selected as the attachmentFolderPolicy option. | ||
Examples | ||
$ qvr2obs MyNote.qvlibrary -o dest/MyNote -a vaultFolder | ||
$ qvr2obs MyNote.qvlibrary -o dest/MyNote -a subfolderUnderVault -n _attachments | ||
` | ||
|
||
|
||
const args = process.argv.slice(2) | ||
if (args.length === 0) { | ||
meow(helpText, { importMeta: import.meta }).showHelp(); | ||
} | ||
|
||
const cli = meow(helpText, { | ||
importMeta: import.meta, | ||
flags: { | ||
output: { | ||
type: 'string', | ||
alias: 'o', | ||
shortFlag: 'o', | ||
isRequired: true, | ||
}, | ||
attachmentFolderPolicy: { | ||
type: 'string', | ||
choices: ['vaultFolder', 'subfolderUnderVault', 'sameFolderAsEachFile', 'subfolderUnderEachFolder'], | ||
shortFlag: 'a', | ||
isRequired: true, | ||
}, | ||
attachmentSubfolderName: { | ||
type: 'string', | ||
shortFlag: 'n', | ||
isRequired: (flags, input) => { | ||
return (flags.attachmentFolderPolicy as string)?.startsWith('subfolder'); | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
if (cli.input.length < 1) { | ||
console.error('Please provide a qvlibrary file'); | ||
process.exit(1); | ||
logger.error('Please provide a qvlibrary file'); | ||
cli.showHelp(); | ||
} | ||
|
||
if (!cli.flags.output) { | ||
console.error('Please provide an output folder'); | ||
process.exit(1); | ||
logger.error('Please provide an output folder'); | ||
cli.showHelp(); | ||
} | ||
|
||
convert(cli.input[0], cli.flags.output); | ||
if (cli.flags.attachmentFolderPolicy.startsWith('subfolder')) { | ||
if (!cli.flags.attachmentSubfolderName) { | ||
logger.error(`Please provide an Attachment subfolder name with -n option (Because you specified '${cli.flags.attachmentFolderPolicy}' with -i)`); | ||
cli.showHelp(); | ||
} | ||
} | ||
else { | ||
if (cli.flags.attachmentSubfolderName) { | ||
logger.error(`It is not necessary to specify Attachment subfolder name (Because you specified '${cli.flags.attachmentFolderPolicy}' with -i) (or is it a mistake in specifying attachmentFolderPolicy?)`); | ||
cli.showHelp(); | ||
} | ||
} | ||
|
||
|
||
|
||
const qvlibraryPath = cli.input[0] | ||
assertValidQvlibraryPath(qvlibraryPath); | ||
|
||
const outputPath = cli.flags.output | ||
|
||
const attachmentFolderPolicy = createAttachmentFolderPolicy(cli.flags.attachmentFolderPolicy, cli.flags.attachmentSubfolderName) | ||
logger.info(`AttachmentFolderPolicy: { attachmentFolderPolicy=${cli.flags.attachmentFolderPolicy}, attachmentSubfolderName=${cli.flags.attachmentSubfolderName} }`); | ||
|
||
exportQvlibrary(qvlibraryPath, outputPath, attachmentFolderPolicy); | ||
|
||
|
||
function createAttachmentFolderPolicy(policyType: string, subfolderName: string): AttachmentFolderPolicy { | ||
|
||
switch (policyType) { | ||
case 'vaultFolder': | ||
case 'sameFolderAsEachFile': | ||
return createAttachmentFolderPolicyWithoutSubfolder(policyType); | ||
case 'subfolderUnderVault': | ||
case 'subfolderUnderEachFolder': | ||
return createAttachmentFolderPolicyWithSubfolder(policyType, subfolderName); | ||
default: | ||
throw new Error(`Unknown policy type: ${policyType}`); | ||
} | ||
} |
Oops, something went wrong.