Skip to content

Commit

Permalink
FindPropIdx() => GetPropIdx(); FindProp() => GetPropValueTemp(); add …
Browse files Browse the repository at this point in the history
…GetMatchingString() and use it
  • Loading branch information
kjk committed May 23, 2024
1 parent 2ce4000 commit d2d7622
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 85 deletions.
29 changes: 21 additions & 8 deletions src/DocProperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,33 +24,33 @@ int PropsCount(const Props& props) {
return n / 2;
}

int FindPropIdx(const Props& props, const char* key) {
int GetPropIdx(const Props& props, const char* name) {
int n = PropsCount(props);
for (int i = 0; i < n; i++) {
int idx = i * 2;
char* v = props.At(idx);
if (str::Eq(v, key)) {
if (str::Eq(v, name)) {
return idx;
}
}
return -1;
}

char* FindProp(const Props& props, const char* key) {
int idx = FindPropIdx(props, key);
char* GetPropValueTemp(const Props& props, const char* name) {
int idx = GetPropIdx(props, name);
if (idx < 0) {
return nullptr;
}
char* v = props.At(idx);
return v;
}

void AddProp(Props& props, const char* key, const char* val, bool replaceIfExists) {
CrashIf(!key || !val);
int idx = FindPropIdx(props, key);
void AddProp(Props& props, const char* name, const char* val, bool replaceIfExists) {
CrashIf(!name || !val);
int idx = GetPropIdx(props, name);
if (idx < 0) {
// doesn't exsit
props.Append(key);
props.Append(name);
props.Append(val);
return;
}
Expand All @@ -59,3 +59,16 @@ void AddProp(Props& props, const char* key, const char* val, bool replaceIfExist
}
props.SetAt(idx + 1, val);
}

// strings are pairs of str1, str2 laid in sequence, with nullptr to mark the en
// we find str1 matching s and return str2 or nullptr if not found
const char* GetMatchingString(const char** strings, const char* s) {
while (*strings) {
const char* str1 = *strings++;
const char* str2 = *strings++;
if (str1 == s || str::Eq(str1, s)) {
return str2;
}
}
return nullptr;
}
10 changes: 6 additions & 4 deletions src/DocProperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ extern const char* kPropPdfVersion;
extern const char* kPropPdfProducer;
extern const char* kPropPdfFileStructure;

// Props are stored in StrVec as key, value sequentially
// Props are stored in StrVec as name, value sequentially
using Props = StrVec;
int PropsCount(const Props& props);
int FindPropIdx(const Props& props, const char* key);
char* FindProp(const Props& props, const char* key);
void AddProp(Props& props, const char* key, const char* val, bool replaceIfExists = false);
int GetPropIdx(const Props& props, const char* name);
char* GetPropValueTemp(const Props& props, const char* name);
void AddProp(Props& props, const char* name, const char* val, bool replaceIfExists = false);

const char* GetMatchingString(const char**, const char*);
62 changes: 39 additions & 23 deletions src/EbookDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,16 +455,29 @@ bool EpubDoc::Load() {
return htmlData.size() > 0;
}

void EpubDoc::ParseMetadata(const char* content) {
static struct {
const char* prop;
const char* name;
} metadataMap[] = {
{kPropTitle, "dc:title"}, {kPropAuthor, "dc:creator"},
{kPropCreationDate, "dc:date"}, {kPropModificationDate, "dcterms:modified"},
{kPropSubject, "dc:description"}, {kPropCopyright, "dc:rights"},
};
// clang-format off
static const char* epubPropsMap[] = {
kPropTitle, "dc:title",
kPropAuthor, "dc:creator",
kPropCreationDate, "dc:date",
kPropModificationDate, "dcterms:modified",
kPropSubject, "dc:description",
kPropCopyright, "dc:rights",
};
// clang-format on

static bool IsTokPropName(HtmlToken* tok, const char* name) {
if (tok->NameIs(name)) {
return true;
}
if (Tag_Meta != tok->tag) {
return false;
}
AttrInfo* attr = tok->GetAttrByName("property");
return attr && attr->ValIs(name);
}

void EpubDoc::ParseMetadata(const char* content) {
HtmlPullParser pullParser(content, str::Len(content));
int insideMetadata = 0;
HtmlToken* tok;
Expand All @@ -482,19 +495,22 @@ void EpubDoc::ParseMetadata(const char* content) {
continue;
}

for (int i = 0; i < dimof(metadataMap); i++) {
int nProps = dimofi(epubPropsMap) / 2;
for (int i = 0; i < nProps; i++) {
int idx = i * 2;
const char* epubName = epubPropsMap[idx + 1];
// TODO: implement proper namespace support
if (tok->NameIs(metadataMap[i].name) || Tag_Meta == tok->tag && tok->GetAttrByName("property") &&
tok->GetAttrByName("property")->ValIs(metadataMap[i].name)) {
tok = pullParser.Next();
if (tok && tok->IsText()) {
auto prop = metadataMap[i].prop;
char* val = ResolveHtmlEntities(tok->s, tok->sLen);
AddProp(props, prop, val);
str::Free(val);
}
break;
if (!IsTokPropName(tok, epubName)) {
continue;
}
tok = pullParser.Next();
if (tok && tok->IsText()) {
auto prop = epubPropsMap[idx];
char* val = ResolveHtmlEntities(tok->s, tok->sLen);
AddProp(props, prop, val);
str::Free(val);
}
break;
}
}
}
Expand Down Expand Up @@ -572,7 +588,7 @@ ByteSlice EpubDoc::GetFileData(const char* relPath, const char* pagePath) {
}

TempStr EpubDoc::GetPropertyTemp(const char* name) const {
return FindProp(props, name);
return GetPropValueTemp(props, name);
}

const char* EpubDoc::GetFileName() const {
Expand Down Expand Up @@ -987,7 +1003,7 @@ ByteSlice* Fb2Doc::GetCoverImage() const {
}

TempStr Fb2Doc::GetPropertyTemp(const char* name) const {
return FindProp(props, name);
return GetPropValueTemp(props, name);
}

const char* Fb2Doc::GetFileName() const {
Expand Down Expand Up @@ -1345,7 +1361,7 @@ ByteSlice HtmlDoc::LoadURL(const char* url) {
}

TempStr HtmlDoc::GetPropertyTemp(const char* name) const {
return FindProp(props, name);
return GetPropValueTemp(props, name);
}

const char* HtmlDoc::GetFileName() const {
Expand Down
2 changes: 1 addition & 1 deletion src/EbookFormatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

/* formatting extensions for Mobi */

class MobiDoc;
struct MobiDoc;

class MobiFormatter : public HtmlFormatter {
// accessor to images (and other format-specific data)
Expand Down
39 changes: 13 additions & 26 deletions src/EngineMupdf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3313,36 +3313,23 @@ TempStr EngineMupdf::ExtractFontListTemp() {
return JoinTemp(fonts, "\n");
}

// TODO: map via char*[]
static const char* DocumentPropertyToMupdfMetadataKey(const char* name) {
if (str::Eq(name, kPropTitle)) {
return FZ_META_INFO_TITLE;
}
if (str::Eq(name, kPropAuthor)) {
return FZ_META_INFO_AUTHOR;
}
if (str::Eq(name, kPropSubject)) {
return "info:Subject";
}
if (str::Eq(name, kPropPdfProducer)) {
return FZ_META_INFO_PRODUCER;
}
if (str::Eq(name, kPropCreatorApp)) {
return "info:Creator"; // not sure if the same meaning
}
if (str::Eq(name, kPropCreationDate)) {
return "info:CreationDate";
}
if (str::Eq(name, kPropModificationDate)) {
return "info:ModDate";
}
return nullptr;
}
// clang-format off
static const char* mupdfPropsMap[] = {
kPropTitle, FZ_META_INFO_TITLE,
kPropAuthor, FZ_META_INFO_AUTHOR,
kPropSubject, "info:Subject",
kPropPdfProducer, FZ_META_INFO_PRODUCER,
kPropCreatorApp, "info:Creator", // not sure if the same meaning
kPropCreationDate, "info:CreationDate",
kPropModificationDate, "info:ModDate",
nullptr,
};
// clang-format on

TempStr EngineMupdf::GetPropertyTemp(const char* name) {
auto ctx = Ctx();

const char* key = DocumentPropertyToMupdfMetadataKey(name);
const char* key = GetMatchingString(mupdfPropsMap, name);
if (key) {
char buf[1024]{};
int bufSize = (int)dimof(buf);
Expand Down
2 changes: 1 addition & 1 deletion src/MobiDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@ ByteSlice MobiDoc::GetHtmlData() const {
}

TempStr MobiDoc::GetPropertyTemp(const char* name) {
char* v = FindProp(props, name);
char* v = GetPropValueTemp(props, name);
if (!v) {
return nullptr;
}
Expand Down
4 changes: 2 additions & 2 deletions src/MobiDoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
class HuffDicDecompressor;
class PdbReader;

class MobiDoc {
struct MobiDoc {
char* fileName = nullptr;

PdbReader* pdbReader = nullptr;
Expand All @@ -25,7 +25,7 @@ class MobiDoc {

HuffDicDecompressor* huffDic = nullptr;

StrVec props;
Props props;

explicit MobiDoc(const char* filePath);

Expand Down
35 changes: 15 additions & 20 deletions src/PdfCreator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,30 +246,25 @@ bool PdfCreator::AddPageFromImageData(const ByteSlice& data, float imgDpi) const
return ok;
}

bool PdfCreator::SetProperty(const char* prop, const char* value) const {
// clang-format off
static const char* pdfCreatorPropsMap[] = {
kPropTitle, "Title",
kPropAuthor, "Author",
kPropSubject, "Subject",
kPropCopyright, "Copyright",
kPropModificationDate, "ModDate",
kPropCreatorApp, "Creator",
kPropPdfProducer, "Producer",
nullptr
};
// clang-format on

bool PdfCreator::SetProperty(const char* propName, const char* value) const {
if (!ctx || !doc) {
return false;
}

// adapted from EngineMupdf::GetProperty
static struct {
const char* prop;
const char* name;
} pdfPropNames[] = {
{kPropTitle, "Title"},
{kPropAuthor, "Author"},
{kPropSubject, "Subject"},
{kPropCopyright, "Copyright"},
{kPropModificationDate, "ModDate"},
{kPropCreatorApp, "Creator"},
{kPropPdfProducer, "Producer"},
};
const char* name = nullptr;
for (int i = 0; i < dimof(pdfPropNames) && !name; i++) {
if (str::Eq(pdfPropNames[i].prop, prop)) {
name = pdfPropNames[i].name;
}
}
const char* name = GetMatchingString(pdfCreatorPropsMap, propName);
if (!name) {
return false;
}
Expand Down

0 comments on commit d2d7622

Please sign in to comment.