~q3cpma/sxiv-manga-reader

62acd57b913376479bbdcfe35248eae1f7ccfa49 — q3cpma 2 years ago 740ee2d
Switch to latest nsxiv and migrate most patch content from program to config.h
Fix/cleanup build.sh and natsort/build.sh
8 files changed, 165 insertions(+), 190 deletions(-)

M README
M build.sh
D manga-mode.patch
M natsort/build.sh
M natsort/gen_unicode_tolower_lut.sh
A sxiv-config.patch
M sxiv-manga-reader
A sxiv-quit-position.patch
M README => README +49 -47
@@ 4,7 4,7 @@
        Description
        -----------

Simple manga reader made from a patched sxiv and a mostly POSIX compliant sh
Simple manga reader made from a patched nsxiv and a mostly POSIX compliant sh
script (see the Dependencies section for more).




@@ 23,23 23,24 @@ script (see the Dependencies section for more).

In addition to the latest POSIX requirements, you'll need the following at
build time:
    * posix-build dependencies: mktemp -d (present on GNU, *BSD, MacOS, Illumos and Tru64) and
      local/typeset support in /bin/sh
    * posix-build dependencies: mktemp -d (present on GNU, *BSD, MacOS, Illumos
      and Tru64) and local/typeset support in /bin/sh
    * curl, wget or fetch
    * gunzip
    * tar
    * C99 compiler
    * imlib2 (sxiv)
    * libX11 (sxiv)
    * libXft, freetype2, fontconfig, libX11, imlib2 (nsxiv)

and the following at runtime:
    * imlib2 (sxiv)
    * libX11 (sxiv)
    * unzip (optional, for cbz)
    * unrar (optional, for cbr)
    * p7zip (optional, for cb7)
    * tar (optional, for cbt)
    * mktemp -d
    * libXft, freetype2, fontconfig, libX11, imlib2 (nsxiv)

libXft, freetype2, fontconfig could be omitted by setting HAVE_LIBFONTS to 0 in
build.sh, thus disabling the status bar functionality of nsxiv.


        Building and installation


@@ 49,48 50,49 @@ Build and install to /usr/local (default values shown between brackets):
    $ [CC=c99] [LTO=false] [NATIVE=false] ./build.sh
    # [DESTDIR=] [PREFIX=/usr/local] ./build.sh install

If there's a `config.h` present at the project root, it'll be used by sxiv.
If there's a `config.h` present at the project root, it'll be patched then
given to nsxiv.


        Documentation
        -------------

+---------------------------------------------------------------------------------+
| NAME                                                                            |
|     sxiv-manga-reader - Read mangas as archives or image directories            |
|                                                                                 |
| SYNOPSIS                                                                        |
|     sxiv-manga-reader [-hr] [-d RESUME_DIR] [-o SXIV_OPTS] ARCHIVE|DIRECTORY... |
|     sxiv-manga-reader [-hR] [-d RESUME_DIR] [-o SXIV_OPTS] -c DIRECTORY         |
|                                                                                 |
| DESCRIPTION                                                                     |
|     In the first mode, read multiple mangas as archives or directories          |
|     containing images. If there's only one argument, reaching past its          |
|     end/start will open the next/previous item and so on (roaming mode).        |
|                                                                                 |
|     In the second mode (-c), consider DIRECTORY as containing mangas in         |
|     the same format as the first mode. Save/resume mode (-r) is                 |
|     automatically enabled by this mode.                                         |
|                                                                                 |
| OPTIONS                                                                         |
|     -c                                                                          |
|         See DESCRIPTION.                                                        |
|                                                                                 |
|     -h                                                                          |
|         Print this help message and exit.                                       |
|                                                                                 |
|     -d RESUME_DIR                                                               |
|         Instead of saving resume state files in the same directory as mangas,   |
|         save them in RESUME_DIR (note: using absolute paths).                   |
|                                                                                 |
|     -o SXIV_OPTS                                                                |
|         Pass these options to sxiv.                                             |
|                                                                                 |
|     -r                                                                          |
|         Enable save/resume mode to save item and page information to resume     |
|         reading later.                                                          |
|                                                                                 |
|     -R                                                                          |
|         Disable save/resume mode.                                               |
|                                                                                 |
+---------------------------------------------------------------------------------+
+----------------------------------------------------------------------------------+
| NAME                                                                             |
|     sxiv-manga-reader - Read mangas as archives or image directories             |
|                                                                                  |
| SYNOPSIS                                                                         |
|     sxiv-manga-reader [-hr] [-d RESUME_DIR] [-o NSXIV_OPTS] ARCHIVE|DIRECTORY... |
|     sxiv-manga-reader [-hR] [-d RESUME_DIR] [-o NSXIV_OPTS] -c DIRECTORY         |
|                                                                                  |
| DESCRIPTION                                                                      |
|     In the first mode, read multiple mangas as archives or directories           |
|     containing images. If there's only one argument, reaching past its           |
|     end/start will open the next/previous item and so on (roaming mode).         |
|                                                                                  |
|     In the second mode (-c), consider DIRECTORY as containing mangas in          |
|     the same format as the first mode. Save/resume mode (-r) is                  |
|     automatically enabled by this mode.                                          |
|                                                                                  |
| OPTIONS                                                                          |
|     -c                                                                           |
|         See DESCRIPTION.                                                         |
|                                                                                  |
|     -h                                                                           |
|         Print this help message and exit.                                        |
|                                                                                  |
|     -d RESUME_DIR                                                                |
|         Instead of saving resume state files in the same directory as mangas,    |
|         save them in RESUME_DIR (note: using absolute paths).                    |
|                                                                                  |
|     -o NSXIV_OPTS                                                                |
|         Pass these options to nsxiv.                                             |
|                                                                                  |
|     -r                                                                           |
|         Enable save/resume mode to save item and page information to resume      |
|         reading later.                                                           |
|                                                                                  |
|     -R                                                                           |
|         Disable save/resume mode.                                                |
|                                                                                  |
+----------------------------------------------------------------------------------+

M build.sh => build.sh +24 -18
@@ 7,35 7,35 @@ export PROJECT=sxiv-manga-reader

PREFIX=$(preadlinkf "${DESTDIR+${DESTDIR%/}}${PREFIX:-/usr/local}")

sxiv_url=https://github.com/muennich/sxiv/archive/v24.tar.gz
sxiv_tgz=v24.tar.gz
sxiv_dir=sxiv-24
sxiv_bin=sxiv-manga
nsxiv_url=https://github.com/nsxiv/nsxiv/archive/refs/tags/v29.tar.gz
nsxiv_tgz=v29.tar.gz
nsxiv_dir=nsxiv-29
nsxiv_bin=nsxiv-manga

if [ $# -eq 1 ]
then
	case "$(tolower "$1")" in
		install)
			set_rpaths \
				bin_sxiv="$PREFIX"/bin \
				bin_natsort="$PREFIX"/bin \
				nsxiv_dir="$PREFIX"/bin \
				natsort_dir="$PREFIX"/bin \
				share="$PREFIX"/share/"$PROJECT"
			pb_install -m 755 -r "$PREFIX"/bin/ sxiv-manga-reader sxiv-manga
			pb_install -m 755 -r "$PREFIX"/bin/ "$PROJECT" "$nsxiv_bin"
			pb_install -m 644 "$PREFIX"/share/"$PROJECT"/ util.sh
			pb_install -m 644 "$PREFIX"/share/doc/"$PROJECT"/ README
			mkdir -p "$PREFIX"/share/applications
			sed "s#^\(Try\)\{0,1\}Exec=\$#&$PREFIX/bin/sxiv-manga-reader#" \
			sed "s#^\(Try\)\{0,1\}Exec=\$#&$PREFIX/bin/$PROJECT#" \
				"$PROJECT".desktop >"$PREFIX"/share/applications/"$PROJECT".desktop
			;;
		uninstall)
			uninstall \
				"$PREFIX"/bin/sxiv-manga-reader \
				"$PREFIX"/bin/"$PROJECT" \
				"$PREFIX"/share/"$PROJECT"/util.sh \
				"$PREFIX"/share/doc/"$PROJECT"/README \
				"$PREFIX"/share/applications/"$PROJECT".desktop
			;;
		clean)
			rm -rf -- "$sxiv_dir" "$sxiv_bin" # "$sxiv_tgz"
			rm -rf -- "$nsxiv_dir" "$nsxiv_bin" # "$nsxiv_tgz"
			;;
		help)
			pb_usage 0


@@ 51,16 51,22 @@ then
	pb_usage 1
fi

! [ -s "$sxiv_tgz" ] && pb_fetch "$sxiv_url"
! [ -s "$sxiv_dir" ] && gunzip -c -- "$sxiv_tgz" | tar xf -
! [ -s "$nsxiv_tgz" ] && pb_fetch "$nsxiv_url"
! [ -s "$nsxiv_dir" ] && gunzip -c -- "$nsxiv_tgz" | tar xf -

if ! [ -s "$sxiv_bin" ]
if ! [ -s "$nsxiv_bin" ]
then
	patch -d"$sxiv_dir" -p1 <manga-mode.patch
	[ -f config.h ] && cp -- config.h "$sxiv_dir" || true
	cd "$sxiv_dir"
	make CFLAGS='-O2 -s' HAVE_GIFLIB=0 HAVE_LIBEXIF=0
	cp -f -- sxiv ..
	patch -d "$nsxiv_dir" -p1 <sxiv-quit-position.patch
	if [ -f config.h ]
	then
		patch -o "$nsxiv_dir"/config.h config.h sxiv-config.patch
	else
		patch "$nsxiv_dir"/config.def.h sxiv-config.patch
	fi
	cd "$nsxiv_dir"
	make CFLAGS='-std=c99 -Wall -pedantic -O2' LDFLAGS='-s' \
		HAVE_INOTIFY=0 HAVE_LIBFONTS=1 HAVE_LIBGIF=0 HAVE_LIBEXIF=0 HAVE_LIBWEBP=0
	cp -f -- nsxiv ../"$nsxiv_bin"
	cd - >/dev/null
fi


D manga-mode.patch => manga-mode.patch +0 -105
@@ 1,105 0,0 @@
diff --git a/commands.c b/commands.c
index 966ee4c..6cada11 100644
--- a/commands.c
+++ b/commands.c
@@ -59,6 +59,9 @@ bool cg_quit(arg_t _)
 				printf("%s\n", files[i].name);
 		}
 	}
+	if (!_ && options->manga_mode)
+		printf("Quit at %d\n", fileidx + 1);
+
 	exit(EXIT_SUCCESS);
 }
 
@@ -225,7 +228,7 @@ bool cg_navigate_marked(arg_t n)
 {
 	int d, i;
 	int new = fileidx;
-	
+
 	if (prefix > 0)
 		n *= prefix;
 	d = n > 0 ? 1 : -1;
@@ -264,11 +267,20 @@ bool ci_navigate(arg_t n)
 	if (prefix > 0)
 		n *= prefix;
 	n += fileidx;
-	if (n < 0)
-		n = 0;
-	if (n >= filecnt)
-		n = filecnt - 1;
-
+	if (n < 0) {
+		if (options->manga_mode) {
+			puts("Start reached");
+			cg_quit(1);
+		} else
+			n = 0;
+	}
+	if (n >= filecnt) {
+		if (options->manga_mode) {
+			puts("End reached");
+			cg_quit(1);
+		} else
+			n = filecnt - 1;
+	}
 	if (n != fileidx) {
 		load_image(n);
 		return true;
@@ -329,7 +341,7 @@ bool ci_drag(arg_t _)
 
 	if ((int)(img.w * img.zoom) <= win.w && (int)(img.h * img.zoom) <= win.h)
 		return false;
-	
+
 	win_set_cursor(&win, CURSOR_DRAG);
 
 	win_cursor_pos(&win, &x, &y);
@@ -432,4 +444,3 @@ bool ct_reload_all(arg_t _)
 const cmd_t cmds[CMD_COUNT] = {
 #include "commands.lst"
 };
-
diff --git a/options.c b/options.c
index 6b3599c..3b3dd72 100644
--- a/options.c
+++ b/options.c
@@ -70,8 +70,9 @@ void parse_options(int argc, char **argv)
 	_options.thumb_mode = false;
 	_options.clean_cache = false;
 	_options.private_mode = false;
+	_options.manga_mode = false;
 
-	while ((opt = getopt(argc, argv, "A:abce:fG:g:hin:N:opqrS:s:tvZz:")) != -1) {
+	while ((opt = getopt(argc, argv, "A:abce:fG:g:himn:N:opqrS:s:tvZz:")) != -1) {
 		switch (opt) {
 			case '?':
 				print_usage();
@@ -115,6 +116,9 @@ void parse_options(int argc, char **argv)
 			case 'i':
 				_options.from_stdin = true;
 				break;
+			case 'm':
+				_options.manga_mode = true;
+				break;
 			case 'n':
 				n = strtol(optarg, &end, 0);
 				if (*end != '\0' || n <= 0)
diff --git a/sxiv.h b/sxiv.h
index 25443ea..19cdb25 100644
--- a/sxiv.h
+++ b/sxiv.h
@@ -281,6 +281,7 @@ struct opt {
 	bool thumb_mode;
 	bool clean_cache;
 	bool private_mode;
+	bool manga_mode;
 };
 
 extern const opt_t *options;
@@ -448,4 +449,3 @@ void win_set_cursor(win_t*, cursor_t);
 void win_cursor_pos(win_t*, int*, int*);
 
 #endif /* SXIV_H */
-

M natsort/build.sh => natsort/build.sh +1 -6
@@ 44,14 44,9 @@ else
				;;
			install)
				pb_install -m 755 "$PREFIX"/bin/ "$BIN"
				pb_install -m 644 "$PREFIX"/share/doc/"$PROJECT"/README_mus_player.txt README
				pb_install -m 644 "$PREFIX"/share/doc/"$PROJECT"/ IPC.txt
				;;
			uninstall)
				uninstall \
					"$PREFIX"/bin/"$BIN" \
					"$PREFIX"/share/doc/"$PROJECT"/README_mus_player.txt \
					"$PREFIX"/share/doc/"$PROJECT"/IPC.txt
				uninstall "$PREFIX"/bin/"$BIN"
				;;
			help)
				pb_usage 0

M natsort/gen_unicode_tolower_lut.sh => natsort/gen_unicode_tolower_lut.sh +1 -1
@@ 13,7 13,7 @@ cat <<'EOF'
static const uint32_t unicode_tolower_lut[] =
{
EOF
if readlinkf "$(command -v awk)" | grep -q '/gawk$'
if preadlinkf "$(command -v awk)" | grep -q '/gawk$'
then
	gawk=
fi

A sxiv-config.patch => sxiv-config.patch +63 -0
@@ 0,0 1,63 @@
diff --git a/config.def.h b/config.def.h
index 1e102fe..20d6fe1 100644
--- a/config.def.h
+++ b/config.def.h
@@ -79,6 +79,32 @@ static const unsigned int USED_MODMASK = ShiftMask | ControlMask | Mod1Mask;
 /* abort the keyhandler */
 static const KeySym KEYHANDLER_ABORT = XK_Escape;
 
+bool ci_nav_quit(arg_t n)
+{
+	extern int fileidx, filecnt;
+
+	if (fileidx + n < 0)
+	{
+		puts("Start reached");
+		cg_quit(2);
+	}
+	if (fileidx + n >= filecnt)
+	{
+		puts("End reached");
+		cg_quit(3);
+	}
+	return ci_navigate(n);
+}
+
+extern int nav_button(void);
+bool ci_cursor_nav_quit(arg_t _)
+{
+	return ci_nav_quit(nav_button() - 1);
+}
+
+#define i_nav_quit        { ci_nav_quit,        MODE_IMAGE }
+#define i_cursor_nav_quit { ci_cursor_nav_quit, MODE_IMAGE }
+
 /* keyboard mappings for image and thumbnail mode: */
 static const keymap_t keys[] = {
 	/* modifiers    key               function              argument */
@@ -123,12 +149,12 @@ static const keymap_t keys[] = {
 	{ 0,            XK_Right,         t_move_sel,           DIR_RIGHT },
 	{ 0,            XK_R,             t_reload_all,         None },
 
-	{ 0,            XK_n,             i_navigate,           +1 },
+	{ 0,            XK_n,             i_nav_quit,           +1 },
 	{ 0,            XK_n,             i_scroll_to_edge,     DIR_LEFT | DIR_UP },
-	{ 0,            XK_space,         i_navigate,           +1 },
-	{ 0,            XK_p,             i_navigate,           -1 },
+	{ 0,            XK_space,         i_nav_quit,           +1 },
+	{ 0,            XK_p,             i_nav_quit,           -1 },
 	{ 0,            XK_p,             i_scroll_to_edge,     DIR_LEFT | DIR_UP },
-	{ 0,            XK_BackSpace,     i_navigate,           -1 },
+	{ 0,            XK_BackSpace,     i_nav_quit,           -1 },
 	{ 0,            XK_bracketright,  i_navigate,           +10 },
 	{ 0,            XK_bracketleft,   i_navigate,           -10 },
 	{ ControlMask,  XK_6,             i_alternate,          None },
@@ -168,7 +194,7 @@ static const keymap_t keys[] = {
 /* mouse button mappings for image mode: */
 static const button_t buttons_img[] = {
 	/* modifiers    button            function              argument */
-	{ 0,            1,                i_cursor_navigate,    None },
+	{ 0,            1,                i_cursor_nav_quit,    None },
 	{ ControlMask,  1,                i_drag,               DRAG_RELATIVE },
 	{ 0,            2,                i_drag,               DRAG_ABSOLUTE },
 	{ 0,            3,                g_switch_mode,        None },

M sxiv-manga-reader => sxiv-manga-reader +13 -13
@@ 1,5 1,5 @@
#!/bin/sh
# Dependencies: sxiv_manga, natsort, (tar, unzip, unrar, 7z) (optional)
# Dependencies: nsxiv-manga, natsort, (tar, unzip, unrar, 7z) (optional)
# Portability:  GNU, *BSD, MacOS, Illumos and Tru64
# +-----------+-----+---------+--------+--------------+---------+-------+---------+-------+-----+------+-------+
# | cmd\OS    | GNU | OpenBSD | NetBSD | DragonflyBSD | FreeBSD | MacOS | Illumos | HP-UX | AIX | IRIX | Tru64 |


@@ 8,10 8,10 @@
# +-----------+-----+---------+--------+--------------+---------+-------+---------+-------+-----+------+-------+
set -eu
rpath_share=$(dirname -- "$0")
rpath_bin_sxiv=$(dirname -- "$0")
rpath_bin_natsort=$(dirname -- "$0")/natsort
sxiv=$rpath_bin_sxiv/sxiv-manga
sort=$rpath_bin_natsort/natsort
rpath_nsxiv_dir=$(dirname -- "$0")
rpath_natsort_dir=$(dirname -- "$0")/natsort
nsxiv=$rpath_nsxiv_dir/nsxiv-manga
sort=$rpath_natsort_dir/natsort
. "$rpath_share"/util.sh




@@ 57,7 57,7 @@ open()

# $1: image directory path
# $2: mode, "Start reached", "End reached" or "Initial"
# View all the images in $1 with $sxiv. Starting page depends on $2
# View all the images in $1 with $nsxiv. Starting page depends on $2
# and global variables $resume_mode and $resume_page (for "Initial")
view()
{


@@ 74,7 74,7 @@ view()
				start=$resume_page || start=1
			;;
	esac
	pecho "$list" | "$sxiv" -n$start -m $sxiv_opts -
	pecho "$list" | "$nsxiv" -n$start $nsxiv_opts - || true
}

# $1: mode, "next", "prev" or "first"


@@ 117,8 117,8 @@ usage()
    $name - Read mangas as archives or image directories

**SYNOPSIS**
    $name [**-hr**] [**-d** __RESUME_DIR__] [**-o** __SXIV_OPTS__] __ARCHIVE|DIRECTORY__...
    $name [**-hR**] [**-d** __RESUME_DIR__] [**-o** __SXIV_OPTS__] **-c** __DIRECTORY__
    $name [**-hr**] [**-d** __RESUME_DIR__] [**-o** __NSXIV_OPTS__] __ARCHIVE|DIRECTORY__...
    $name [**-hR**] [**-d** __RESUME_DIR__] [**-o** __NSXIV_OPTS__] **-c** __DIRECTORY__

**DESCRIPTION**
    In the first mode, read multiple mangas as archives or directories


@@ 140,8 140,8 @@ usage()
        Instead of saving resume state files in the same directory as mangas,
        save them in __RESUME_DIR__ (note: using absolute paths).

    **-o** __SXIV_OPTS__
        Pass these options to sxiv.
    **-o** __NSXIV_OPTS__
        Pass these options to nsxiv.

    **-r**
        Enable save/resume mode to save item and page information to resume


@@ 154,7 154,7 @@ EOF
	exit $1
}

sxiv_opts=
nsxiv_opts=
container_dir_mode=false
resume_mode=true
resume_dir=


@@ 166,7 166,7 @@ do
		d)  resume_dir=$OPTARG;;
		r)  resume_mode=true;;
		R)  resume_mode=false;;
		o)  sxiv_opts=$OPTARG;;
		o)  nsxiv_opts=$OPTARG;;
		\?) usage 1;;
	esac
done

A sxiv-quit-position.patch => sxiv-quit-position.patch +14 -0
@@ 0,0 1,14 @@
diff --git a/commands.c b/commands.c
index 19d2abe..f51a7f5 100644
--- a/commands.c
+++ b/commands.c
@@ -63,6 +63,9 @@ bool cg_quit(arg_t status)
 				printf("%s%c", files[i].name, options->using_null ? '\0' : '\n');
 		}
 	}
+	if (status < 2)
+		printf("Quit at %d\n", fileidx + 1);
+
 	exit(status);
 	return None; /* silence tcc warning */
 }