nail.rc: review
[s-mailx.git] / make-news-anchors.sh
blobc83033304743f845671c40c26c8d903d37abaa22
1 #!/bin/sh -
2 #@ make-news-anchors.sh
3 #@ Expand *XY*# / $XY# / -XY# / `XY'# / `~XY'# / "XY"# style anchors
4 #@ so that the anchor matches the number given in ANCHORFILE.
5 #@ The number sign may be followed by space, question-mark ? or a number.
6 #@ We always expand STDIN to STDOUT, but only in the range
7 #@ ChangeLog .. ^(Appendix|git\(1\) shortlog) (or EOF, of course)
8 #@ The ANCHORFILE can be produced by
9 #@ $ < manual.mdoc mdocmx.sh |
10 #@ MDOCMX_ENABLE=1 groff -U -mdoc -dmx-anchor-dump=/tmp/anchors \
11 #@ -dmx-toc-force=tree >/dev/null
12 # Public Domain
14 : ${awk:=awk}
16 syno() {
17 if [ ${#} -gt 0 ]; then
18 echo >&2 "ERROR: ${*}"
19 echo >&2
21 echo >&2 'Synopsis: make-news-anchors.sh ANCHORFILE'
22 exit 1
25 [ ${#} -eq 1 ] || syno
26 [ -f "${1}" ] || syno 'the given anchorfile does not exist'
28 APO=\'
29 ${awk} -v anchorfile="${1}" '
30 BEGIN{hot = 0}
31 /^(NOTES|ChangeLog)/{
32 hot = 1
33 print
34 next
36 /^(Appendix|git\(1\) shortlog)/{
37 hot = -1
38 print
39 next
42 if(hot <= 0){
43 print
44 next
46 any = 0
47 res = ""
48 s = $0
49 while(match(s,
50 /(^|\(|[[:space:]]+)("[^"]+"|\*[^\*]+\*|`[^'${APO}']+'${APO}'|[-~][-\/:_.[:alnum:]]+|\$[_[:alnum:]]+)#(\?|[0-9]+)?/))
52 any = 1
53 pre = (RSTART > 1) ? substr(s, 1, RSTART - 1) : ""
54 mat = substr(s, RSTART, RLENGTH)
55 s = substr(s, RSTART + RLENGTH)
57 # Unfortunately groups are not supported
58 if(match(mat, /^(\(|[[:space:]]+)/) != 0 && RLENGTH > 0){
59 pre = pre substr(mat, 1, RLENGTH)
60 mat = substr(mat, RSTART + RLENGTH)
63 match(mat, /#(\?|[0-9]+)?/)
64 mat = substr(mat, 1, RSTART - 1)
65 res = res pre mat "#"
67 if(mat ~ /^`/){ # Cm, Ic
68 mat = substr(mat, 2, length(mat) - 2)
69 t = 1
70 }else if(mat ~ /^\*/){ # Va
71 mat = substr(mat, 2, length(mat) - 2)
72 t = 2
73 }else if(mat ~ /^\$/){ # Ev, Dv
74 mat = substr(mat, 2, length(mat) - 1)
75 t = 3
76 }else if(mat ~ /^-/){ # Fl
77 mat = substr(mat, 2, length(mat) - 1)
78 t = 4
79 }else if(mat ~ /^\"/){ # Sh, Ss. But: "catch-all"
80 mat = substr(mat, 2, length(mat) - 2)
81 t = 5
82 }else
83 t = 0
85 # Insufficient, of course
86 gsub("\\\\", "\\e", mat)
88 ano = got = 0
89 while(getline < anchorfile){
90 if(t == 1){
91 if($2 != "Cm" && $2 != "Ic")
92 continue
93 }else if(t == 2){
94 if($2 != "Va")
95 continue
96 }else if(t == 3){
97 if($2 != "Ev" && $2 != "Dv")
98 continue
99 }else if(t == 4){
100 if($2 != "Fl")
101 continue
102 }else if(t == 0){
103 if($2 == "Cm" || $2 == "Ic" ||
104 $2 == "Va" ||
105 $2 == "Ev" || $2 == "Dv" ||
106 $2 == "Fl")
107 continue
110 if(!got)
111 ano = $1
112 $1 = $2 = ""
113 match($0, /^[[:space:]]*/)
114 $0 = substr($0, RLENGTH + 1)
116 if($0 == mat){
117 if(got)
118 print "WARN: ambiguous: \"" mat "\"" > "/dev/stderr"
119 got = 1
122 close(anchorfile)
123 if(!got){
124 print "ERROR: no anchor for \"" mat "\"" > "/dev/stderr"
125 res = res "?"
126 }else
127 res = res ano
129 if(any && length(s))
130 res = res s
131 print any ? res : s
135 # s-sh-mode