script to extract an AO3 .epub and create an index.htm from toc.ncx
[shellsnippets/shellsnippets.git] / mksh / unepub
1 #!/bin/mksh
2 # $MirOS: contrib/hosted/tg/unepub,v 1.1 2011/11/13 19:58:18 tg Exp $
3 #-
4 # Copyright (c) 2011
5 #       Thorsten Glaser <tg@mirbsd.org>
6 #
7 # Provided that these terms and disclaimer and all copyright notices
8 # are retained or reproduced in an accompanying document, permission
9 # is granted to deal in this work without restriction, including un-
10 # limited rights to use, publicly perform, distribute, sell, modify,
11 # merge, give away, or sublicence.
12 #
13 # This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
14 # the utmost extent permitted by applicable law, neither express nor
15 # implied; without malicious intent or gross negligence. In no event
16 # may a licensor, author or contributor be held liable for indirect,
17 # direct, other damage, loss, or other issues arising in any way out
18 # of dealing in the work, even if advised of the possibility of such
19 # damage or existence of a defect, except proven that it results out
20 # of said person's immediate fault when using the work as intended.
21 #-
22 # Convert args foo.epub, bar.epub, ... to {foo,bar...}/{*,index.htm}
23 # using perl (easy U+00A0 fixup), unzip and xmlstarlet from ports.
24
25 function ncx2html {
26         local state texts links docTitle=""
27
28         # I would use xmlstarlet sel, but it seems to be broken, or,
29         # XPath is not obvious to learn
30         <"$1" tr '\n\t' ' ' | sed -e 's/> *</></g' | xmlstarlet pyx |&
31         state=0
32         set -A texts
33         set -A links
34         while IFS= read -pr line; do
35                 case $state {
36                 (0)
37                         [[ $line = '(docTitle' ]] && state=1
38                         continue ;;
39                 (1)
40                         [[ $line = ')'* ]] && state=2
41                         [[ $line = '-'* ]] || continue
42                         docTitle+=${line#-}
43                         ;;
44                 (2)
45                         [[ $line = 'AplayOrder '+([0-9]) ]] || continue
46                         idx=${line#* }
47                         state=3 ;;
48                 (3)
49                         [[ $line = ')'* ]] && state=4
50                         [[ $line = '-'* ]] || continue
51                         texts[idx]+=${line#-}
52                         ;;
53                 (4)
54                         [[ $line = 'Asrc '* ]] || continue
55                         links[idx]=${line#* }
56                         state=2 ;;
57                 }
58         done
59         : ${docTitle:=unknown title}
60
61         print -r '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
62          "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
63         <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head>
64          <meta http-equiv="content-type" content="text/html; charset=utf-8" />
65          <title>'"$docTitle"'</title>
66         </head><body>
67         <h1>'"$docTitle</h1>
68         <ul>"
69         for idx in ${!links[*]}; do
70                 print -r " <li>$idx. <a href=\"${links[idx]}\">${texts[idx]:-〈${links[idx]}〉}</a></li>"
71         done
72         print '</ul>
73         </body></html>'
74 }
75
76 for fn in "$@"; do
77         dn=${fn%.epub}
78         [[ $dn = "$fn" ]] && dn=$dn.extracted
79         mkdir -p "$dn/tmp"
80         cd "$dn/tmp"
81         unzip "../../$fn"
82         mv content/* ..
83         cd ..
84         rm -rf tmp
85         perl -pi -e 's/ / /g' toc.ncx *.htm*
86         ncx2html toc.ncx >index.htm
87         cd ..
88 done