summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-05-05 13:30:38 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-05-05 13:30:38 +0300
commita47d8d7051e9d5b0eaddf2c3895c439c4f26a104 (patch)
treee2cb32e12dd126fedad4329aa1da93fb76179d3c
parent14e64fde73a25d5758fe70d5425b70399c3705db (diff)
Gempub: Split to show index and first chapter
When opening a Gempub, split the window and show the index page and the first chapter.
-rw-r--r--src/gmdocument.c2
-rw-r--r--src/gmutil.c5
-rw-r--r--src/gmutil.h3
-rw-r--r--src/ui/documentwidget.c38
4 files changed, 42 insertions, 6 deletions
diff --git a/src/gmdocument.c b/src/gmdocument.c
index 2cce9b24..6ea9348e 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -168,7 +168,7 @@ static iRangecc addLink_GmDocument_(iGmDocument *d, iRangecc line, iGmLinkId *li
168 /* Returns the human-readable label of the link. */ 168 /* Returns the human-readable label of the link. */
169 static iRegExp *pattern_; 169 static iRegExp *pattern_;
170 if (!pattern_) { 170 if (!pattern_) {
171 pattern_ = new_RegExp("=>\\s*([^\\s]+)(\\s.*)?", caseInsensitive_RegExpOption); 171 pattern_ = newGemtextLink_RegExp();
172 } 172 }
173 iRegExpMatch m; 173 iRegExpMatch m;
174 init_RegExpMatch(&m); 174 init_RegExpMatch(&m);
diff --git a/src/gmutil.c b/src/gmutil.c
index a9d70fbb..57d7e350 100644
--- a/src/gmutil.c
+++ b/src/gmutil.c
@@ -25,6 +25,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
25#include <the_Foundation/regexp.h> 25#include <the_Foundation/regexp.h>
26#include <the_Foundation/object.h> 26#include <the_Foundation/object.h>
27#include <the_Foundation/path.h> 27#include <the_Foundation/path.h>
28#include <the_Foundation/regexp.h>
29
30iRegExp *newGemtextLink_RegExp(void) {
31 return new_RegExp("=>\\s*([^\\s]+)(\\s.*)?", 0);
32}
28 33
29void init_Url(iUrl *d, const iString *text) { 34void init_Url(iUrl *d, const iString *text) {
30 /* Handle "file:" as a special case since it only has the path part. */ 35 /* Handle "file:" as a special case since it only has the path part. */
diff --git a/src/gmutil.h b/src/gmutil.h
index 84f31e2e..09d333e7 100644
--- a/src/gmutil.h
+++ b/src/gmutil.h
@@ -26,6 +26,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
26#include <the_Foundation/string.h> 26#include <the_Foundation/string.h>
27 27
28iDeclareType(GmError) 28iDeclareType(GmError)
29iDeclareType(RegExp)
29iDeclareType(Url) 30iDeclareType(Url)
30 31
31/* Response status codes. */ 32/* Response status codes. */
@@ -90,6 +91,8 @@ struct Impl_GmError {
90iBool isDefined_GmError (enum iGmStatusCode code); 91iBool isDefined_GmError (enum iGmStatusCode code);
91const iGmError * get_GmError (enum iGmStatusCode code); 92const iGmError * get_GmError (enum iGmStatusCode code);
92 93
94iRegExp * newGemtextLink_RegExp (void);
95
93struct Impl_Url { 96struct Impl_Url {
94 iRangecc scheme; 97 iRangecc scheme;
95 iRangecc host; 98 iRangecc host;
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index ed38ad0b..3175f274 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -1094,6 +1094,7 @@ static const char *zipPageHeading_(const iRangecc mime) {
1094} 1094}
1095 1095
1096static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d) { 1096static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d) {
1097 iWidget *w = as_Widget(d);
1097 delete_Gempub(d->sourceGempub); 1098 delete_Gempub(d->sourceGempub);
1098 d->sourceGempub = NULL; 1099 d->sourceGempub = NULL;
1099 if (!cmpCase_String(&d->sourceMime, "application/octet-stream") || 1100 if (!cmpCase_String(&d->sourceMime, "application/octet-stream") ||
@@ -1111,20 +1112,27 @@ static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d) {
1111 } 1112 }
1112 } 1113 }
1113 if (!d->sourceGempub) { 1114 if (!d->sourceGempub) {
1114 iString *localPath = localFilePathFromUrl_String(d->mod.url); 1115 const iString *localPath = collect_String(localFilePathFromUrl_String(d->mod.url));
1116 iBool isInside = iFalse;
1117 if (localPath && !fileExists_FileInfo(localPath)) {
1118 /* This URL may refer to a file inside the archive. */
1119 localPath = findContainerArchive_Path(localPath);
1120 isInside = iTrue;
1121 }
1115 if (localPath && equal_CStr(mediaType_Path(localPath), "application/gpub+zip")) { 1122 if (localPath && equal_CStr(mediaType_Path(localPath), "application/gpub+zip")) {
1116 iGempub *gempub = new_Gempub(); 1123 iGempub *gempub = new_Gempub();
1117 if (openFile_Gempub(gempub, localPath)) { 1124 if (openFile_Gempub(gempub, localPath)) {
1118 setBaseUrl_Gempub(gempub, d->mod.url); 1125 setBaseUrl_Gempub(gempub, collect_String(makeFileUrl_String(localPath)));
1119 setSource_DocumentWidget(d, collect_String(coverPageSource_Gempub(gempub))); 1126 if (!isInside) {
1120 setCStr_String(&d->sourceMime, mimeType_Gempub); 1127 setSource_DocumentWidget(d, collect_String(coverPageSource_Gempub(gempub)));
1128 setCStr_String(&d->sourceMime, mimeType_Gempub);
1129 }
1121 d->sourceGempub = gempub; 1130 d->sourceGempub = gempub;
1122 } 1131 }
1123 else { 1132 else {
1124 delete_Gempub(gempub); 1133 delete_Gempub(gempub);
1125 } 1134 }
1126 } 1135 }
1127 delete_String(localPath);
1128 } 1136 }
1129 if (d->sourceGempub) { 1137 if (d->sourceGempub) {
1130 if (preloadCoverImage_Gempub(d->sourceGempub, d->doc)) { 1138 if (preloadCoverImage_Gempub(d->sourceGempub, d->doc)) {
@@ -1132,6 +1140,26 @@ static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d) {
1132 updateVisible_DocumentWidget_(d); 1140 updateVisible_DocumentWidget_(d);
1133 invalidate_DocumentWidget_(d); 1141 invalidate_DocumentWidget_(d);
1134 } 1142 }
1143 if (prefs_App()->pinSplit && equal_String(d->mod.url, indexPageUrl_Gempub(d->sourceGempub))) {
1144 const iString *navStart = navStartLinkUrl_Gempub(d->sourceGempub);
1145 if (navStart) {
1146 iWindow *win = get_Window();
1147 /* Auto-split to show index and the first navigation link. */
1148 if (numRoots_Window(win) == 2) {
1149 /* This document is showing the index page. */
1150 iRoot *other = otherRoot_Window(win, w->root);
1151 postCommandf_Root(other, "open url:%s", cstr_String(navStart));
1152 if (prefs_App()->pinSplit == 1 && w->root == win->roots[1]) {
1153 /* On the wrong side. */
1154 postCommand_App("ui.split swap:1");
1155 }
1156 }
1157 else {
1158 postCommandf_App(
1159 "open newtab:%d url:%s", otherRoot_OpenTabFlag, cstr_String(navStart));
1160 }
1161 }
1162 }
1135 } 1163 }
1136} 1164}
1137 1165