Switch to configure and make based build
Also removed excessive use of std.regex in esvapi.d and made it actually compile -_-
This commit is contained in:
parent
7ebc0d7b66
commit
6efe117545
5 changed files with 254 additions and 68 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@
|
||||||
*.so
|
*.so
|
||||||
*.a
|
*.a
|
||||||
esv
|
esv
|
||||||
|
Makefile
|
||||||
|
|
32
Makefile
32
Makefile
|
@ -1,32 +0,0 @@
|
||||||
IMPORT = import
|
|
||||||
PREFIX = /usr/local
|
|
||||||
MANPREFIX = /usr/share/man
|
|
||||||
|
|
||||||
DC = ldc2
|
|
||||||
CFLAGS = -O -I${IMPORT} -release -w
|
|
||||||
OBJS = main.o esvapi.o ini.o
|
|
||||||
|
|
||||||
all: esv
|
|
||||||
|
|
||||||
esv: ${OBJS}
|
|
||||||
${DC} ${CFLAGS} -of$@ ${OBJS}
|
|
||||||
|
|
||||||
# main executable
|
|
||||||
main.o: main.d esvapi.o
|
|
||||||
${DC} ${CFLAGS} -of$@ -c main.d
|
|
||||||
|
|
||||||
esvapi.o: esvapi.d
|
|
||||||
${DC} ${CFLAGS} -of$@ -c esvapi.d
|
|
||||||
|
|
||||||
ini.o: ${IMPORT}/dini/*.d
|
|
||||||
${DC} ${CFLAGS} -of$@ -c ${IMPORT}/dini/*.d
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f esv ${OBJS}
|
|
||||||
|
|
||||||
install: esv
|
|
||||||
install -m755 esv ${DESTDIR}${PREFIX}/bin/esv
|
|
||||||
cp -f esv.1 ${DESTDIR}${MANPREFIX}/man1
|
|
||||||
cp -f esv.conf.5 ${DESTDIR}${MANPREFIX}/man5
|
|
||||||
|
|
||||||
.PHONY: all clean install
|
|
35
README.md
35
README.md
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
*Read the Bible from your terminal*
|
*Read the Bible from your terminal*
|
||||||
|
|
||||||
`esv` is a utility that displays passages of the English Standard Bible on your terminal.
|
`esv` is a utility that displays passages of the English Standard Bible
|
||||||
It connects to the ESV web API to retrieve the passages,
|
on your terminal. It connects to the ESV web API to retrieve the passages,
|
||||||
and allows configuration through command-line options and the configuration file.
|
and allows configuration through command-line options and the configuration file.
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
|
@ -20,18 +20,20 @@ A Psalm of David.
|
||||||
He makes me lie down in green pastures....
|
He makes me lie down in green pastures....
|
||||||
```
|
```
|
||||||
|
|
||||||
If the requested passage is over 32 lines long, `esv` will pipe it through a pager
|
If the requested passage is over 32 lines long, `esv` will pipe it through
|
||||||
(default less). The pager being used can be changed through the `ESV_PAGER`
|
a pager (default less). The pager being used can be changed through the
|
||||||
environment variable or just disabled altogether by passing the -P option.
|
`ESV_PAGER` environment variable or just disabled altogether by passing the
|
||||||
|
-P option.
|
||||||
|
|
||||||
The names of Bible books are not case sensitive, so John, john, JOHN and jOhN
|
The names of Bible books are not case sensitive, so John, john, and JOHN
|
||||||
are all accepted.
|
are all accepted.
|
||||||
|
|
||||||
## Audio
|
## Audio
|
||||||
|
|
||||||
`esv` supports playing audio passages through the -a option.
|
`esv` supports playing audio passages through the -a option.
|
||||||
The `mpg123` audio/video player is utilised here and so it is therefore required
|
The `mpg123` audio/video player is utilised here and so it required if you
|
||||||
if you want to use audio mode.
|
want to play audio passages. If you prefer, you can use a different player
|
||||||
|
(such as mpv) by editing config.di.
|
||||||
|
|
||||||
Audio usage is the same as normal text usage. `esv -a Matthew 5-7` will play
|
Audio usage is the same as normal text usage. `esv -a Matthew 5-7` will play
|
||||||
an audio passage of Matthew 5-7.
|
an audio passage of Matthew 5-7.
|
||||||
|
@ -40,10 +42,13 @@ an audio passage of Matthew 5-7.
|
||||||
|
|
||||||
To install `esv`, first make sure you have the
|
To install `esv`, first make sure you have the
|
||||||
[LLVM D compiler (ldc)](https://github.com/ldc-developers/ldc#installation)
|
[LLVM D compiler (ldc)](https://github.com/ldc-developers/ldc#installation)
|
||||||
installed on your system. You should also have Phobos (the D standard library, comes included with LDC)
|
installed on your system.
|
||||||
installed as a dynamic library in order to run the executable.
|
|
||||||
|
|
||||||
First clone the source code repository:
|
Commands prefixed with a dollar sign ($) are intended to be run as
|
||||||
|
a standard user, and commands prefixed with a hash sign (#) are intended
|
||||||
|
to be run as the root user.
|
||||||
|
|
||||||
|
First, get the source code:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git clone https://codeberg.org/jtbx/esv
|
$ git clone https://codeberg.org/jtbx/esv
|
||||||
|
@ -53,13 +58,15 @@ $ cd esv
|
||||||
Now, compile and install:
|
Now, compile and install:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
$ ./configure
|
||||||
$ make
|
$ make
|
||||||
# make install
|
# make install
|
||||||
```
|
```
|
||||||
|
|
||||||
By default the Makefile guesses that the ldc executable is named `ldc2`. If it is installed
|
<!--
|
||||||
under a different name, or if you wish to use a different compiler, use `make DC=compiler`
|
By default the configure script looks for ldc and dmd in your PATH
|
||||||
(where `compiler` is your compiler) instead.
|
and optimises the command-line arguments based on the compiler.
|
||||||
|
-->
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|
187
configure
vendored
Executable file
187
configure
vendored
Executable file
|
@ -0,0 +1,187 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
# simple and flexible configure script for people who don't like to waste time
|
||||||
|
# licensed to the public domain
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
IMPORT=import
|
||||||
|
|
||||||
|
mkf=Makefile
|
||||||
|
cflags=-I"$IMPORT"
|
||||||
|
objs='esv.o esvapi.o'
|
||||||
|
srcs='esv.d esvapi.d'
|
||||||
|
makefile='
|
||||||
|
IMPORT = '"$IMPORT"'
|
||||||
|
PREFIX = /usr/local
|
||||||
|
MANPREFIX = ${PREFIX}/man
|
||||||
|
|
||||||
|
DC = ${_DC}
|
||||||
|
CFLAGS = ${_CFLAGS}
|
||||||
|
OBJS = ${_OBJS} ini.o
|
||||||
|
|
||||||
|
all: esv
|
||||||
|
|
||||||
|
esv: ${OBJS}
|
||||||
|
${DC} ${_LDFLAGS} -of=$@ ${OBJS}
|
||||||
|
|
||||||
|
.SUFFIXES: .d .o
|
||||||
|
|
||||||
|
.d.o:
|
||||||
|
${DC} ${CFLAGS} -c $<
|
||||||
|
|
||||||
|
ini.o: ${IMPORT}/dini/*.d
|
||||||
|
${DC} ${CFLAGS} -of=ini.o -c ${IMPORT}/dini/*.d
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f esv ${OBJS}
|
||||||
|
|
||||||
|
install: esv
|
||||||
|
install -m755 esv ${DESTDIR}${PREFIX}/bin/esv
|
||||||
|
cp -f esv.1 ${DESTDIR}${MANPREFIX}/man1
|
||||||
|
cp -f esv.conf.5 ${DESTDIR}${MANPREFIX}/man5
|
||||||
|
|
||||||
|
.PHONY: all clean install
|
||||||
|
'
|
||||||
|
|
||||||
|
# utility functions
|
||||||
|
|
||||||
|
present () {
|
||||||
|
command -v "$1" 1>/dev/null 2>/dev/null
|
||||||
|
}
|
||||||
|
using () {
|
||||||
|
>&2 printf "using $1\n"
|
||||||
|
}
|
||||||
|
error () {
|
||||||
|
>&2 printf "$(basename $0): $1\n"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# generators
|
||||||
|
|
||||||
|
## D compiler
|
||||||
|
gen_DC () {
|
||||||
|
if ! [ -z "$dc" ]; then
|
||||||
|
using "$dc"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if present ldc2; then
|
||||||
|
dc=ldc2
|
||||||
|
using ldc2
|
||||||
|
elif present dmd; then
|
||||||
|
dc=dmd
|
||||||
|
using dmd
|
||||||
|
else
|
||||||
|
error "D compiler not found; install ldc or dmd"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
## flags used in the compilation step
|
||||||
|
gen_CFLAGS () {
|
||||||
|
if [ -z "$debug" ]; then
|
||||||
|
case "$dc" in
|
||||||
|
ldc2) cflags="-Oz";;
|
||||||
|
dmd) cflags="-O";;
|
||||||
|
esac
|
||||||
|
using "$cflags"
|
||||||
|
else
|
||||||
|
fdebugsymbols="-g"
|
||||||
|
using "$fdebugsymbols"
|
||||||
|
case "$dc" in
|
||||||
|
ldc2)
|
||||||
|
fdebug="-d-debug"
|
||||||
|
using "$fdebug"
|
||||||
|
foptimisation="-O0"
|
||||||
|
using "$foptimisation"
|
||||||
|
;;
|
||||||
|
dmd) fdebug="-debug";;
|
||||||
|
esac
|
||||||
|
cflags="$fdebugsymbols $fdebug"
|
||||||
|
unset fdebug
|
||||||
|
unset fdebugsymbols
|
||||||
|
unset foptimisation
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
## flags used in the linking step
|
||||||
|
gen_LDFLAGS () {
|
||||||
|
if [ "$dc" = ldc2 ]; then
|
||||||
|
if present ld.lld; then
|
||||||
|
ldflags="-linker=lld"
|
||||||
|
using "$ldflags"
|
||||||
|
elif present ld.gold; then
|
||||||
|
ldflags="-linker=gold"
|
||||||
|
using "$ldflags"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# command line interface
|
||||||
|
|
||||||
|
while getopts c:dhr ch; do
|
||||||
|
case "$ch" in
|
||||||
|
c)
|
||||||
|
case "$OPTARG" in
|
||||||
|
ldc2) dc="ldc2" ;;
|
||||||
|
dmd) dc="dmd" ;;
|
||||||
|
*) error "unknown D compiler '$OPTARG' specified (valid options: ldc2, dmd)" ;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
d) debug=1 ;;
|
||||||
|
r) unset debug ;;
|
||||||
|
h)
|
||||||
|
cat <<EOF
|
||||||
|
configure: create an optimised makefile for the current environment
|
||||||
|
|
||||||
|
options:
|
||||||
|
-c: force use of a particular compiler (dmd or ldc2)
|
||||||
|
-d: build in debug mode, with debug symbols and statements enabled
|
||||||
|
-r: build in release mode with optimisation flags enabled (default)
|
||||||
|
-h: show this help message
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
?) exit 1 ;;
|
||||||
|
:) exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# creating the makefile
|
||||||
|
|
||||||
|
u_cflags="$cflags"
|
||||||
|
unset cflags
|
||||||
|
|
||||||
|
gen_DC
|
||||||
|
gen_CFLAGS
|
||||||
|
gen_LDFLAGS
|
||||||
|
|
||||||
|
rm -f "$mkf"
|
||||||
|
printf '# begin generated definitions' >>"$mkf"
|
||||||
|
printf '
|
||||||
|
_DC = %s
|
||||||
|
_CFLAGS = %s
|
||||||
|
_LDFLAGS = %s
|
||||||
|
' \
|
||||||
|
"$dc" \
|
||||||
|
"$cflags $u_cflags" \
|
||||||
|
"$ldflags" \
|
||||||
|
>>"$mkf"
|
||||||
|
## generate obj list
|
||||||
|
printf '_OBJS =' >>"$mkf"
|
||||||
|
for obj in $objs; do
|
||||||
|
printf " $obj" >>"$mkf"
|
||||||
|
done
|
||||||
|
printf '\n' >>"$mkf"
|
||||||
|
printf '# end generated definitions\n' >>"$mkf"
|
||||||
|
|
||||||
|
printf "$makefile" >>"$mkf"
|
||||||
|
|
||||||
|
## generate dependency list
|
||||||
|
>&2 printf "generating dependency list\n"
|
||||||
|
printf '\n# begin generated dependencies\n' >>"$mkf"
|
||||||
|
i=1
|
||||||
|
for obj in $objs; do
|
||||||
|
"$dc" $u_cflags -O0 -o- -makedeps \
|
||||||
|
"$(printf "$srcs" | awk '{print $'"$i"'}')" >>"$mkf"
|
||||||
|
i="$(($i + 1))"
|
||||||
|
done
|
||||||
|
printf '# end generated dependencies\n' >>"$mkf"
|
67
esvapi.d
67
esvapi.d
|
@ -25,9 +25,9 @@ import std.exception : basicExceptionCtors, enforce;
|
||||||
import std.file : tempDir, write;
|
import std.file : tempDir, write;
|
||||||
import std.format : format;
|
import std.format : format;
|
||||||
import std.json : JSONValue, parseJSON;
|
import std.json : JSONValue, parseJSON;
|
||||||
import std.regex : regex, matchAll, replaceAll;
|
import std.regex : regex, matchAll;
|
||||||
import std.stdio : File;
|
import std.stdio : File;
|
||||||
import std.string : capitalize;
|
import std.string : capitalize, tr;
|
||||||
import std.net.curl : HTTP;
|
import std.net.curl : HTTP;
|
||||||
|
|
||||||
enum ESVIndent
|
enum ESVIndent
|
||||||
|
@ -162,8 +162,6 @@ bool verseValid(in char[] verse) @safe
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class ESVApi
|
class ESVApi
|
||||||
{
|
{
|
||||||
protected {
|
protected {
|
||||||
|
@ -234,32 +232,51 @@ class ESVApi
|
||||||
params = [];
|
params = [];
|
||||||
|
|
||||||
{
|
{
|
||||||
(char[])[] parambuf;
|
void *o;
|
||||||
|
string[] parambuf;
|
||||||
foreach (string opt; ESVAPI_PARAMETERS) {
|
foreach (string opt; ESVAPI_PARAMETERS) {
|
||||||
bool bo;
|
|
||||||
int io;
|
|
||||||
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case "indent-using":
|
case "indent-using":
|
||||||
o = opts.indent_using;
|
o = cast(void *)opts.indent_using;
|
||||||
break;
|
break;
|
||||||
case "indent-poetry":
|
case "indent-poetry":
|
||||||
|
case "include-passage-references":
|
||||||
|
case "include-verse-numbers":
|
||||||
|
case "include-first-verse-numbers":
|
||||||
|
case "include-footnotes":
|
||||||
|
case "include-footnote-body":
|
||||||
|
case "include-headings":
|
||||||
|
case "include-short-copyright":
|
||||||
|
case "include-copyright":
|
||||||
|
case "include-passage-horizontal-lines":
|
||||||
|
case "include-heading-horizontal-lines":
|
||||||
|
case "include-selahs":
|
||||||
|
o = cast(void *)opts.b[opt];
|
||||||
|
break;
|
||||||
|
case "line-length":
|
||||||
|
case "horizontal-line-length":
|
||||||
|
case "indent-paragraphs":
|
||||||
|
case "indent-poetry-lines":
|
||||||
|
case "indent-declares":
|
||||||
|
case "indent-psalm-doxology":
|
||||||
|
o = cast(void *)opts.i[opt];
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
!opt.matchAll("^include-").empty) {
|
parambuf[parambuf.length] = format!"&%s=%s"(
|
||||||
o = opts.b[opt];
|
opt,
|
||||||
} else if (opt == "line-length" ||
|
opt == "indent-using" ?
|
||||||
opt == "horizontal-line-length" ||
|
opts.indent_using == ESVIndent.TAB ? "tab" : "space"
|
||||||
!opt.matchAll("^indent-").empty) {
|
: o.to!string()
|
||||||
o = opts.i[opt];
|
);
|
||||||
}
|
|
||||||
params = format!"%s&%s=%s"(params, opt, o.to!string());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
request = HTTP(
|
request = HTTP(format!"%s/text/?q=%s+%s%s%s"(
|
||||||
format!"%s/text/?q=%s+%s%s%s"(_url, book
|
_url,
|
||||||
|
book
|
||||||
.capitalize()
|
.capitalize()
|
||||||
.replaceAll(regex(" "), "+"),
|
.tr(" ", "+"),
|
||||||
verse, params, extraParameters)
|
verse, params, extraParameters)
|
||||||
);
|
);
|
||||||
request.onProgress = onProgress;
|
request.onProgress = onProgress;
|
||||||
|
@ -290,7 +307,12 @@ class ESVApi
|
||||||
File tmpFile;
|
File tmpFile;
|
||||||
|
|
||||||
auto request = HTTP(format!"%s/audio/?q=%s+%s"(
|
auto request = HTTP(format!"%s/audio/?q=%s+%s"(
|
||||||
_url, book.capitalize().replaceAll(regex(" "), "+"), verse));
|
_url,
|
||||||
|
book
|
||||||
|
.capitalize()
|
||||||
|
.tr(" ", "+"),
|
||||||
|
verse)
|
||||||
|
);
|
||||||
request.onProgress = onProgress;
|
request.onProgress = onProgress;
|
||||||
request.onReceive =
|
request.onReceive =
|
||||||
(ubyte[] data)
|
(ubyte[] data)
|
||||||
|
@ -320,7 +342,8 @@ class ESVApi
|
||||||
JSONValue json;
|
JSONValue json;
|
||||||
|
|
||||||
request = HTTP(format!"%s/search/?q=%s"(
|
request = HTTP(format!"%s/search/?q=%s"(
|
||||||
_url, query.replaceAll(regex(" "), "+")));
|
_url, query.tr(" ", "+"))
|
||||||
|
);
|
||||||
request.onProgress = onProgress;
|
request.onProgress = onProgress;
|
||||||
request.onReceive =
|
request.onReceive =
|
||||||
(ubyte[] data)
|
(ubyte[] data)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue