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
|
||||
*.a
|
||||
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*
|
||||
|
||||
`esv` is a utility that displays passages of the English Standard Bible on your terminal.
|
||||
It connects to the ESV web API to retrieve the passages,
|
||||
`esv` is a utility that displays passages of the English Standard Bible
|
||||
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.
|
||||
|
||||
Example usage:
|
||||
|
@ -20,18 +20,20 @@ A Psalm of David.
|
|||
He makes me lie down in green pastures....
|
||||
```
|
||||
|
||||
If the requested passage is over 32 lines long, `esv` will pipe it through a pager
|
||||
(default less). The pager being used can be changed through the `ESV_PAGER`
|
||||
environment variable or just disabled altogether by passing the -P option.
|
||||
If the requested passage is over 32 lines long, `esv` will pipe it through
|
||||
a pager (default less). The pager being used can be changed through the
|
||||
`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.
|
||||
|
||||
## Audio
|
||||
|
||||
`esv` supports playing audio passages through the -a option.
|
||||
The `mpg123` audio/video player is utilised here and so it is therefore required
|
||||
if you want to use audio mode.
|
||||
The `mpg123` audio/video player is utilised here and so it required if you
|
||||
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
|
||||
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
|
||||
[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 as a dynamic library in order to run the executable.
|
||||
installed on your system.
|
||||
|
||||
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
|
||||
|
@ -53,13 +58,15 @@ $ cd esv
|
|||
Now, compile and install:
|
||||
|
||||
```
|
||||
$ ./configure
|
||||
$ make
|
||||
# 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`
|
||||
(where `compiler` is your compiler) instead.
|
||||
<!--
|
||||
By default the configure script looks for ldc and dmd in your PATH
|
||||
and optimises the command-line arguments based on the compiler.
|
||||
-->
|
||||
|
||||
## 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.format : format;
|
||||
import std.json : JSONValue, parseJSON;
|
||||
import std.regex : regex, matchAll, replaceAll;
|
||||
import std.regex : regex, matchAll;
|
||||
import std.stdio : File;
|
||||
import std.string : capitalize;
|
||||
import std.string : capitalize, tr;
|
||||
import std.net.curl : HTTP;
|
||||
|
||||
enum ESVIndent
|
||||
|
@ -162,8 +162,6 @@ bool verseValid(in char[] verse) @safe
|
|||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ESVApi
|
||||
{
|
||||
protected {
|
||||
|
@ -234,32 +232,51 @@ class ESVApi
|
|||
params = [];
|
||||
|
||||
{
|
||||
(char[])[] parambuf;
|
||||
void *o;
|
||||
string[] parambuf;
|
||||
foreach (string opt; ESVAPI_PARAMETERS) {
|
||||
bool bo;
|
||||
int io;
|
||||
|
||||
switch (opt) {
|
||||
case "indent-using":
|
||||
o = opts.indent_using;
|
||||
o = cast(void *)opts.indent_using;
|
||||
break;
|
||||
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) {
|
||||
o = opts.b[opt];
|
||||
} else if (opt == "line-length" ||
|
||||
opt == "horizontal-line-length" ||
|
||||
!opt.matchAll("^indent-").empty) {
|
||||
o = opts.i[opt];
|
||||
}
|
||||
params = format!"%s&%s=%s"(params, opt, o.to!string());
|
||||
parambuf[parambuf.length] = format!"&%s=%s"(
|
||||
opt,
|
||||
opt == "indent-using" ?
|
||||
opts.indent_using == ESVIndent.TAB ? "tab" : "space"
|
||||
: o.to!string()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
request = HTTP(
|
||||
format!"%s/text/?q=%s+%s%s%s"(_url, book
|
||||
request = HTTP(format!"%s/text/?q=%s+%s%s%s"(
|
||||
_url,
|
||||
book
|
||||
.capitalize()
|
||||
.replaceAll(regex(" "), "+"),
|
||||
.tr(" ", "+"),
|
||||
verse, params, extraParameters)
|
||||
);
|
||||
request.onProgress = onProgress;
|
||||
|
@ -290,7 +307,12 @@ class ESVApi
|
|||
File tmpFile;
|
||||
|
||||
auto request = HTTP(format!"%s/audio/?q=%s+%s"(
|
||||
_url, book.capitalize().replaceAll(regex(" "), "+"), verse));
|
||||
_url,
|
||||
book
|
||||
.capitalize()
|
||||
.tr(" ", "+"),
|
||||
verse)
|
||||
);
|
||||
request.onProgress = onProgress;
|
||||
request.onReceive =
|
||||
(ubyte[] data)
|
||||
|
@ -320,7 +342,8 @@ class ESVApi
|
|||
JSONValue json;
|
||||
|
||||
request = HTTP(format!"%s/search/?q=%s"(
|
||||
_url, query.replaceAll(regex(" "), "+")));
|
||||
_url, query.tr(" ", "+"))
|
||||
);
|
||||
request.onProgress = onProgress;
|
||||
request.onReceive =
|
||||
(ubyte[] data)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue