diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-05-05 13:30:38 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-05-05 13:30:38 +0300 |
commit | a47d8d7051e9d5b0eaddf2c3895c439c4f26a104 (patch) | |
tree | e2cb32e12dd126fedad4329aa1da93fb76179d3c | |
parent | 14e64fde73a25d5758fe70d5425b70399c3705db (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.c | 2 | ||||
-rw-r--r-- | src/gmutil.c | 5 | ||||
-rw-r--r-- | src/gmutil.h | 3 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 38 |
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 | |||
30 | iRegExp *newGemtextLink_RegExp(void) { | ||
31 | return new_RegExp("=>\\s*([^\\s]+)(\\s.*)?", 0); | ||
32 | } | ||
28 | 33 | ||
29 | void init_Url(iUrl *d, const iString *text) { | 34 | void 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 | ||
28 | iDeclareType(GmError) | 28 | iDeclareType(GmError) |
29 | iDeclareType(RegExp) | ||
29 | iDeclareType(Url) | 30 | iDeclareType(Url) |
30 | 31 | ||
31 | /* Response status codes. */ | 32 | /* Response status codes. */ |
@@ -90,6 +91,8 @@ struct Impl_GmError { | |||
90 | iBool isDefined_GmError (enum iGmStatusCode code); | 91 | iBool isDefined_GmError (enum iGmStatusCode code); |
91 | const iGmError * get_GmError (enum iGmStatusCode code); | 92 | const iGmError * get_GmError (enum iGmStatusCode code); |
92 | 93 | ||
94 | iRegExp * newGemtextLink_RegExp (void); | ||
95 | |||
93 | struct Impl_Url { | 96 | struct 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 | ||
1096 | static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d) { | 1096 | static 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 | ||