uniorg-attach
Version:
Uniorg plugin to process org-attach attachment links
78 lines • 2.73 kB
JavaScript
import path from 'path';
import { visitParents } from 'unist-util-visit-parents';
const defaultOptions = {
idDir: 'data/',
// TODO: default value in Emacs is 'selective
useInheritance: false,
idToPath: idUuidFolderFormat,
};
/**
* Translate an UUID ID into a folder-path. Default format for how Org
* translates ID properties to a path for attachments. Useful if ID is
* generated with UUID.
*
* Corresponds to `org-attach-id-uuid-folder-format` in Emacs.
*/
export function idUuidFolderFormat(id) {
return path.join(id.substring(0, 2), id.substring(2));
}
/**
* Translate an ID based on a timestamp to a folder-path. Useful way
* of translation if ID is generated based on ISO8601 timestamp.
* Splits the attachment folder hierarchy into year-month, the rest.
*
* Corresponds to `org-attach-id-ts-folder-format` in Emacs.
*/
export function idTsFolderFormat(id) {
return path.join(id.substring(0, 6), id.substring(6));
}
export const uniorgAttach = (options = {}) => {
const opts = { ...defaultOptions, ...options };
return transformer;
function transformer(tree, file) {
visitParents(tree, 'link', (link, ancestors) => {
if (link.linkType === 'attachment') {
const path = resolveAttachmentPath(link, ancestors, file, opts);
link.linkType = 'file';
link.path = path;
link.rawLink = link.linkType + ':' + link.path;
}
});
}
};
export default uniorgAttach;
function resolveAttachmentPath(link, ancestors, file, options) {
if (path.isAbsolute(link.path)) {
// Link is already absolute. Ignore any attachment directory.
return link.path;
}
const dir = getProperty(ancestors, 'DIR', options.useInheritance);
if (dir) {
return path.join(dir, link.path);
}
const id = getProperty(ancestors, 'ID', options.useInheritance);
if (id) {
const directory = options.idToPath(id);
return path.join(options.idDir, directory, link.path);
}
return link.path;
}
function getProperty(ancestors, property, useInheritance) {
ancestors = [...ancestors];
do {
let parent = ancestors.pop();
while (parent && parent.type !== 'section' && parent.type !== 'org-data') {
parent = ancestors.pop();
}
if (!parent) {
return null;
}
const properties = parent.children.find((n) => n.type === 'property-drawer');
const value = properties?.children.find((p) => p.key === property)?.value;
if (value !== undefined) {
return value;
}
} while (useInheritance);
return null;
}
//# sourceMappingURL=index.js.map