@ -7,15 +7,60 @@ import std/[httpclient, json, logging, os, re, strutils, uri, wordwrap]
import cliutils , docopt , zero_functional
import cliutils , docopt , zero_functional
proc formatMarkdown ( raw : string ) : string =
proc formatMarkdown ( raw : string ) : string =
let rawLines = raw . splitLines - - > map ( it . strip )
var reference = " "
let wrapped = ( rawLines - - >
var inVerse = false
filter ( not isEmptyOrWhitespace ( it . strip ) and match ( it , re" ^ \ [ \ d+ \ ].* " ) ) .
var verseLines = newSeq [ string ] ( )
map ( it . multiReplace ( [ ( re" \ (( \ d+) \ ) " , " " ) , ( re" \ [( \ d+) \ ] " , " ** $1 ** " ) ] ) ) .
map ( wrapWords ( it , maxLineWidth = 74 , newLine = " \ p " ) ) ) .
join ( " \ p " )
result = ( wrapped . splitLines - - > map ( " > " & it ) ) . join ( " \ p " ) &
for line in raw . splitLines :
" \ p> \ p> -- * " & rawLines [ 0 ] & " (ESV)* "
if reference . len = = 0 : reference = line . strip
if inVerse :
if line . startsWith ( " Footnotes " ) : inVerse = false
elif line . isEmptyOrWhitespace and verseLines [ ^ 1 ] ! = " " :
verseLines . add ( " " )
elif not line . match ( re" ^ \ s+[^ \ s] " ) : continue
elif line . match ( re" $ (.*) \ (ESV \ ) $ " ) : verseLines . add ( line [ 0 .. < ^ 5 ] )
else : verseLines . add ( line )
elif line . match ( re" ^ \ s+ \ [ \ d+ \ ] " ) :
inVerse = true
verseLines . add ( line )
let wrapped = ( verseLines - - >
map ( if it . len > 90 : it . strip else : it & " " ) .
map ( it . multiReplace ( [ ( re" \ (( \ d+) \ ) " , " " ) , ( re" \ [( \ d+) \ ] " , " ** $1 ** " ) ] ) ) .
map ( wrapWords ( it , maxLineWidth = 74 , newLine = " \ p " ) ) ) . join ( " \ p " )
result = ( wrapped . splitLines - - > map ( " > " & it ) ) .
join ( " \ p " ) & " \ p> -- * " & reference & " (ESV)* "
proc formatPlain ( raw : string , keepVerseNumbers = true ) : string =
var reference = " "
var inVerse = false
var verseLines = newSeq [ string ] ( )
for line in raw . splitLines :
if reference . len = = 0 : reference = line . strip
if inVerse :
if line . startsWith ( " Footnotes " ) : inVerse = false
elif line . isEmptyOrWhitespace and verseLines [ ^ 1 ] ! = " " :
verseLines . add ( " " )
elif not line . match ( re" ^ \ s+[^ \ s] " ) : continue
elif line . match ( re" $ (.*) \ (ESV \ ) $ " ) : verseLines . add ( line [ 0 .. < ^ 5 ] )
else : verseLines . add ( line )
elif line . match ( re" ^ \ s+ \ [ \ d+ \ ] " ) :
inVerse = true
verseLines . add ( line )
let wrapped = ( verseLines - - >
map ( if it . len > 90 : it . strip else : it & " " ) .
map (
if keepVerseNumbers :
it . multiReplace ( [ ( re" \ (( \ d+) \ ) " , " " ) , ( re" \ [( \ d+) \ ] " , " $1 " ) ] )
else :
it . multiReplace ( [ ( re" \ (( \ d+) \ ) " , " " ) , ( re" \ [( \ d+) \ ] " , " " ) ] ) ) .
map ( wrapWords ( it , maxLineWidth = 74 , newLine = " \ p " ) ) ) . join ( " \ p " )
result = ( wrapped . splitLines - - > map ( it ) ) .
join ( " \ p " ) & " \ p– " & reference & " (ESV) "
when isMainModule :
when isMainModule :
const USAGE = """ Usage:
const USAGE = """ Usage:
@ -29,7 +74,7 @@ Options:
command line for debugging purposes.
command line for debugging purposes.
-f, --output-format <format> Select a specific output format. Valid values
-f, --output-format <format> Select a specific output format. Valid values
are ' raw ' , ' markdown ' , ' plain ' .
are ' raw ' , ' markdown ' , ' plain ' , ' reading ' .
-t, --esv-api-token <token> Provide the API token on the command line. By
-t, --esv-api-token <token> Provide the API token on the command line. By
default this will be read either from the
default this will be read either from the
@ -44,7 +89,7 @@ Options:
try :
try :
# Parse arguments
# Parse arguments
let args = docopt ( USAGE , version = " 0.2.1 " )
let args = docopt ( USAGE , version = " 0.3.0 " )
if args [ " --debug " ] :
if args [ " --debug " ] :
consoleLogger . levelThreshold = lvlDebug
consoleLogger . levelThreshold = lvlDebug
@ -71,6 +116,11 @@ Options:
let formattedPassages =
let formattedPassages =
case $ args [ " --output-format " ] :
case $ args [ " --output-format " ] :
of " plain " :
respJson [ " passages " ] . getElems - - > map ( formatPlain ( it . getStr ) )
of " reading " :
respJson [ " passages " ] . getElems - - >
map ( formatPlain ( it . getStr , keepVerseNumbers = false ) )
of " text " :
of " text " :
respJson [ " passages " ] . getElems - - >
respJson [ " passages " ] . getElems - - >
map ( it . getStr . multiReplace ( [ ( re" \ [( \ d+) \ ] " , " $1 " ) ] ) )
map ( it . getStr . multiReplace ( [ ( re" \ [( \ d+) \ ] " , " $1 " ) ] ) )