Skip to content

Instantly share code, notes, and snippets.

@AnonymerNiklasistanonym
Last active February 28, 2019 05:01
Show Gist options
  • Save AnonymerNiklasistanonym/b790c7d09103352a4b4cdfecefa76bad to your computer and use it in GitHub Desktop.
Save AnonymerNiklasistanonym/b790c7d09103352a4b4cdfecefa76bad to your computer and use it in GitHub Desktop.
Extract used image resources from a note written in Notable (https://github.com/notable/notable) via a CLI node script
const fs = require('fs')
const colors = require('colors')
/**
* Info option, when true enable performance tracking and other infos
*/
let enableInfo = false
/**
* JSON option, return image paths in JSON format
*/
let enableJson = false
/**
* CLI Help output
*/
const helpOutput = () => {
console.log('Description:\n' +
'\tScraps Markdown note created with Notable for used resources to\n' +
'\texport it even when some attachments were forgotten')
console.log('Example:\n\t$ node ' +
colors.yellow('.\\notableNoteGetImgs.js ') +
colors.green('filePath.md ') +
colors.magenta('-enableOptionalOption') +
'\n\tattachments:[test.svg,test.png]')
console.log('Options:\n' + '\t-info\t' +
colors.grey('Get information about performance and other things') +
'\n\t-json\t' +
colors.grey('Get all image paths in JSON format'))
}
/**
* CLI Version output
*/
const versionOutput = () => {
console.log('0.0.6')
}
// Check if a file was given
if (process.argv.length < 3) {
console.error('No file path specified!\n')
helpOutput()
process.exit(1)
}
// Check if options are correct
if (process.argv.length >= 4) {
for (let i = 3; i < process.argv.length; i++) {
if (process.argv[i] === '-json') {
enableJson = true
} else if (process.argv[i] === '-info') {
enableInfo = true
} else {
console.error(`Unknown option: "${colors.red(process.argv[i])}"\n`)
helpOutput()
process.exit(1)
}
}
}
// Check if instead of a file help/version is wanted
if (process.argv[2] === '--help' ||
process.argv[2] === '-help' ||
process.argv[2] === 'help') {
helpOutput()
process.exit(0)
} else if (process.argv[2] === '--version' ||
process.argv[2] === '-version' ||
process.argv[2] === 'version') {
versionOutput()
process.exit(0)
}
/**
* File path file
*/
const filePath = process.argv[2]
// Check if file exists
if (!fs.existsSync(filePath)) {
console.error(`File was not found: "${colors.red(filePath)}"\n`)
helpOutput()
process.exit(1)
}
/**
* Regex to find image resources
* ```js
* const aString = '<img src="@attachment/test.svg" >' +
* '<img src="@attachment/test.png" >'
* let match = regexImageResource.exec(aString)
* while (match !== null) {
* // test.svg, test.png
* console.log(match[1])
* match = regexImageResource.exec(aString)
* }
* ```
*/
const regexImageResource = /<img .*?src="@attachment\/(.*?)" .*?>/g
/**
* Get all connected resources
* @param {string} fileContent The file content string
*/
function extractConnectedResources (fileContent) {
const matches = []
// Extract all image resources
let match = regexImageResource.exec(fileContent)
while (match !== null) {
matches.push(match[1])
match = regexImageResource.exec(fileContent)
}
// Return all matches
return matches
}
/**
* Extract all matches from the file via a fs.stream (much faster
* when executing on large files)
* @param {string} filePath File that should be read
* @returns {Promise<string[]>} Array with all found attachments
*/
async function extractMatchesFromFileViaStream (filePath) {
return new Promise((resolve, reject) => {
const label = `extractMatchesFromFileViaStream (${filePath})`
if (enableInfo) { console.time(label) }
const matches = []
const stream = fs.createReadStream(filePath, { encoding: 'utf8' })
stream.on('data', data => {
matches.push(...extractConnectedResources(data))
stream.destroy()
}).on('error', err => {
if (enableInfo) { console.timeEnd(label) }
reject(err)
}).on('close', () => {
const uniqueMatches = [...new Set(matches)]
if (enableInfo) { console.timeEnd(label) }
resolve(uniqueMatches)
})
})
}
// MAIN
// Get matches
extractMatchesFromFileViaStream(filePath)
.then(matches => {
// Format found matches for a string that can be copy-pasted
if (enableJson) {
console.log(JSON.stringify({ imagePaths: matches }, null, 0))
} else {
console.log('attachments:[' + matches.join(',') + ']')
}
})
.catch(console.error)
Description:
Scraps Markdown note created with Notable for used resources to
export it even when some attachments were forgotten
Example:
$ node .\notableNoteGetImgs.js filePath.md -enableOptionalOption
attachments:[test.svg,test.png]
Options:
-info Get information about performance and other things
-json Get all image paths in JSON format
title tags created modified attachments
A title
Notebooks/Test
2019-02-17T19:54:53.942Z
2019-02-19T16:27:42.872Z
test.svg

A title

Another section

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment