aboutsummaryrefslogtreecommitdiffstats
path: root/src/pdf_cnki.c
diff options
context:
space:
mode:
authoryzrh <yzrh@tuta.io>2020-08-14 22:04:26 +0000
committeryzrh <yzrh@tuta.io>2020-08-14 22:04:26 +0000
commit12ecdd71592eccf7bdb6214edbc7318246469c1c (patch)
treefda27e41c37a2345702ad3e90480154d975e426f /src/pdf_cnki.c
downloadmelon-12ecdd71592eccf7bdb6214edbc7318246469c1c.tar.gz
melon-12ecdd71592eccf7bdb6214edbc7318246469c1c.tar.zst
Initial commit.
Diffstat (limited to 'src/pdf_cnki.c')
-rw-r--r--src/pdf_cnki.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/pdf_cnki.c b/src/pdf_cnki.c
new file mode 100644
index 0000000..2dec0b6
--- /dev/null
+++ b/src/pdf_cnki.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2020, yzrh <yzrh@tuta.io>
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cnki.h"
+#include "iconv.h"
+#include "pdf.h"
+
+/*
+ * It will write first, list, and count to *stat
+ * so that when called recursively, it knows
+ * what to do
+ */
+static int
+_outline(pdf_object_t **pdf, object_outline_tree_t **outline_tree, int id, int **stat)
+{
+ *stat = malloc(3 * sizeof(int));
+
+ if (*stat == NULL)
+ return 1;
+
+ int size;
+ char *str;
+
+ int *ret;
+
+ char buf[64];
+ char dictionary[1024];
+
+ object_outline_tree_t *ptr = *outline_tree;
+
+ (*stat)[0] = ptr->id;
+ (*stat)[2] = 0;
+
+ while (ptr != NULL) {
+ memset(dictionary, 0, 1024);
+
+ strcat(dictionary, "<<\n");
+
+ size = 512;
+ str = NULL;
+
+ if (strconv(&str, "UTF-16BE",
+ ptr->item->title, "GB18030",
+ &size) == 0) {
+ strcat(dictionary, "/Title <feff");
+
+ for (int i = 0; i < size; i++) {
+ snprintf(buf, 64, "%02x", (unsigned char) str[i]);
+ strcat(dictionary, buf);
+ }
+
+ strcat(dictionary, ">\n");
+ }
+
+ free(str);
+
+ snprintf(buf, 64, "/Parent %d 0 R\n", id);
+ strcat(dictionary, buf);
+
+ if (ptr->up != NULL && ptr->up->id != id) {
+ snprintf(buf, 64, "/Prev %d 0 R\n", ptr->up->id);
+ strcat(dictionary, buf);
+ }
+
+ if (ptr->left != NULL) {
+ snprintf(buf, 64, "/Next %d 0 R\n", ptr->left->id);
+ strcat(dictionary, buf);
+ }
+
+ if (ptr->right != NULL) {
+ _outline(pdf, &ptr->right, ptr->id, &ret);
+
+ snprintf(buf, 64, "/First %d 0 R\n", ret[0]);
+ strcat(dictionary, buf);
+
+ snprintf(buf, 64, "/Last %d 0 R\n", ret[1]);
+ strcat(dictionary, buf);
+
+ snprintf(buf, 64, "/Count -%d\n", ret[2]);
+ strcat(dictionary, buf);
+
+ free(ret);
+ }
+
+ /* Page starts from 0 */
+ snprintf(buf, 64, "/Dest [%d /XYZ null null null]\n>>\n",
+ atoi(ptr->item->page) - 1);
+ strcat(dictionary, buf);
+
+ pdf_obj_append(pdf, ptr->id, NULL, dictionary, NULL);
+
+ if (ptr->left == NULL)
+ (*stat)[1] = ptr->id;
+
+ (*stat)[2]++;
+
+ ptr = ptr->left;
+ }
+
+ return 0;
+}
+
+int
+pdf_cnki_outline(pdf_object_t **pdf, object_outline_t **outline, int **ids)
+{
+ if (*pdf == NULL || *outline == NULL || *ids == NULL)
+ return 1;
+
+ object_outline_tree_t *outline_tree = NULL;
+ cnki_outline_tree(&outline_tree, outline, *ids);
+
+ char buf[128];
+ int *ret;
+
+ _outline(pdf, &outline_tree->left, outline_tree->id, &ret);
+
+ free(outline_tree);
+
+ snprintf(buf, 128,
+ "<<\n/Type Outlines\n/First %d 0 R\n/Last %d 0 R\n/Count %d\n>>\n",
+ ret[0], ret[1], ret[2]);
+
+ free(ret);
+
+ pdf_obj_append(pdf, (*ids)[0], NULL, buf, NULL);
+
+ return 0;
+}