const STATUS_MAP = {
'todo': '👀',
'reading': '🤓',
'read': '✅',
'ditched': '☠',
'paused': '⏸',
};
const TOPIC_MAP = [
{tag: 'politics', icon: '🏁'},
{tag: 'scifi', icon: '🪐'},
{tag: 'urbanism', icon: '🌇'},
{tag: 'business', icon: '💰'},
{tag: 'sailing', icon: '⛵️'},
{tag: 'history', icon: '⏳'},
{tag: 'lifestyle', icon: '💅'},
{tag: 'novel', icon: '🎭'},
{tag: 'cooking', icon: '🍽'},
{tag: 'sustainability', icon: '🍃'},
{tag: 'fiction', icon: '🧠'},
{tag: 'nonfiction', icon: '📜'},
];
const STATUS_SORT = ['reading', 'todo', 'paused', 'read', 'ditched']
.reverse()
.reduce((obj, status, index) => ({...obj, [status]: index}));
const determineTopic = (tags) => {
tags = new Set(tags);
const icon = TOPIC_MAP.find(({tag, icon}) => tags.has(tag));
return icon?.icon || '📖';
};
const DATE_REGEX = /([0-9]{4})\-([0-9]{2})-([0-9]{2})/;
const dateFmt = (dt) => {
if (!dt) return '\\-';
const split = dt.toString().split('-');
return `${split[0]}-${split[1]}`;
};
const books = dv.pages('#books')
.sort((p) => p, 'asc', (a, b) => {
const statusA = STATUS_SORT[a.status] || -1;
const statusB = STATUS_SORT[b.status] || -1;
if (statusA > statusB) return -1;
if (statusA < statusB) return 1;
const dateA = a.started;
const dateB = b.started;
if (!dateA) return 1;
if (!dateB) return -1;
if (dateA.ts > dateB.ts) return -1;
if (dateA.ts < dateB.ts) return 1;
return 0;
})
.map((page) => {
const title = page.file.name.replace(/[0-9]*/, '');
const status = STATUS_MAP[page.status] || '❓';
const topic = determineTopic(page.tags);
return [
status,
`[[${page.file.name}|${title}]]`,
topic,
dateFmt(page.started),
dateFmt(page.completed),
];
});
dv.table(['', 'Name', '', 'Started', 'Completed'], books);