aboutsummaryrefslogtreecommitdiff
path: root/man.filter.dpi
blob: afe880e85a526177cb62ed2070148f6fbedab8e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/bin/bash
# Copyright (c) 2023-2025 Rodrigo Arias Mallo
# SPDX-License-Identifier: GPL-3.0-or-later

IFS= read -d '>' auth # Ignore auth
IFS= read -d '>' cmd

case "$cmd" in
  "<cmd='open_url' url='"*);;
  *) echo $cmd; exit;;
esac

url=${cmd#"<cmd='open_url' url='"}
url=${url%"' '"}

serve_404() {
  printf "<cmd='start_send_page' url='' '>\n"
  printf "Content-type: text/plain\r\n\r\n"
  manpage="$1"
  apropos="$2"
  if [ -z "$1" ]; then
    echo "Not found"
    exit 0
  fi
  echo "Manual page not found: $1"
  if [ -n "$apropos" ]; then
    printf "\nRelated pages:\n"
    man -k "$apropos"
  fi
}

inject_css() {
  css=$(cat "$(dirname $(readlink -f $0))/style.css" | tr '\n' ' ')
  sed "s_</style>_$css\n</style>_"
}

link_xrefs() {
  # Link references to other pages to a man:xyz link

  # <a class="Xr">mandoc(1)</a>
  sed 's_<a class="Xr">\([^<]*\)</a>_<a href="man:\1" class="Xr">\1</a>_g' |
  # <b>bzip2</b>(1)
  sed 's_<b>\([^<]*\)</b>(\([0-9][^)]*\))_<a href="man:\1(\2)" class="Xr">\1(\2)</a>_g' |
  # <i>nroff</i>(1)
  sed 's_<i>\([^<]*\)</i>(\([0-9][^)]*\))_<a href="man:\1(\2)" class="Xr">\1(\2)</a>_g'
}

fix_br() {
  # Line breaks <br> inside <pre> show duplicated breaks
  awk '/<pre>/ {inpre=1}; inpre && / *<br\/>$/ { next }; /<\/pre>/ { inpre=0 } { print }'
}

serve_manpage() {
  url="$1"
  ref="${url#"man:"}"
  # Remove #<frag> fragment if any
  cleanref=$(echo "$ref" | sed 's/#.*$//')
  # Reverse open(3) -> 3 open if given
  manpage=$(echo "$cleanref" | sed 's/\(.*\)(\(.*\))/\2 \1/')
  # If page not found, return 404
  if [ -z "$manpage" ]; then
    serve_404
    exit 0
  fi
  if ! man -w $manpage 2>/dev/null; then
    apropos=$(echo "$cleanref" | sed 's/(.*)//')
    serve_404 "$manpage" "$apropos"
  else
    printf "<cmd='start_send_page' url='' '>\n"
    printf "Content-type: text/html\r\n\r\n"
    unset MANROFFOPT
    man -Thtml $manpage | fix_br | inject_css | link_xrefs 2>&1
  fi
}

case "$url" in
  man:*) serve_manpage "$url";;
  *) serve_404;;
esac