kdenote/lib/denote_metadata.cpp

124 lines
3.4 KiB
C++

#include "denote_metadata.h"
#include <QFileInfo>
#include <QRegularExpression>
namespace Denote {
QDateTime Metadata::creationDate() const
{
if (identifier.isEmpty())
return {};
return QDateTime::fromString(identifier, QStringLiteral("yyyyMMdd'T'HHmmss"));
}
Metadata parseFilename(const QString &path)
{
Metadata meta;
meta.path = path;
const QString fname = QFileInfo(path).fileName();
// Identifier: leading YYYYMMDDTHHMMSS
static const QRegularExpression reId(QStringLiteral("^(\\d{8}T\\d{6})"));
auto m = reId.match(fname);
if (m.hasMatch())
meta.identifier = m.captured(1);
// Signature: ==sig-- (between identifier and title)
static const QRegularExpression reSig(QStringLiteral("==([^-]+?)--"));
m = reSig.match(fname);
if (m.hasMatch())
meta.signature = m.captured(1);
// Title: --title (first -- delimited segment, before __ or .)
static const QRegularExpression reTitle(QStringLiteral("--([^_\\.]+)"));
m = reTitle.match(fname);
if (m.hasMatch()) {
QString raw = m.captured(1);
raw.replace(QLatin1Char('-'), QLatin1Char(' '));
meta.title = raw;
}
// Tags: __tag1_tag2 (before extension or end)
static const QRegularExpression reTags(QStringLiteral("__(.+?)(?:\\.|$)"));
m = reTags.match(fname);
if (m.hasMatch()) {
meta.tags = m.captured(1).split(QLatin1Char('_'), Qt::SkipEmptyParts);
}
return meta;
}
QString generateIdentifier()
{
return QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd'T'HHmmss"));
}
QString slugifyTitle(const QString &title)
{
QString slug = title.toLower();
slug.replace(QLatin1Char(' '), QLatin1Char('-'));
slug.replace(QLatin1Char('_'), QLatin1Char('-'));
// Remove anything that isn't a-z, 0-9, or hyphen
static const QRegularExpression reClean(QStringLiteral("[^a-z0-9-]"));
slug.remove(reClean);
return slug;
}
bool isValidTag(const QString &tag)
{
if (tag.isEmpty())
return false;
for (const QChar &ch : tag) {
if (!ch.isLetterOrNumber())
return false;
if (ch.isLetter() && ch.isUpper())
return false;
}
return true;
}
QString buildFilename(const QString &title,
const QStringList &tags,
const QString &signature,
const QString &ext)
{
QString result = generateIdentifier();
// Signature
if (!signature.isEmpty()) {
QString sig = signature.toLower();
sig.replace(QLatin1Char(' '), QStringLiteral("=="));
sig.replace(QLatin1Char('_'), QStringLiteral("=="));
// Remove special chars
static const QRegularExpression reSigClean(
QStringLiteral("[{}!@#$%^&*()+\'\"?,.\\\\|;:~`\u2018\u2019\u201c\u201d/-]"));
sig.remove(reSigClean);
// Normalize consecutive equals
static const QRegularExpression reEq(QStringLiteral("={3,}"));
sig.replace(reEq, QStringLiteral("=="));
// Trim trailing =
while (sig.endsWith(QLatin1Char('=')))
sig.chop(1);
result += QStringLiteral("==") + sig;
}
// Title
result += QStringLiteral("--") + slugifyTitle(title);
// Tags
if (!tags.isEmpty()) {
result += QStringLiteral("__") + tags.join(QLatin1Char('_'));
}
// Extension
result += ext;
return result;
}
} // namespace Denote