diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2000-04-09 07:58:38 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2000-04-09 07:58:38 +0000 |
commit | 098fe4a0b368c914c7d1f7ce086634958df8796a (patch) | |
tree | 35c4467b0223be7d6cd8bf4a8d03b0010b342e2a | |
parent | 972922b0b73ac8052cf5ab98e029ac4e27c752f3 (diff) |
groff 1.15
45 files changed, 21004 insertions, 0 deletions
diff --git a/gnu/usr.bin/groff/devhtml/CB b/gnu/usr.bin/groff/devhtml/CB new file mode 100644 index 00000000000..7ca40b89c0e --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/CB @@ -0,0 +1,306 @@ +name CB +spacewidth 9 +charset +--- 9,1 0 040 +! 9,9 0 041 +" 9,10 0 042 +# 9,10,1 0 043 +sh " +$ 9,11,1 0 044 +Do " +% 9,10 0 045 +& 9,8 0 046 +' 9,10 0 047 +( 9,9,2 0 050 +) 9,9,2 0 051 +* 9,9 0 052 ++ 9,8 0 053 +, 9,2,2 0 054 +\- 9,5 0 055 +. 9,2 0 056 +/ 9,10,2 0 057 +sl " +0 9,10 0 060 +1 9,10 0 061 +2 9,10 0 062 +3 9,10 0 063 +4 9,10 0 064 +5 9,10 0 065 +6 9,10 0 066 +7 9,10 0 067 +8 9,10 0 070 +9 9,10 0 071 +: 9,7 0 072 +; 9,7,2 0 073 +< 9,8 0 074 += 9,6 0 075 +eq " +> 9,8 0 076 +? 9,9 0 077 +@ 9,9 0 0100 +at " +A 9,9 0 0101 +B 9,9 0 0102 +C 9,9 0 0103 +D 9,9 0 0104 +E 9,9 0 0105 +F 9,9 0 0106 +G 9,9 0 0107 +H 9,9 0 0110 +I 9,9 0 0111 +J 9,9 0 0112 +K 9,9 0 0113 +L 9,9 0 0114 +M 9,9 0 0115 +N 9,9 0 0116 +O 9,9 0 0117 +P 9,9 0 0120 +Q 9,9,2 0 0121 +R 9,9 0 0122 +S 9,9 0 0123 +T 9,9 0 0124 +U 9,9 0 0125 +V 9,9 0 0126 +W 9,9 0 0127 +X 9,9 0 0130 +Y 9,9 0 0131 +Z 9,9 0 0132 +[ 9,9,2 0 0133 +lB " +\ 9,10,2 0 0134 +rs " +] 9,9,2 0 0135 +rB " +^ 9,9 0 0136 +a^ " +ha " +_ 9,0,2 0 0137 +` 9,10 0 0140 +oq " +a 9,7 0 0141 +b 9,10 0 0142 +c 9,7 0 0143 +d 9,10 0 0144 +e 9,7 0 0145 +f 9,10 0 0146 +g 9,7,3 0 0147 +h 9,10 0 0150 +i 9,10 0 0151 +j 9,10,3 0 0152 +k 9,10 0 0153 +l 9,10 0 0154 +m 9,7 0 0155 +n 9,7 0 0156 +o 9,7 0 0157 +p 9,7,3 0 0160 +q 9,7,3 0 0161 +r 9,7 0 0162 +s 9,7 0 0163 +t 9,9 0 0164 +u 9,7 0 0165 +v 9,7 0 0166 +w 9,7 0 0167 +x 9,7 0 0170 +y 9,7,3 0 0171 +z 9,7 0 0172 +{ 9,9,2 0 0173 +lC " +| 9,9,2 0 0174 +or " +ba " +} 9,9,2 0 0175 +rC " +~ 9,6 0 0176 +a~ " +ap " +ti " +r! 9,7,2 0 0241 +¡ " +ct 9,9,1 0 0242 +¢ " +Po 9,9 0 0243 +£ " +Cs 9,7 0 0244 +¤ " +Ye 9,9 0 0245 +¥ " +bb 9,9,2 0 0246 +¦ " +sc 9,10,1 0 0247 +§ " +ad 9,10 0 0250 +¨ " +co 9,9 0 0251 +© " +Of 9,9 0 0252 +ª " +Fo 9,6 0 0253 +« " +no 9,5 0 0254 +¬ " +- 9,5 0 055 +hy " + " +rg 9,9 0 0256 +® " +a- 9,9 0 0257 +¯ " +de 9,9 0 0260 +° " ++- 9,8 0 0261 +± " +S2 9,10 0 0262 +² " +S3 9,10 0 0263 +³ " +aa 9,9 0 0264 +´ " +µ 9,7,3 0 0265 +ps 9,10,1 0 0266 +¶ " +md 9,5 0 0267 +· " +ac 9,1,3 0 0270 +¸ " +S1 9,10 0 0271 +¹ " +Om 9,9 0 0272 +º " +Fc 9,6 0 0273 +» " +14 9,10 0 0274 +¼ " +12 9,10 0 0275 +½ " +34 9,10 0 0276 +¾ " +r? 9,7,2 0 0277 +¿ " +`A 9,12 0 0300 +À " +'A 9,12 0 0301 +Á " +^A 9,12 0 0302 +Â " +~A 9,12 0 0303 +Ã " +:A 9,12 0 0304 +Ä " +oA 9,12 0 0305 +Å " +AE 9,9 0 0306 +Æ " +,C 9,9,4 0 0307 +Ç " +`E 9,12 0 0310 +È " +'E 9,12 0 0311 +É " +^E 9,12 0 0312 +Ê " +:E 9,12 0 0313 +Ë " +`I 9,12 0 0314 +Ì " +'I 9,12 0 0315 +Í " +^I 9,12 0 0316 +Î " +:I 9,12 0 0317 +Ï " +-D 9,9 0 0320 +Ð " +~N 9,12 0 0321 +Ñ " +`O 9,12 0 0322 +Ò " +'O 9,12 0 0323 +Ó " +^O 9,12 0 0324 +Ô " +~O 9,12 0 0325 +Õ " +:O 9,12 0 0326 +Ö " +mu 9,8 0 0327 +× " +/O 9,10 0 0330 +Ø " +`U 9,12 0 0331 +Ù " +'U 9,12 0 0332 +Ú " +^U 9,12 0 0333 +Û " +:U 9,12 0 0334 +Ü " +'Y 9,12 0 0335 +Ý " +TP 9,9 0 0336 +Þ " +ss 9,9 0 0337 +ß " +`a 9,10 0 0340 +à " +'a 9,10 0 0341 +á " +^a 9,10 0 0342 +â " +~a 9,10 0 0343 +ã " +:a 9,10 0 0344 +ä " +oa 9,10 0 0345 +å " +ae 9,7 0 0346 +æ " +,c 9,7,4 0 0347 +ç " +`e 9,10 0 0350 +è " +'e 9,10 0 0351 +é " +^e 9,10 0 0352 +ê " +:e 9,10 0 0353 +ë " +`i 9,10 0 0354 +ì " +'i 9,10 0 0355 +í " +^i 9,10 0 0356 +î " +:i 9,10 0 0357 +ï " +Sd 9,10 0 0360 +ð " +~n 9,10 0 0361 +ñ " +`o 9,10 0 0362 +ò " +'o 9,10 0 0363 +ó " +^o 9,10 0 0364 +ô " +~o 9,10 0 0365 +õ " +:o 9,10 0 0366 +ö " +di 9,8 0 0367 +÷ " +/o 9,7 0 0370 +ø " +`u 9,10 0 0371 +ù " +'u 9,10 0 0372 +ú " +^u 9,10 0 0373 +û " +:u 9,10 0 0374 +ü " +'y 9,10,3 0 0375 +ý " +Tp 9,9,3 0 0376 +þ " +:y 9,10,3 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/devhtml/CBI b/gnu/usr.bin/groff/devhtml/CBI new file mode 100644 index 00000000000..551ed26161d --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/CBI @@ -0,0 +1,306 @@ +name CBI +spacewidth 9 +charset +--- 9,1 0 040 +! 9,10 0 041 +" 9,9 0 042 +# 9,11,1 0 043 +sh " +$ 9,11,1 0 044 +Do " +% 9,10 0 045 +& 9,8 0 046 +' 9,9 0 047 +( 9,9,2 0 050 +) 9,9,2 0 051 +* 9,10 0 052 ++ 9,8 0 053 +, 9,2,2 0 054 +\- 9,5 0 055 +. 9,2 0 056 +/ 9,10,2 0 057 +sl " +0 9,10 0 060 +1 9,10 0 061 +2 9,10 0 062 +3 9,10 0 063 +4 9,10 0 064 +5 9,10 0 065 +6 9,10 0 066 +7 9,10 0 067 +8 9,10 0 070 +9 9,10 0 071 +: 9,7 0 072 +; 9,7,2 0 073 +< 9,8 0 074 += 9,6 0 075 +eq " +> 9,8 0 076 +? 9,9 0 077 +@ 9,9 0 0100 +at " +A 9,9 0 0101 +B 9,9 0 0102 +C 9,9 0 0103 +D 9,9 0 0104 +E 9,9 0 0105 +F 9,9 0 0106 +G 9,9 0 0107 +H 9,9 0 0110 +I 9,9 0 0111 +J 9,9 0 0112 +K 9,9 0 0113 +L 9,9 0 0114 +M 9,9 0 0115 +N 9,9 0 0116 +O 9,9 0 0117 +P 9,9 0 0120 +Q 9,9,2 0 0121 +R 9,9 0 0122 +S 9,9 0 0123 +T 9,9 0 0124 +U 9,9 0 0125 +V 9,9 0 0126 +W 9,9 0 0127 +X 9,9 0 0130 +Y 9,9 0 0131 +Z 9,9 0 0132 +[ 9,9,2 0 0133 +lB " +\ 9,10,2 0 0134 +rs " +] 9,9,2 0 0135 +rB " +^ 9,9 0 0136 +a^ " +ha " +_ 9,0,3 0 0137 +` 9,9 0 0140 +oq " +a 9,7 0 0141 +b 9,10 0 0142 +c 9,7 0 0143 +d 9,10 0 0144 +e 9,7 0 0145 +f 9,10 0 0146 +g 9,7,3 0 0147 +h 9,10 0 0150 +i 9,10 0 0151 +j 9,10,3 0 0152 +k 9,10 0 0153 +l 9,10 0 0154 +m 9,7 0 0155 +n 9,7 0 0156 +o 9,7 0 0157 +p 9,7,3 0 0160 +q 9,7,3 0 0161 +r 9,7 0 0162 +s 9,7 0 0163 +t 9,9 0 0164 +u 9,7 0 0165 +v 9,7 0 0166 +w 9,7 0 0167 +x 9,7 0 0170 +y 9,7,3 0 0171 +z 9,7 0 0172 +{ 9,9,2 0 0173 +lC " +| 9,9,2 0 0174 +or " +ba " +} 9,9,2 0 0175 +rC " +~ 9,6 0 0176 +a~ " +ap " +ti " +r! 9,7,3 0 0241 +¡ " +ct 9,9,1 0 0242 +¢ " +Po 9,9 0 0243 +£ " +Cs 9,7 0 0244 +¤ " +Ye 9,9 0 0245 +¥ " +bb 9,10,2 0 0246 +¦ " +sc 9,10,1 0 0247 +§ " +ad 9,10 0 0250 +¨ " +co 9,9 0 0251 +© " +Of 9,9 0 0252 +ª " +Fo 9,6 0 0253 +« " +no 9,6 0 0254 +¬ " +- 9,5 0 055 +hy " + " +rg 9,9 0 0256 +® " +a- 9,9 0 0257 +¯ " +de 9,10 0 0260 +° " ++- 9,8 0 0261 +± " +S2 9,10 0 0262 +² " +S3 9,10 0 0263 +³ " +aa 9,10 0 0264 +´ " +µ 9,7,3 0 0265 +ps 9,10,1 0 0266 +¶ " +md 9,5 0 0267 +· " +ac 9,1,3 0 0270 +¸ " +S1 9,10 0 0271 +¹ " +Om 9,9 0 0272 +º " +Fc 9,6 0 0273 +» " +14 9,10 0 0274 +¼ " +12 9,10 0 0275 +½ " +34 9,10 0 0276 +¾ " +r? 9,7,2 0 0277 +¿ " +`A 9,12 0 0300 +À " +'A 9,12 0 0301 +Á " +^A 9,12 0 0302 +Â " +~A 9,12 0 0303 +Ã " +:A 9,12 0 0304 +Ä " +oA 9,12 0 0305 +Å " +AE 9,9 0 0306 +Æ " +,C 9,9,4 0 0307 +Ç " +`E 9,12 0 0310 +È " +'E 9,12 0 0311 +É " +^E 9,12 0 0312 +Ê " +:E 9,12 0 0313 +Ë " +`I 9,12 0 0314 +Ì " +'I 9,12 0 0315 +Í " +^I 9,12 0 0316 +Î " +:I 9,12 0 0317 +Ï " +-D 9,9 0 0320 +Ð " +~N 9,12 0 0321 +Ñ " +`O 9,12 0 0322 +Ò " +'O 9,12 0 0323 +Ó " +^O 9,12 0 0324 +Ô " +~O 9,12 0 0325 +Õ " +:O 9,12 0 0326 +Ö " +mu 9,8 0 0327 +× " +/O 9,9 0 0330 +Ø " +`U 9,12 0 0331 +Ù " +'U 9,12 0 0332 +Ú " +^U 9,12 0 0333 +Û " +:U 9,12 0 0334 +Ü " +'Y 9,12 0 0335 +Ý " +TP 9,9 0 0336 +Þ " +ss 9,9 0 0337 +ß " +`a 9,10 0 0340 +à " +'a 9,10 0 0341 +á " +^a 9,10 0 0342 +â " +~a 9,10 0 0343 +ã " +:a 9,10 0 0344 +ä " +oa 9,10 0 0345 +å " +ae 9,7 0 0346 +æ " +,c 9,7,4 0 0347 +ç " +`e 9,10 0 0350 +è " +'e 9,10 0 0351 +é " +^e 9,10 0 0352 +ê " +:e 9,10 0 0353 +ë " +`i 9,10 0 0354 +ì " +'i 9,10 0 0355 +í " +^i 9,10 0 0356 +î " +:i 9,10 0 0357 +ï " +Sd 9,10 0 0360 +ð " +~n 9,10 0 0361 +ñ " +`o 9,10 0 0362 +ò " +'o 9,10 0 0363 +ó " +^o 9,10 0 0364 +ô " +~o 9,10 0 0365 +õ " +:o 9,10 0 0366 +ö " +di 9,8 0 0367 +÷ " +/o 9,8 0 0370 +ø " +`u 9,10 0 0371 +ù " +'u 9,10 0 0372 +ú " +^u 9,10 0 0373 +û " +:u 9,10 0 0374 +ü " +'y 9,10,3 0 0375 +ý " +Tp 9,9,3 0 0376 +þ " +:y 9,10,3 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/devhtml/CI b/gnu/usr.bin/groff/devhtml/CI new file mode 100644 index 00000000000..6b26256beee --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/CI @@ -0,0 +1,306 @@ +name CI +spacewidth 9 +charset +--- 9,1 0 040 +! 9,9 0 041 +" 9,10 0 042 +# 9,10,1 0 043 +sh " +$ 9,10,1 0 044 +Do " +% 9,10 0 045 +& 9,8 0 046 +' 9,10 0 047 +( 9,10,3 0 050 +) 9,10,3 0 051 +* 9,9 0 052 ++ 9,8 0 053 +, 9,2,2 0 054 +\- 9,5 0 055 +. 9,2 0 056 +/ 9,10,2 0 057 +sl " +0 9,10 0 060 +1 9,10 0 061 +2 9,10 0 062 +3 9,10 0 063 +4 9,10 0 064 +5 9,10 0 065 +6 9,10 0 066 +7 9,10 0 067 +8 9,10 0 070 +9 9,10 0 071 +: 9,7 0 072 +; 9,7,2 0 073 +< 9,8 0 074 += 9,6 0 075 +eq " +> 9,8 0 076 +? 9,9 0 077 +@ 9,9 0 0100 +at " +A 9,9 0 0101 +B 9,9 0 0102 +C 9,9 0 0103 +D 9,9 0 0104 +E 9,9 0 0105 +F 9,9 0 0106 +G 9,9 0 0107 +H 9,9 0 0110 +I 9,9 0 0111 +J 9,9 0 0112 +K 9,9 0 0113 +L 9,9 0 0114 +M 9,9 0 0115 +N 9,9 0 0116 +O 9,9 0 0117 +P 9,9 0 0120 +Q 9,9,2 0 0121 +R 9,9 0 0122 +S 9,9 0 0123 +T 9,9 0 0124 +U 9,9 0 0125 +V 9,9 0 0126 +W 9,9 0 0127 +X 9,9 0 0130 +Y 9,9 0 0131 +Z 9,9 0 0132 +[ 9,10,3 0 0133 +lB " +\ 9,10,2 0 0134 +rs " +] 9,10,3 0 0135 +rB " +^ 9,9 0 0136 +a^ " +ha " +_ 9,0,3 0 0137 +` 9,10 0 0140 +oq " +a 9,7 0 0141 +b 9,10 0 0142 +c 9,7 0 0143 +d 9,10 0 0144 +e 9,7 0 0145 +f 9,10 0 0146 +g 9,7,3 0 0147 +h 9,10 0 0150 +i 9,10 0 0151 +j 9,10,3 0 0152 +k 9,10 0 0153 +l 9,10 0 0154 +m 9,7 0 0155 +n 9,7 0 0156 +o 9,7 0 0157 +p 9,7,3 0 0160 +q 9,7,3 0 0161 +r 9,7 0 0162 +s 9,7 0 0163 +t 9,9 0 0164 +u 9,7 0 0165 +v 9,7 0 0166 +w 9,7 0 0167 +x 9,7 0 0170 +y 9,7,3 0 0171 +z 9,7 0 0172 +{ 9,10,3 0 0173 +lC " +| 9,9,2 0 0174 +or " +ba " +} 9,10,3 0 0175 +rC " +~ 9,5 0 0176 +a~ " +ap " +ti " +r! 9,7,2 0 0241 +¡ " +ct 9,10 0 0242 +¢ " +Po 9,9 0 0243 +£ " +Cs 9,7 0 0244 +¤ " +Ye 9,9 0 0245 +¥ " +bb 9,9,2 0 0246 +¦ " +sc 9,9,1 0 0247 +§ " +ad 9,9 0 0250 +¨ " +co 9,9 0 0251 +© " +Of 9,9 0 0252 +ª " +Fo 9,7 0 0253 +« " +no 9,6 0 0254 +¬ " +- 9,5 0 055 +hy " + " +rg 9,9 0 0256 +® " +a- 9,9 0 0257 +¯ " +de 9,10 0 0260 +° " ++- 9,8 0 0261 +± " +S2 9,10 0 0262 +² " +S3 9,10 0 0263 +³ " +aa 9,9 0 0264 +´ " +µ 9,7,3 0 0265 +ps 9,9,1 0 0266 +¶ " +md 9,5 0 0267 +· " +ac 9,1,3 0 0270 +¸ " +S1 9,10 0 0271 +¹ " +Om 9,9 0 0272 +º " +Fc 9,7 0 0273 +» " +14 9,10 0 0274 +¼ " +12 9,10 0 0275 +½ " +34 9,10 0 0276 +¾ " +r? 9,7,2 0 0277 +¿ " +`A 9,12 0 0300 +À " +'A 9,12 0 0301 +Á " +^A 9,12 0 0302 +Â " +~A 9,12 0 0303 +Ã " +:A 9,11 0 0304 +Ä " +oA 9,12 0 0305 +Å " +AE 9,9 0 0306 +Æ " +,C 9,9,3 0 0307 +Ç " +`E 9,12 0 0310 +È " +'E 9,12 0 0311 +É " +^E 9,12 0 0312 +Ê " +:E 9,11 0 0313 +Ë " +`I 9,12 0 0314 +Ì " +'I 9,12 0 0315 +Í " +^I 9,12 0 0316 +Î " +:I 9,11 0 0317 +Ï " +-D 9,9 0 0320 +Ð " +~N 9,12 0 0321 +Ñ " +`O 9,12 0 0322 +Ò " +'O 9,12 0 0323 +Ó " +^O 9,12 0 0324 +Ô " +~O 9,12 0 0325 +Õ " +:O 9,11 0 0326 +Ö " +mu 9,8 0 0327 +× " +/O 9,9 0 0330 +Ø " +`U 9,12 0 0331 +Ù " +'U 9,12 0 0332 +Ú " +^U 9,12 0 0333 +Û " +:U 9,11 0 0334 +Ü " +'Y 9,12 0 0335 +Ý " +TP 9,9 0 0336 +Þ " +ss 9,9 0 0337 +ß " +`a 9,10 0 0340 +à " +'a 9,10 0 0341 +á " +^a 9,10 0 0342 +â " +~a 9,10 0 0343 +ã " +:a 9,9 0 0344 +ä " +oa 9,11 0 0345 +å " +ae 9,7 0 0346 +æ " +,c 9,7,3 0 0347 +ç " +`e 9,10 0 0350 +è " +'e 9,10 0 0351 +é " +^e 9,10 0 0352 +ê " +:e 9,9 0 0353 +ë " +`i 9,10 0 0354 +ì " +'i 9,10 0 0355 +í " +^i 9,10 0 0356 +î " +:i 9,9 0 0357 +ï " +Sd 9,10 0 0360 +ð " +~n 9,10 0 0361 +ñ " +`o 9,10 0 0362 +ò " +'o 9,10 0 0363 +ó " +^o 9,10 0 0364 +ô " +~o 9,10 0 0365 +õ " +:o 9,9 0 0366 +ö " +di 9,8 0 0367 +÷ " +/o 9,7 0 0370 +ø " +`u 9,10 0 0371 +ù " +'u 9,10 0 0372 +ú " +^u 9,10 0 0373 +û " +:u 9,9 0 0374 +ü " +'y 9,10,3 0 0375 +ý " +Tp 9,9,3 0 0376 +þ " +:y 9,9,3 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/devhtml/CR b/gnu/usr.bin/groff/devhtml/CR new file mode 100644 index 00000000000..d8020a1b539 --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/CR @@ -0,0 +1,306 @@ +name CR +spacewidth 9 +charset +--- 9,1 0 040 +! 9,9 0 041 +" 9,10 0 042 +# 9,9,1 0 043 +sh " +$ 9,11,2 0 044 +Do " +% 9,10 0 045 +& 9,8 0 046 +' 9,10 0 047 +( 9,10,2 0 050 +) 9,10,2 0 051 +* 9,9 0 052 ++ 9,8 0 053 +, 9,2,2 0 054 +\- 9,5 0 055 +. 9,2 0 056 +/ 9,10,1 0 057 +sl " +0 9,10 0 060 +1 9,10 0 061 +2 9,10 0 062 +3 9,10 0 063 +4 9,10 0 064 +5 9,10 0 065 +6 9,10 0 066 +7 9,10 0 067 +8 9,10 0 070 +9 9,10 0 071 +: 9,7 0 072 +; 9,7,2 0 073 +< 9,8 0 074 += 9,6 0 075 +eq " +> 9,8 0 076 +? 9,9 0 077 +@ 9,9,1 0 0100 +at " +A 9,9 0 0101 +B 9,9 0 0102 +C 9,9 0 0103 +D 9,9 0 0104 +E 9,9 0 0105 +F 9,9 0 0106 +G 9,9 0 0107 +H 9,9 0 0110 +I 9,9 0 0111 +J 9,9 0 0112 +K 9,9 0 0113 +L 9,9 0 0114 +M 9,9 0 0115 +N 9,9 0 0116 +O 9,9 0 0117 +P 9,9 0 0120 +Q 9,9,2 0 0121 +R 9,9 0 0122 +S 9,9 0 0123 +T 9,9 0 0124 +U 9,9 0 0125 +V 9,9 0 0126 +W 9,9 0 0127 +X 9,9 0 0130 +Y 9,9 0 0131 +Z 9,9 0 0132 +[ 9,10,2 0 0133 +lB " +\ 9,10,1 0 0134 +rs " +] 9,10,2 0 0135 +rB " +^ 9,9 0 0136 +a^ " +ha " +_ 9,0,3 0 0137 +` 9,10 0 0140 +oq " +a 9,7 0 0141 +b 9,10 0 0142 +c 9,7 0 0143 +d 9,10 0 0144 +e 9,7 0 0145 +f 9,10 0 0146 +g 9,7,3 0 0147 +h 9,10 0 0150 +i 9,10 0 0151 +j 9,10,3 0 0152 +k 9,10 0 0153 +l 9,10 0 0154 +m 9,7 0 0155 +n 9,7 0 0156 +o 9,7 0 0157 +p 9,7,3 0 0160 +q 9,7,3 0 0161 +r 9,7 0 0162 +s 9,7 0 0163 +t 9,9 0 0164 +u 9,7 0 0165 +v 9,7 0 0166 +w 9,7 0 0167 +x 9,7 0 0170 +y 9,7,3 0 0171 +z 9,7 0 0172 +{ 9,10,2 0 0173 +lC " +| 9,9,2 0 0174 +or " +ba " +} 9,10,2 0 0175 +rC " +~ 9,5 0 0176 +a~ " +ap " +ti " +r! 9,7,2 0 0241 +¡ " +ct 9,9 0 0242 +¢ " +Po 9,9 0 0243 +£ " +Cs 9,7 0 0244 +¤ " +Ye 9,9 0 0245 +¥ " +bb 9,9,2 0 0246 +¦ " +sc 9,9,1 0 0247 +§ " +ad 9,9 0 0250 +¨ " +co 9,9 0 0251 +© " +Of 9,9 0 0252 +ª " +Fo 9,7 0 0253 +« " +no 9,6 0 0254 +¬ " +- 9,5 0 055 +hy " + " +rg 9,9 0 0256 +® " +a- 9,9 0 0257 +¯ " +de 9,10 0 0260 +° " ++- 9,8 0 0261 +± " +S2 9,10 0 0262 +² " +S3 9,10 0 0263 +³ " +aa 9,10 0 0264 +´ " +µ 9,7,3 0 0265 +ps 9,9,1 0 0266 +¶ " +md 9,5 0 0267 +· " +ac 9,0,3 0 0270 +¸ " +S1 9,10 0 0271 +¹ " +Om 9,9 0 0272 +º " +Fc 9,7 0 0273 +» " +14 9,10 0 0274 +¼ " +12 9,10 0 0275 +½ " +34 9,10 0 0276 +¾ " +r? 9,7,2 0 0277 +¿ " +`A 9,12 0 0300 +À " +'A 9,12 0 0301 +Á " +^A 9,12 0 0302 +Â " +~A 9,12 0 0303 +Ã " +:A 9,11 0 0304 +Ä " +oA 9,12 0 0305 +Å " +AE 9,9 0 0306 +Æ " +,C 9,9,3 0 0307 +Ç " +`E 9,12 0 0310 +È " +'E 9,12 0 0311 +É " +^E 9,12 0 0312 +Ê " +:E 9,11 0 0313 +Ë " +`I 9,12 0 0314 +Ì " +'I 9,12 0 0315 +Í " +^I 9,12 0 0316 +Î " +:I 9,11 0 0317 +Ï " +-D 9,9 0 0320 +Ð " +~N 9,12 0 0321 +Ñ " +`O 9,12 0 0322 +Ò " +'O 9,12 0 0323 +Ó " +^O 9,12 0 0324 +Ô " +~O 9,12 0 0325 +Õ " +:O 9,11 0 0326 +Ö " +mu 9,8 0 0327 +× " +/O 9,9 0 0330 +Ø " +`U 9,12 0 0331 +Ù " +'U 9,12 0 0332 +Ú " +^U 9,12 0 0333 +Û " +:U 9,11 0 0334 +Ü " +'Y 9,12 0 0335 +Ý " +TP 9,9 0 0336 +Þ " +ss 9,9 0 0337 +ß " +`a 9,10 0 0340 +à " +'a 9,10 0 0341 +á " +^a 9,10 0 0342 +â " +~a 9,10 0 0343 +ã " +:a 9,9 0 0344 +ä " +oa 9,10 0 0345 +å " +ae 9,7 0 0346 +æ " +,c 9,7,3 0 0347 +ç " +`e 9,10 0 0350 +è " +'e 9,10 0 0351 +é " +^e 9,10 0 0352 +ê " +:e 9,9 0 0353 +ë " +`i 9,10 0 0354 +ì " +'i 9,10 0 0355 +í " +^i 9,10 0 0356 +î " +:i 9,9 0 0357 +ï " +Sd 9,12 0 0360 +ð " +~n 9,10 0 0361 +ñ " +`o 9,10 0 0362 +ò " +'o 9,10 0 0363 +ó " +^o 9,10 0 0364 +ô " +~o 9,10 0 0365 +õ " +:o 9,9 0 0366 +ö " +di 9,8 0 0367 +÷ " +/o 9,7 0 0370 +ø " +`u 9,10 0 0371 +ù " +'u 9,10 0 0372 +ú " +^u 9,10 0 0373 +û " +:u 9,9 0 0374 +ü " +'y 9,10,3 0 0375 +ý " +Tp 9,9,3 0 0376 +þ " +:y 9,9,3 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/devhtml/DESC b/gnu/usr.bin/groff/devhtml/DESC new file mode 100644 index 00000000000..dcab7cd4adf --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/DESC @@ -0,0 +1,10 @@ +styles R I B BI +fonts 6 0 0 0 0 0 S +sizes 8 10 12 14 18 24 0 +res 100 +tcommand +html +hor 1 +vert 1 +unitwidth 10 +postpro grohtml diff --git a/gnu/usr.bin/groff/devhtml/HB b/gnu/usr.bin/groff/devhtml/HB new file mode 100644 index 00000000000..06f2bf95f61 --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/HB @@ -0,0 +1,306 @@ +name HB +spacewidth 4 +charset +--- 4,1 0 040 +! 4,11 0 041 +" 7,11 0 042 +# 9,10 0 043 +sh " +$ 8,12,2 0 044 +Do " +% 13,11 0 045 +& 11,10 0 046 +' 5,11 0 047 +( 5,11,3 0 050 +) 5,11,3 0 051 +* 6,11 0 052 ++ 9,8 0 053 +, 4,2,1 0 054 +\- 9,5 0 055 +. 4,2 0 056 +/ 4,11 0 057 +sl " +0 8,11 0 060 +1 8,11 0 061 +2 8,11 0 062 +3 8,11 0 063 +4 8,11 0 064 +5 8,11 0 065 +6 8,11 0 066 +7 8,11 0 067 +8 8,11 0 070 +9 8,11 0 071 +: 5,8 0 072 +; 5,8,1 0 073 +< 8,7 0 074 += 9,6 0 075 +eq " +> 8,7 0 076 +? 9,11 0 077 +@ 14,11,1 0 0100 +at " +A 10,11 0 0101 +B 10,11 0 0102 +C 11,11 0 0103 +D 11,11 0 0104 +E 9,11 0 0105 +F 9,11 0 0106 +G 11,11 0 0107 +H 10,11 0 0110 +I 4,11 0 0111 +J 8,11 0 0112 +K 10,11 0 0113 +L 8,11 0 0114 +M 13,11 0 0115 +N 11,11 0 0116 +O 12,11 0 0117 +P 10,11 0 0120 +Q 12,11 0 0121 +R 11,11 0 0122 +S 10,11 0 0123 +T 8,11 0 0124 +U 11,11 0 0125 +V 10,11 0 0126 +W 14,11 0 0127 +X 9,11 0 0130 +Y 10,11 0 0131 +Z 9,11 0 0132 +[ 5,11,3 0 0133 +lB " +\ 4,11 0 0134 +rs " +] 5,11,3 0 0135 +rB " +^ 8,11 0 0136 +a^ " +ha " +_ 8,0,3 0 0137 +` 5,11 0 0140 +oq " +a 8,8 0 0141 +b 9,11 0 0142 +c 8,8 0 0143 +d 9,11 0 0144 +e 8,8 0 0145 +f 4,11 0 0146 +g 9,8,3 0 0147 +h 9,11 0 0150 +i 4,11 0 0151 +j 4,11,3 0 0152 +k 8,11 0 0153 +l 4,11 0 0154 +m 12,8 0 0155 +n 9,8 0 0156 +o 9,8 0 0157 +p 9,8,3 0 0160 +q 9,8,3 0 0161 +r 6,8 0 0162 +s 8,8 0 0163 +t 5,10 0 0164 +u 9,8 0 0165 +v 8,8 0 0166 +w 10,8 0 0167 +x 7,8 0 0170 +y 8,8,3 0 0171 +z 6,8 0 0172 +{ 6,11,3 0 0173 +lC " +| 4,11,3 0 0174 +or " +ba " +} 6,11,3 0 0175 +rC " +~ 9,6 0 0176 +a~ " +ap " +ti " +r! 4,8,3 0 0241 +¡ " +ct 8,9,1 0 0242 +¢ " +Po 8,11 0 0243 +£ " +Cs 8,9 0 0244 +¤ " +Ye 9,11 0 0245 +¥ " +bb 4,11,3 0 0246 +¦ " +sc 8,11,3 0 0247 +§ " +ad 5,11 0 0250 +¨ " +co 12,11 0 0251 +© " +Of 6,11 0 0252 +ª " +Fo 9,7 0 0253 +« " +no 9,6 0 0254 +¬ " +- 4,5 0 055 +hy " + " +rg 12,11 0 0256 +® " +a- 5,10 0 0257 +¯ " +de 6,11 0 0260 +° " ++- 9,9 0 0261 +± " +S2 5,11 0 0262 +² " +S3 5,11 0 0263 +³ " +aa 5,11 0 0264 +´ " +µ 9,8,3 0 0265 +ps 8,11,3 0 0266 +¶ " +md 4,5 0 0267 +· " +ac 5,0,3 0 0270 +¸ " +S1 4,11 0 0271 +¹ " +Om 6,11 0 0272 +º " +Fc 9,7 0 0273 +» " +14 12,11 0 0274 +¼ " +12 12,11 0 0275 +½ " +34 12,11 0 0276 +¾ " +r? 9,8,3 0 0277 +¿ " +`A 10,14 0 0300 +À " +'A 10,14 0 0301 +Á " +^A 10,14 0 0302 +Â " +~A 10,14 0 0303 +Ã " +:A 10,14 0 0304 +Ä " +oA 10,14 0 0305 +Å " +AE 15,11 0 0306 +Æ " +,C 11,11,3 0 0307 +Ç " +`E 9,14 0 0310 +È " +'E 9,14 0 0311 +É " +^E 9,14 0 0312 +Ê " +:E 9,14 0 0313 +Ë " +`I 4,14 0 0314 +Ì " +'I 4,14 0 0315 +Í " +^I 4,14 0 0316 +Î " +:I 4,14 0 0317 +Ï " +-D 11,11 0 0320 +Ð " +~N 11,14 0 0321 +Ñ " +`O 12,14 0 0322 +Ò " +'O 12,14 0 0323 +Ó " +^O 12,14 0 0324 +Ô " +~O 12,14 0 0325 +Õ " +:O 12,14 0 0326 +Ö " +mu 9,8 0 0327 +× " +/O 12,11 0 0330 +Ø " +`U 11,14 0 0331 +Ù " +'U 11,14 0 0332 +Ú " +^U 11,14 0 0333 +Û " +:U 11,14 0 0334 +Ü " +'Y 10,14 0 0335 +Ý " +TP 10,11 0 0336 +Þ " +ss 8,11 0 0337 +ß " +`a 8,11 0 0340 +à " +'a 8,11 0 0341 +á " +^a 8,11 0 0342 +â " +~a 8,11 0 0343 +ã " +:a 8,11 0 0344 +ä " +oa 8,11 0 0345 +å " +ae 13,8 0 0346 +æ " +,c 9,8,3 0 0347 +ç " +`e 8,11 0 0350 +è " +'e 8,11 0 0351 +é " +^e 8,11 0 0352 +ê " +:e 8,11 0 0353 +ë " +`i 4,11 0 0354 +ì " +'i 4,11 0 0355 +í " +^i 4,11 0 0356 +î " +:i 4,11 0 0357 +ï " +Sd 9,11 0 0360 +ð " +~n 9,11 0 0361 +ñ " +`o 9,11 0 0362 +ò " +'o 9,11 0 0363 +ó " +^o 9,11 0 0364 +ô " +~o 9,11 0 0365 +õ " +:o 9,11 0 0366 +ö " +di 9,8 0 0367 +÷ " +/o 9,8 0 0370 +ø " +`u 9,11 0 0371 +ù " +'u 9,11 0 0372 +ú " +^u 9,11 0 0373 +û " +:u 9,11 0 0374 +ü " +'y 8,11,3 0 0375 +ý " +Tp 9,11,3 0 0376 +þ " +:y 8,11,3 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/devhtml/HBI b/gnu/usr.bin/groff/devhtml/HBI new file mode 100644 index 00000000000..bb2031a06c9 --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/HBI @@ -0,0 +1,306 @@ +name HBI +spacewidth 4 +charset +--- 4,1 0 040 +! 5,11 0 041 +" 7,11 0 042 +# 10,10 0 043 +sh " +$ 8,12,1 0 044 +Do " +% 13,11 0 045 +& 11,10 0 046 +' 5,11 0 047 +( 5,11,3 0 050 +) 6,11,3 0 051 +* 6,11 0 052 ++ 9,8 0 053 +, 4,2,2 0 054 +\- 9,5 0 055 +. 4,2 0 056 +/ 4,11 0 057 +sl " +0 8,11 0 060 +1 8,11 0 061 +2 8,11 0 062 +3 8,11 0 063 +4 8,11 0 064 +5 8,11 0 065 +6 8,11 0 066 +7 8,11 0 067 +8 8,11 0 070 +9 8,11 0 071 +: 5,8 0 072 +; 5,8,2 0 073 +< 8,7 0 074 += 9,6 0 075 +eq " +> 9,7 0 076 +? 9,11 0 077 +@ 14,11,2 0 0100 +at " +A 9,11 0 0101 +B 10,11 0 0102 +C 11,11 0 0103 +D 11,11 0 0104 +E 9,11 0 0105 +F 8,11 0 0106 +G 11,11 0 0107 +H 10,11 0 0110 +I 4,11 0 0111 +J 8,11 0 0112 +K 10,11 0 0113 +L 8,11 0 0114 +M 13,11 0 0115 +N 11,11 0 0116 +O 12,11 0 0117 +P 10,11 0 0120 +Q 12,11 0 0121 +R 10,11 0 0122 +S 10,11 0 0123 +T 8,11 0 0124 +U 11,11 0 0125 +V 10,11 0 0126 +W 14,11 0 0127 +X 9,11 0 0130 +Y 10,11 0 0131 +Z 9,11 0 0132 +[ 5,11,3 0 0133 +lB " +\ 6,11 0 0134 +rs " +] 5,11,3 0 0135 +rB " +^ 8,11 0 0136 +a^ " +ha " +_ 8,0,3 0 0137 +` 5,11 0 0140 +oq " +a 8,8 0 0141 +b 9,11 0 0142 +c 8,8 0 0143 +d 9,11 0 0144 +e 8,8 0 0145 +f 5,11 0 0146 +g 9,8,3 0 0147 +h 9,11 0 0150 +i 4,11 0 0151 +j 4,11,3 0 0152 +k 8,11 0 0153 +l 4,11 0 0154 +m 12,8 0 0155 +n 9,8 0 0156 +o 8,8 0 0157 +p 9,8,3 0 0160 +q 9,8,3 0 0161 +r 6,8 0 0162 +s 8,8 0 0163 +t 5,10 0 0164 +u 9,8 0 0165 +v 8,8 0 0166 +w 11,8 0 0167 +x 7,8 0 0170 +y 7,8,3 0 0171 +z 6,8 0 0172 +{ 6,11,3 0 0173 +lC " +| 4,11,3 0 0174 +or " +ba " +} 6,11,3 0 0175 +rC " +~ 9,6 0 0176 +a~ " +ap " +ti " +r! 5,8,3 0 0241 +¡ " +ct 8,9,1 0 0242 +¢ " +Po 9,11 0 0243 +£ " +Cs 9,8 0 0244 +¤ " +Ye 9,11 0 0245 +¥ " +bb 4,11,3 0 0246 +¦ " +sc 9,11,3 0 0247 +§ " +ad 5,11 0 0250 +¨ " +co 12,11 0 0251 +© " +Of 6,11 0 0252 +ª " +Fo 11,7 0 0253 +« " +no 9,6 0 0254 +¬ " +- 5,5 0 055 +hy " + " +rg 12,11 0 0256 +® " +a- 5,11 0 0257 +¯ " +de 6,11 0 0260 +° " ++- 9,9 0 0261 +± " +S2 5,11 0 0262 +² " +S3 5,11 0 0263 +³ " +aa 5,11 0 0264 +´ " +µ 9,8,3 0 0265 +ps 8,11,3 0 0266 +¶ " +md 4,5 0 0267 +· " +ac 5,1,3 0 0270 +¸ " +S1 5,11 0 0271 +¹ " +Om 6,11 0 0272 +º " +Fc 11,7 0 0273 +» " +14 12,11 0 0274 +¼ " +12 12,11 0 0275 +½ " +34 13,11 0 0276 +¾ " +r? 8,8,3 0 0277 +¿ " +`A 9,14 0 0300 +À " +'A 9,14 0 0301 +Á " +^A 9,14 0 0302 +Â " +~A 9,14 0 0303 +Ã " +:A 9,14 0 0304 +Ä " +oA 9,14 0 0305 +Å " +AE 14,11 0 0306 +Æ " +,C 11,11,3 0 0307 +Ç " +`E 9,14 0 0310 +È " +'E 9,14 0 0311 +É " +^E 9,14 0 0312 +Ê " +:E 9,14 0 0313 +Ë " +`I 4,14 0 0314 +Ì " +'I 4,14 0 0315 +Í " +^I 4,14 0 0316 +Î " +:I 4,14 0 0317 +Ï " +-D 11,11 0 0320 +Ð " +~N 11,14 0 0321 +Ñ " +`O 12,14 0 0322 +Ò " +'O 12,14 0 0323 +Ó " +^O 12,14 0 0324 +Ô " +~O 12,14 0 0325 +Õ " +:O 12,14 0 0326 +Ö " +mu 9,8 0 0327 +× " +/O 12,11 0 0330 +Ø " +`U 11,14 0 0331 +Ù " +'U 11,14 0 0332 +Ú " +^U 11,14 0 0333 +Û " +:U 11,14 0 0334 +Ü " +'Y 10,14 0 0335 +Ý " +TP 10,11 0 0336 +Þ " +ss 9,11 0 0337 +ß " +`a 8,11 0 0340 +à " +'a 8,11 0 0341 +á " +^a 8,11 0 0342 +â " +~a 8,11 0 0343 +ã " +:a 8,11 0 0344 +ä " +oa 8,11 0 0345 +å " +ae 13,8 0 0346 +æ " +,c 8,8,3 0 0347 +ç " +`e 8,11 0 0350 +è " +'e 8,11 0 0351 +é " +^e 8,11 0 0352 +ê " +:e 8,11 0 0353 +ë " +`i 4,11 0 0354 +ì " +'i 4,11 0 0355 +í " +^i 4,11 0 0356 +î " +:i 4,11 0 0357 +ï " +Sd 8,11 0 0360 +ð " +~n 9,11 0 0361 +ñ " +`o 8,11 0 0362 +ò " +'o 8,11 0 0363 +ó " +^o 8,11 0 0364 +ô " +~o 8,11 0 0365 +õ " +:o 8,11 0 0366 +ö " +di 9,8 0 0367 +÷ " +/o 8,8 0 0370 +ø " +`u 9,11 0 0371 +ù " +'u 9,11 0 0372 +ú " +^u 9,11 0 0373 +û " +:u 9,11 0 0374 +ü " +'y 7,11,3 0 0375 +ý " +Tp 9,11,3 0 0376 +þ " +:y 7,11,3 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/devhtml/HI b/gnu/usr.bin/groff/devhtml/HI new file mode 100644 index 00000000000..1c66db735f3 --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/HI @@ -0,0 +1,306 @@ +name HI +spacewidth 4 +charset +--- 4,1 0 040 +! 4,11 0 041 +" 5,11 0 042 +# 9,10 0 043 +sh " +$ 8,12,2 0 044 +Do " +% 12,11 0 045 +& 10,10 0 046 +' 3,11 0 047 +( 5,11,3 0 050 +) 5,11,3 0 051 +* 8,11 0 052 ++ 9,8 0 053 +, 3,2,2 0 054 +\- 9,5 0 055 +. 3,2 0 056 +/ 4,11 0 057 +sl " +0 8,11 0 060 +1 8,11 0 061 +2 8,11 0 062 +3 8,11 0 063 +4 8,11 0 064 +5 8,11 0 065 +6 8,11 0 066 +7 8,11 0 067 +8 8,11 0 070 +9 8,11 0 071 +: 4,8 0 072 +; 4,8,2 0 073 +< 9,7 0 074 += 9,6 0 075 +eq " +> 9,7 0 076 +? 8,11 0 077 +@ 13,11,1 0 0100 +at " +A 11,11 0 0101 +B 10,11 0 0102 +C 10,11 0 0103 +D 10,11 0 0104 +E 9,11 0 0105 +F 9,11 0 0106 +G 11,11 0 0107 +H 11,11 0 0110 +I 5,11 0 0111 +J 9,11 0 0112 +K 10,11 0 0113 +L 8,11 0 0114 +M 14,11 0 0115 +N 11,11 0 0116 +O 11,11 0 0117 +P 9,11 0 0120 +Q 11,11 0 0121 +R 10,11 0 0122 +S 9,11 0 0123 +T 8,11 0 0124 +U 11,11 0 0125 +V 11,11 0 0126 +W 14,11 0 0127 +X 10,11 0 0130 +Y 9,11 0 0131 +Z 9,11 0 0132 +[ 5,11,3 0 0133 +lB " +\ 6,11 0 0134 +rs " +] 5,11,3 0 0135 +rB " +^ 7,11 0 0136 +a^ " +ha " +_ 8,0,3 0 0137 +` 3,11 0 0140 +oq " +a 8,8 0 0141 +b 8,11 0 0142 +c 7,8 0 0143 +d 8,11 0 0144 +e 8,8 0 0145 +f 4,11 0 0146 +g 8,8,3 0 0147 +h 8,11 0 0150 +i 4,11 0 0151 +j 3,11,3 0 0152 +k 7,11 0 0153 +l 3,11 0 0154 +m 11,8 0 0155 +n 8,8 0 0156 +o 8,8 0 0157 +p 8,8,3 0 0160 +q 8,8,3 0 0161 +r 5,8 0 0162 +s 7,8 0 0163 +t 4,10 0 0164 +u 8,8 0 0165 +v 7,8 0 0166 +w 10,8 0 0167 +x 7,8 0 0170 +y 7,8,3 0 0171 +z 7,8 0 0172 +{ 5,11,3 0 0173 +lC " +| 4,11,3 0 0174 +or " +ba " +} 5,11,3 0 0175 +rC " +~ 8,6 0 0176 +a~ " +ap " +ti " +r! 4,8,3 0 0241 +¡ " +ct 8,9,1 0 0242 +¢ " +Po 9,11 0 0243 +£ " +Cs 8,8 0 0244 +¤ " +Ye 9,11 0 0245 +¥ " +bb 4,11,3 0 0246 +¦ " +sc 8,11,3 0 0247 +§ " +ad 5,10 0 0250 +¨ " +co 12,11 0 0251 +© " +Of 5,11 0 0252 +ª " +Fo 8,6 0 0253 +« " +no 9,6 0 0254 +¬ " +- 5,5 0 055 +hy " + " +rg 12,11 0 0256 +® " +a- 4,10 0 0257 +¯ " +de 6,11 0 0260 +° " ++- 9,9 0 0261 +± " +S2 5,11 0 0262 +² " +S3 5,11 0 0263 +³ " +aa 4,11 0 0264 +´ " +µ 8,8,3 0 0265 +ps 8,11,3 0 0266 +¶ " +md 4,5 0 0267 +· " +ac 3,0,3 0 0270 +¸ " +S1 5,11 0 0271 +¹ " +Om 5,11 0 0272 +º " +Fc 8,6 0 0273 +» " +14 12,11 0 0274 +¼ " +12 12,11 0 0275 +½ " +34 12,11 0 0276 +¾ " +r? 8,8,3 0 0277 +¿ " +`A 11,14 0 0300 +À " +'A 11,14 0 0301 +Á " +^A 11,14 0 0302 +Â " +~A 11,14 0 0303 +Ã " +:A 11,13 0 0304 +Ä " +oA 11,14 0 0305 +Å " +AE 15,11 0 0306 +Æ " +,C 10,11,3 0 0307 +Ç " +`E 9,14 0 0310 +È " +'E 9,14 0 0311 +É " +^E 9,14 0 0312 +Ê " +:E 9,13 0 0313 +Ë " +`I 5,14 0 0314 +Ì " +'I 5,14 0 0315 +Í " +^I 5,14 0 0316 +Î " +:I 5,13 0 0317 +Ï " +-D 10,11 0 0320 +Ð " +~N 11,14 0 0321 +Ñ " +`O 11,14 0 0322 +Ò " +'O 11,14 0 0323 +Ó " +^O 11,14 0 0324 +Ô " +~O 11,14 0 0325 +Õ " +:O 11,13 0 0326 +Ö " +mu 9,8 0 0327 +× " +/O 11,11 0 0330 +Ø " +`U 11,14 0 0331 +Ù " +'U 11,14 0 0332 +Ú " +^U 11,14 0 0333 +Û " +:U 11,13 0 0334 +Ü " +'Y 9,14 0 0335 +Ý " +TP 9,11 0 0336 +Þ " +ss 8,11 0 0337 +ß " +`a 8,11 0 0340 +à " +'a 8,11 0 0341 +á " +^a 8,11 0 0342 +â " +~a 8,11 0 0343 +ã " +:a 8,11 0 0344 +ä " +oa 8,11 0 0345 +å " +ae 12,8 0 0346 +æ " +,c 7,8,3 0 0347 +ç " +`e 8,11 0 0350 +è " +'e 8,11 0 0351 +é " +^e 8,11 0 0352 +ê " +:e 8,11 0 0353 +ë " +`i 3,11 0 0354 +ì " +'i 3,11 0 0355 +í " +^i 3,11 0 0356 +î " +:i 3,11 0 0357 +ï " +Sd 8,11 0 0360 +ð " +~n 8,11 0 0361 +ñ " +`o 8,11 0 0362 +ò " +'o 8,11 0 0363 +ó " +^o 8,11 0 0364 +ô " +~o 8,11 0 0365 +õ " +:o 8,11 0 0366 +ö " +di 9,8 0 0367 +÷ " +/o 8,9,1 0 0370 +ø " +`u 8,11 0 0371 +ù " +'u 8,11 0 0372 +ú " +^u 8,11 0 0373 +û " +:u 8,11 0 0374 +ü " +'y 7,11,3 0 0375 +ý " +Tp 8,11,3 0 0376 +þ " +:y 7,11,3 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/devhtml/HR b/gnu/usr.bin/groff/devhtml/HR new file mode 100644 index 00000000000..756ef71120c --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/HR @@ -0,0 +1,306 @@ +name HR +spacewidth 4 +charset +--- 4,1 0 040 +! 4,11 0 041 +" 5,11 0 042 +# 8,10 0 043 +sh " +$ 8,12,2 0 044 +Do " +% 12,11 0 045 +& 10,10 0 046 +' 3,11 0 047 +( 5,11,3 0 050 +) 5,11,3 0 051 +* 7,11 0 052 ++ 9,8 0 053 +, 3,2,2 0 054 +\- 9,5 0 055 +. 3,2 0 056 +/ 4,11 0 057 +sl " +0 8,11 0 060 +1 8,11 0 061 +2 8,11 0 062 +3 8,11 0 063 +4 8,11 0 064 +5 8,11 0 065 +6 8,11 0 066 +7 8,11 0 067 +8 8,11 0 070 +9 8,11 0 071 +: 3,8 0 072 +; 4,8,2 0 073 +< 8,7 0 074 += 9,6 0 075 +eq " +> 8,7 0 076 +? 8,11 0 077 +@ 13,11,1 0 0100 +at " +A 9,11 0 0101 +B 9,11 0 0102 +C 10,11 0 0103 +D 10,11 0 0104 +E 9,11 0 0105 +F 8,11 0 0106 +G 11,11 0 0107 +H 10,11 0 0110 +I 4,11 0 0111 +J 7,11 0 0112 +K 9,11 0 0113 +L 8,11 0 0114 +M 12,11 0 0115 +N 10,11 0 0116 +O 11,11 0 0117 +P 9,11 0 0120 +Q 11,11 0 0121 +R 10,11 0 0122 +S 9,11 0 0123 +T 9,11 0 0124 +U 10,11 0 0125 +V 9,11 0 0126 +W 13,11 0 0127 +X 9,11 0 0130 +Y 9,11 0 0131 +Z 9,11 0 0132 +[ 4,11,3 0 0133 +lB " +\ 4,11 0 0134 +rs " +] 4,11,3 0 0135 +rB " +^ 7,11 0 0136 +a^ " +ha " +_ 8,0,3 0 0137 +` 3,11 0 0140 +oq " +a 8,8 0 0141 +b 7,11 0 0142 +c 7,8 0 0143 +d 8,11 0 0144 +e 8,8 0 0145 +f 4,11 0 0146 +g 8,8,3 0 0147 +h 8,11 0 0150 +i 3,11 0 0151 +j 3,11,3 0 0152 +k 7,11 0 0153 +l 3,11 0 0154 +m 11,8 0 0155 +n 8,8 0 0156 +o 8,8 0 0157 +p 8,8,3 0 0160 +q 8,8,3 0 0161 +r 5,8 0 0162 +s 7,8 0 0163 +t 4,10 0 0164 +u 7,8 0 0165 +v 7,8 0 0166 +w 10,8 0 0167 +x 7,8 0 0170 +y 7,8,3 0 0171 +z 7,8 0 0172 +{ 5,11,3 0 0173 +lC " +| 3,11,3 0 0174 +or " +ba " +} 5,11,3 0 0175 +rC " +~ 8,6 0 0176 +a~ " +ap " +ti " +r! 4,8,3 0 0241 +¡ " +ct 8,9,1 0 0242 +¢ " +Po 8,11 0 0243 +£ " +Cs 8,8 0 0244 +¤ " +Ye 7,11 0 0245 +¥ " +bb 3,11,3 0 0246 +¦ " +sc 8,11,3 0 0247 +§ " +ad 5,10 0 0250 +¨ " +co 12,11 0 0251 +© " +Of 6,11 0 0252 +ª " +Fo 8,7 0 0253 +« " +no 9,6 0 0254 +¬ " +- 4,5 0 055 +hy " + " +rg 12,11 0 0256 +® " +a- 4,10 0 0257 +¯ " +de 6,11 0 0260 +° " ++- 9,9 0 0261 +± " +S2 5,11 0 0262 +² " +S3 5,11 0 0263 +³ " +aa 5,11 0 0264 +´ " +µ 8,8,3 0 0265 +ps 8,11,3 0 0266 +¶ " +md 4,5 0 0267 +· " +ac 5,0,3 0 0270 +¸ " +S1 5,11 0 0271 +¹ " +Om 6,11 0 0272 +º " +Fc 8,7 0 0273 +» " +14 12,11 0 0274 +¼ " +12 12,11 0 0275 +½ " +34 12,11 0 0276 +¾ " +r? 8,8,3 0 0277 +¿ " +`A 9,14 0 0300 +À " +'A 9,14 0 0301 +Á " +^A 9,14 0 0302 +Â " +~A 9,13 0 0303 +Ã " +:A 9,14 0 0304 +Ä " +oA 9,14 0 0305 +Å " +AE 14,11 0 0306 +Æ " +,C 10,11,3 0 0307 +Ç " +`E 9,14 0 0310 +È " +'E 9,14 0 0311 +É " +^E 9,14 0 0312 +Ê " +:E 9,13 0 0313 +Ë " +`I 4,14 0 0314 +Ì " +'I 4,14 0 0315 +Í " +^I 4,14 0 0316 +Î " +:I 4,13 0 0317 +Ï " +-D 10,11 0 0320 +Ð " +~N 10,14 0 0321 +Ñ " +`O 11,14 0 0322 +Ò " +'O 11,14 0 0323 +Ó " +^O 11,14 0 0324 +Ô " +~O 11,14 0 0325 +Õ " +:O 11,13 0 0326 +Ö " +mu 9,8 0 0327 +× " +/O 11,11 0 0330 +Ø " +`U 10,14 0 0331 +Ù " +'U 10,14 0 0332 +Ú " +^U 10,14 0 0333 +Û " +:U 10,13 0 0334 +Ü " +'Y 9,14 0 0335 +Ý " +TP 9,11 0 0336 +Þ " +ss 7,11 0 0337 +ß " +`a 8,11 0 0340 +à " +'a 8,11 0 0341 +á " +^a 8,11 0 0342 +â " +~a 8,11 0 0343 +ã " +:a 8,11 0 0344 +ä " +oa 8,12 0 0345 +å " +ae 13,8 0 0346 +æ " +,c 8,8,3 0 0347 +ç " +`e 8,11 0 0350 +è " +'e 8,11 0 0351 +é " +^e 8,11 0 0352 +ê " +:e 8,11 0 0353 +ë " +`i 3,11 0 0354 +ì " +'i 3,11 0 0355 +í " +^i 3,11 0 0356 +î " +:i 3,11 0 0357 +ï " +Sd 8,11 0 0360 +ð " +~n 8,11 0 0361 +ñ " +`o 8,11 0 0362 +ò " +'o 8,11 0 0363 +ó " +^o 8,11 0 0364 +ô " +~o 8,11 0 0365 +õ " +:o 8,11 0 0366 +ö " +di 9,8 0 0367 +÷ " +/o 8,8 0 0370 +ø " +`u 8,11 0 0371 +ù " +'u 8,11 0 0372 +ú " +^u 8,11 0 0373 +û " +:u 8,11 0 0374 +ü " +'y 7,11,3 0 0375 +ý " +Tp 8,11,3 0 0376 +þ " +:y 7,10,3 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/devhtml/Makefile.sub b/gnu/usr.bin/groff/devhtml/Makefile.sub new file mode 100644 index 00000000000..57c9f44de77 --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/Makefile.sub @@ -0,0 +1,2 @@ +DEV=html +DEVFILES=DESC TR TI TB TBI CR CI CB CBI HR HI HB HBI NR NI NB NBI S diff --git a/gnu/usr.bin/groff/devhtml/NB b/gnu/usr.bin/groff/devhtml/NB new file mode 100644 index 00000000000..88ef29f0e59 --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/NB @@ -0,0 +1,306 @@ +name NB +spacewidth 11 +charset +--- 11,1 0 040 +! 4,11 0 041 +" 5,11 0 042 +# 8,10 0 043 +sh " +$ 8,12,1 0 044 +Do " +% 13,11 0 045 +& 13,11 0 046 +' 4,11 0 047 +( 5,11,2 0 050 +) 5,11,2 0 051 +* 6,11 0 052 ++ 8,8 0 053 +, 4,3,2 0 054 +\- 8,5 0 055 +. 4,3 0 056 +/ 5,11 0 057 +sl " +0 8,11 0 060 +1 6,11 0 061 +2 8,11 0 062 +3 8,11 0 063 +4 8,11 0 064 +5 8,11 0 065 +6 8,11 0 066 +7 8,11 0 067 +8 8,11 0 070 +9 8,11 0 071 +: 4,7 0 072 +; 4,7,2 0 073 +< 8,8 0 074 += 8,6 0 075 +eq " +> 8,8 0 076 +? 7,11 0 077 +@ 14,11 0 0100 +at " +A 11,11 0 0101 +B 10,11 0 0102 +C 11,11 0 0103 +D 12,11 0 0104 +E 10,11 0 0105 +F 10,11 0 0106 +G 12,11 0 0107 +H 12,11 0 0110 +I 7,11 0 0111 +J 9,11 0 0112 +K 12,11 0 0113 +L 10,11 0 0114 +M 14,11 0 0115 +N 12,11 0 0116 +O 12,11 0 0117 +P 10,11 0 0120 +Q 12,11,3 0 0121 +R 12,11 0 0122 +S 10,11 0 0123 +T 11,11 0 0124 +U 12,11 0 0125 +V 11,11 0 0126 +W 14,11 0 0127 +X 12,11 0 0130 +Y 11,11 0 0131 +Z 9,11 0 0132 +[ 5,11,2 0 0133 +lB " +\ 7,11 0 0134 +rs " +] 5,11,2 0 0135 +rB " +^ 8,11 0 0136 +a^ " +ha " +_ 7,0,2 0 0137 +` 4,11 0 0140 +oq " +a 9,7 0 0141 +b 10,11 0 0142 +c 8,7 0 0143 +d 10,11 0 0144 +e 9,7 0 0145 +f 6,11 0 0146 +g 8,8,3 0 0147 +h 10,11 0 0150 +i 5,10 0 0151 +j 5,10,3 0 0152 +k 9,11 0 0153 +l 5,11 0 0154 +m 15,7 0 0155 +n 10,7 0 0156 +o 9,7 0 0157 +p 10,7,3 0 0160 +q 9,7,3 0 0161 +r 7,7 0 0162 +s 7,7 0 0163 +t 6,10 0 0164 +u 10,7 0 0165 +v 7,7 0 0166 +w 12,7 0 0167 +x 9,7 0 0170 +y 7,7,3 0 0171 +z 7,7 0 0172 +{ 6,11,2 0 0173 +lC " +| 8,11 0 0174 +or " +ba " +} 6,11,2 0 0175 +rC " +~ 8,6 0 0176 +a~ " +ap " +ti " +r! 5,8,3 0 0241 +¡ " +ct 8,8,1 0 0242 +¢ " +Po 9,11 0 0243 +£ " +Cs 9,10 0 0244 +¤ " +Ye 11,11 0 0245 +¥ " +bb 8,11 0 0246 +¦ " +sc 7,11,2 0 0247 +§ " +ad 7,10 0 0250 +¨ " +co 12,11 0 0251 +© " +Of 6,11 0 0252 +ª " +Fo 8,6 0 0253 +« " +no 8,6 0 0254 +¬ " +- 5,5 0 055 +hy " + " +rg 12,11 0 0256 +® " +a- 7,9 0 0257 +¯ " +de 6,11 0 0260 +° " ++- 8,8 0 0261 +± " +S2 5,11 0 0262 +² " +S3 5,11 0 0263 +³ " +aa 6,11 0 0264 +´ " +µ 10,7,3 0 0265 +ps 10,11 0 0266 +¶ " +md 5,6 0 0267 +· " +ac 5,0,3 0 0270 +¸ " +S1 5,11 0 0271 +¹ " +Om 6,11 0 0272 +º " +Fc 8,6 0 0273 +» " +14 12,11 0 0274 +¼ " +12 12,11 0 0275 +½ " +34 12,11 0 0276 +¾ " +r? 7,8,3 0 0277 +¿ " +`A 11,15 0 0300 +À " +'A 11,15 0 0301 +Á " +^A 11,15 0 0302 +Â " +~A 11,14 0 0303 +Ã " +:A 11,14 0 0304 +Ä " +oA 11,15 0 0305 +Å " +AE 15,11 0 0306 +Æ " +,C 11,11,3 0 0307 +Ç " +`E 10,15 0 0310 +È " +'E 10,15 0 0311 +É " +^E 10,15 0 0312 +Ê " +:E 10,14 0 0313 +Ë " +`I 7,15 0 0314 +Ì " +'I 7,15 0 0315 +Í " +^I 7,15 0 0316 +Î " +:I 7,14 0 0317 +Ï " +-D 12,11 0 0320 +Ð " +~N 12,14 0 0321 +Ñ " +`O 12,15 0 0322 +Ò " +'O 12,15 0 0323 +Ó " +^O 12,15 0 0324 +Ô " +~O 12,14 0 0325 +Õ " +:O 12,14 0 0326 +Ö " +mu 8,8 0 0327 +× " +/O 12,11 0 0330 +Ø " +`U 12,15 0 0331 +Ù " +'U 12,15 0 0332 +Ú " +^U 12,15 0 0333 +Û " +:U 12,14 0 0334 +Ü " +'Y 11,14 0 0335 +Ý " +TP 10,11 0 0336 +Þ " +ss 9,11 0 0337 +ß " +`a 9,11 0 0340 +à " +'a 9,11 0 0341 +á " +^a 9,11 0 0342 +â " +~a 9,10 0 0343 +ã " +:a 9,10 0 0344 +ä " +oa 9,11 0 0345 +å " +ae 14,7 0 0346 +æ " +,c 8,7,3 0 0347 +ç " +`e 9,11 0 0350 +è " +'e 9,11 0 0351 +é " +^e 9,11 0 0352 +ê " +:e 9,10 0 0353 +ë " +`i 5,11 0 0354 +ì " +'i 5,11 0 0355 +í " +^i 5,11 0 0356 +î " +:i 5,10 0 0357 +ï " +Sd 9,11 0 0360 +ð " +~n 10,10 0 0361 +ñ " +`o 9,11 0 0362 +ò " +'o 9,11 0 0363 +ó " +^o 9,11 0 0364 +ô " +~o 9,10 0 0365 +õ " +:o 9,10 0 0366 +ö " +di 8,8 0 0367 +÷ " +/o 9,8,1 0 0370 +ø " +`u 10,11 0 0371 +ù " +'u 10,11 0 0372 +ú " +^u 10,11 0 0373 +û " +:u 10,10 0 0374 +ü " +'y 7,11,3 0 0375 +ý " +Tp 10,11,3 0 0376 +þ " +:y 7,10,3 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/devhtml/NBI b/gnu/usr.bin/groff/devhtml/NBI new file mode 100644 index 00000000000..58d9522ebde --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/NBI @@ -0,0 +1,306 @@ +name NBI +spacewidth 4 +charset +--- 4,1 0 040 +! 5,11 0 041 +" 6,11 0 042 +# 8,10 0 043 +sh " +$ 8,12,1 0 044 +Do " +% 13,11,1 0 045 +& 13,11 0 046 +' 4,11 0 047 +( 5,11,2 0 050 +) 6,11,2 0 051 +* 7,11 0 052 ++ 8,8 0 053 +, 4,2,3 0 054 +\- 8,5 0 055 +. 4,2 0 056 +/ 5,11 0 057 +sl " +0 8,11 0 060 +1 8,11 0 061 +2 8,11 0 062 +3 8,11 0 063 +4 8,11 0 064 +5 8,11 0 065 +6 8,11 0 066 +7 8,11 0 067 +8 8,11 0 070 +9 8,11 0 071 +: 4,7 0 072 +; 5,7,3 0 073 +< 9,9 0 074 += 9,7 0 075 +eq " +> 9,9 0 076 +? 7,11 0 077 +@ 13,11 0 0100 +at " +A 11,11 0 0101 +B 10,11 0 0102 +C 11,11 0 0103 +D 12,11 0 0104 +E 10,11 0 0105 +F 10,11 0 0106 +G 11,11 0 0107 +H 12,11 0 0110 +I 6,11 0 0111 +J 8,11 0 0112 +K 12,11 0 0113 +L 10,11 0 0114 +M 15,11 0 0115 +N 13,11 0 0116 +O 12,11 0 0117 +P 11,11 0 0120 +Q 12,11,2 0 0121 +R 12,11 0 0122 +S 10,11 0 0123 +T 11,11 0 0124 +U 12,11 0 0125 +V 11,11 0 0126 +W 15,11 0 0127 +X 11,11 0 0130 +Y 9,11 0 0131 +Z 10,11 0 0132 +[ 7,11,2 0 0133 +lB " +\ 9,11 0 0134 +rs " +] 7,11,2 0 0135 +rB " +^ 8,11 0 0136 +a^ " +ha " +_ 9,0,2 0 0137 +` 4,11 0 0140 +oq " +a 10,7 0 0141 +b 8,11 0 0142 +c 8,7 0 0143 +d 10,11 0 0144 +e 8,7 0 0145 +f 5,11,3 0 0146 +g 8,9,3 0 0147 +h 10,11 0 0150 +i 5,10 0 0151 +j 4,10,3 0 0152 +k 9,11 0 0153 +l 5,11 0 0154 +m 15,7 0 0155 +n 10,7 0 0156 +o 8,7 0 0157 +p 8,7,3 0 0160 +q 9,7,3 0 0161 +r 7,7 0 0162 +s 8,7 0 0163 +t 5,9 0 0164 +u 10,7 0 0165 +v 8,7 0 0166 +w 13,7 0 0167 +x 9,7 0 0170 +y 9,7,3 0 0171 +z 9,7 0 0172 +{ 6,11,2 0 0173 +lC " +| 9,11 0 0174 +or " +ba " +} 6,11,2 0 0175 +rC " +~ 11,6 0 0176 +a~ " +ap " +ti " +r! 5,8,3 0 0241 +¡ " +ct 8,8,1 0 0242 +¢ " +Po 10,11 0 0243 +£ " +Cs 8,9 0 0244 +¤ " +Ye 10,11 0 0245 +¥ " +bb 8,11 0 0246 +¦ " +sc 9,11,2 0 0247 +§ " +ad 6,10 0 0250 +¨ " +co 12,11 0 0251 +© " +Of 8,11 0 0252 +ª " +Fo 10,7 0 0253 +« " +no 9,7 0 0254 +¬ " +- 5,5 0 055 +hy " + " +rg 12,11 0 0256 +® " +a- 6,9 0 0257 +¯ " +de 6,11 0 0260 +° " ++- 8,8 0 0261 +± " +S2 5,11 0 0262 +² " +S3 5,11 0 0263 +³ " +aa 5,11 0 0264 +´ " +µ 10,7,3 0 0265 +ps 9,11 0 0266 +¶ " +md 5,6 0 0267 +· " +ac 5,0,3 0 0270 +¸ " +S1 5,11 0 0271 +¹ " +Om 8,11 0 0272 +º " +Fc 10,7 0 0273 +» " +14 12,11 0 0274 +¼ " +12 12,11 0 0275 +½ " +34 12,11 0 0276 +¾ " +r? 7,8,3 0 0277 +¿ " +`A 11,15 0 0300 +À " +'A 11,15 0 0301 +Á " +^A 11,15 0 0302 +Â " +~A 11,14 0 0303 +Ã " +:A 11,14 0 0304 +Ä " +oA 11,15 0 0305 +Å " +AE 14,11 0 0306 +Æ " +,C 11,11,3 0 0307 +Ç " +`E 10,15 0 0310 +È " +'E 10,15 0 0311 +É " +^E 10,15 0 0312 +Ê " +:E 10,14 0 0313 +Ë " +`I 6,15 0 0314 +Ì " +'I 6,15 0 0315 +Í " +^I 6,15 0 0316 +Î " +:I 6,14 0 0317 +Ï " +-D 12,11 0 0320 +Ð " +~N 13,14 0 0321 +Ñ " +`O 12,15 0 0322 +Ò " +'O 12,15 0 0323 +Ó " +^O 12,15 0 0324 +Ô " +~O 12,14 0 0325 +Õ " +:O 12,14 0 0326 +Ö " +mu 8,8 0 0327 +× " +/O 12,11 0 0330 +Ø " +`U 12,15 0 0331 +Ù " +'U 12,15 0 0332 +Ú " +^U 12,15 0 0333 +Û " +:U 12,14 0 0334 +Ü " +'Y 9,15 0 0335 +Ý " +TP 11,11 0 0336 +Þ " +ss 10,11,3 0 0337 +ß " +`a 10,11 0 0340 +à " +'a 10,11 0 0341 +á " +^a 10,11 0 0342 +â " +~a 10,10 0 0343 +ã " +:a 10,10 0 0344 +ä " +oa 10,11 0 0345 +å " +ae 13,7 0 0346 +æ " +,c 8,7,3 0 0347 +ç " +`e 8,11 0 0350 +è " +'e 8,11 0 0351 +é " +^e 8,11 0 0352 +ê " +:e 8,10 0 0353 +ë " +`i 5,11 0 0354 +ì " +'i 5,11 0 0355 +í " +^i 5,11 0 0356 +î " +:i 5,10 0 0357 +ï " +Sd 8,11 0 0360 +ð " +~n 10,10 0 0361 +ñ " +`o 8,11 0 0362 +ò " +'o 8,11 0 0363 +ó " +^o 8,11 0 0364 +ô " +~o 8,10 0 0365 +õ " +:o 8,10 0 0366 +ö " +di 8,8 0 0367 +÷ " +/o 8,7 0 0370 +ø " +`u 10,11 0 0371 +ù " +'u 10,11 0 0372 +ú " +^u 10,11 0 0373 +û " +:u 10,10 0 0374 +ü " +'y 9,11,3 0 0375 +ý " +Tp 8,11,3 0 0376 +þ " +:y 9,10,3 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/devhtml/NI b/gnu/usr.bin/groff/devhtml/NI new file mode 100644 index 00000000000..b76ed021789 --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/NI @@ -0,0 +1,306 @@ +name NI +spacewidth 4 +charset +--- 4,1 0 040 +! 5,11 0 041 +" 6,11 0 042 +# 11,10 0 043 +sh " +$ 8,12,1 0 044 +Do " +% 12,11,1 0 045 +& 11,11 0 046 +' 4,11 0 047 +( 5,11,2 0 050 +) 5,11,2 0 051 +* 6,11 0 052 ++ 8,8 0 053 +, 4,2,2 0 054 +\- 9,5 0 055 +. 4,2 0 056 +/ 9,11,3 0 057 +sl " +0 8,11 0 060 +1 8,11 0 061 +2 8,11 0 062 +3 8,11 0 063 +4 8,11 0 064 +5 8,11 0 065 +6 8,11 0 066 +7 8,11 0 067 +8 8,11 0 070 +9 8,11 0 071 +: 4,7 0 072 +; 4,7,2 0 073 +< 9,8 0 074 += 8,6 0 075 +eq " +> 9,8 0 076 +? 6,11 0 077 +@ 12,11 0 0100 +at " +A 11,11 0 0101 +B 9,11 0 0102 +C 10,11 0 0103 +D 11,11 0 0104 +E 9,11 0 0105 +F 8,11 0 0106 +G 10,11 0 0107 +H 11,11 0 0110 +I 7,11 0 0111 +J 8,11 0 0112 +K 10,11 0 0113 +L 9,11 0 0114 +M 14,11 0 0115 +N 12,11 0 0116 +O 10,11 0 0117 +P 10,11 0 0120 +Q 10,11,2 0 0121 +R 11,11 0 0122 +S 10,11 0 0123 +T 10,11 0 0124 +U 12,11 0 0125 +V 10,11 0 0126 +W 13,11 0 0127 +X 10,11 0 0130 +Y 9,11 0 0131 +Z 10,11 0 0132 +[ 6,11,2 0 0133 +lB " +\ 8,11 0 0134 +rs " +] 6,11,2 0 0135 +rB " +^ 6,11 0 0136 +a^ " +ha " +_ 7,0,2 0 0137 +` 4,11 0 0140 +oq " +a 9,7 0 0141 +b 7,11 0 0142 +c 6,7 0 0143 +d 9,11 0 0144 +e 6,7 0 0145 +f 5,11,3 0 0146 +g 7,8,3 0 0147 +h 9,11 0 0150 +i 4,11 0 0151 +j 4,11,3 0 0152 +k 8,11 0 0153 +l 4,11 0 0154 +m 14,7 0 0155 +n 9,7 0 0156 +o 7,7 0 0157 +p 7,7,3 0 0160 +q 8,7,3 0 0161 +r 7,7 0 0162 +s 7,7 0 0163 +t 5,9 0 0164 +u 9,7 0 0165 +v 7,7 0 0166 +w 11,7 0 0167 +x 8,7 0 0170 +y 7,7,3 0 0171 +z 8,7 0 0172 +{ 6,11,2 0 0173 +lC " +| 9,11 0 0174 +or " +ba " +} 6,11,2 0 0175 +rC " +~ 9,6 0 0176 +a~ " +ap " +ti " +r! 4,8,3 0 0241 +¡ " +ct 8,9,2 0 0242 +¢ " +Po 9,11 0 0243 +£ " +Cs 8,9 0 0244 +¤ " +Ye 9,11 0 0245 +¥ " +bb 8,11 0 0246 +¦ " +sc 7,11,2 0 0247 +§ " +ad 7,10 0 0250 +¨ " +co 13,11 0 0251 +© " +Of 6,11 0 0252 +ª " +Fo 8,7 0 0253 +« " +no 8,6 0 0254 +¬ " +- 5,5 0 055 +hy " + " +rg 13,11 0 0256 +® " +a- 6,9 0 0257 +¯ " +de 6,11 0 0260 +° " ++- 8,8 0 0261 +± " +S2 5,11 0 0262 +² " +S3 5,11 0 0263 +³ " +aa 4,11 0 0264 +´ " +µ 9,7,3 0 0265 +ps 9,11 0 0266 +¶ " +md 5,6 0 0267 +· " +ac 5,0,3 0 0270 +¸ " +S1 5,11 0 0271 +¹ " +Om 6,11 0 0272 +º " +Fc 8,7 0 0273 +» " +14 12,11 0 0274 +¼ " +12 12,11 0 0275 +½ " +34 12,11 0 0276 +¾ " +r? 6,8,3 0 0277 +¿ " +`A 11,14 0 0300 +À " +'A 11,14 0 0301 +Á " +^A 11,14 0 0302 +Â " +~A 11,14 0 0303 +Ã " +:A 11,14 0 0304 +Ä " +oA 11,14 0 0305 +Å " +AE 14,11 0 0306 +Æ " +,C 10,11,3 0 0307 +Ç " +`E 9,14 0 0310 +È " +'E 9,14 0 0311 +É " +^E 9,14 0 0312 +Ê " +:E 9,14 0 0313 +Ë " +`I 7,14 0 0314 +Ì " +'I 7,14 0 0315 +Í " +^I 7,14 0 0316 +Î " +:I 7,14 0 0317 +Ï " +-D 11,11 0 0320 +Ð " +~N 12,14 0 0321 +Ñ " +`O 10,14 0 0322 +Ò " +'O 10,14 0 0323 +Ó " +^O 10,14 0 0324 +Ô " +~O 10,14 0 0325 +Õ " +:O 10,14 0 0326 +Ö " +mu 8,8 0 0327 +× " +/O 10,11 0 0330 +Ø " +`U 12,14 0 0331 +Ù " +'U 12,14 0 0332 +Ú " +^U 12,14 0 0333 +Û " +:U 12,14 0 0334 +Ü " +'Y 9,14 0 0335 +Ý " +TP 10,11 0 0336 +Þ " +ss 8,11,3 0 0337 +ß " +`a 9,11 0 0340 +à " +'a 9,11 0 0341 +á " +^a 9,11 0 0342 +â " +~a 9,10 0 0343 +ã " +:a 9,10 0 0344 +ä " +oa 9,11 0 0345 +å " +ae 10,7 0 0346 +æ " +,c 6,7,3 0 0347 +ç " +`e 6,11 0 0350 +è " +'e 6,11 0 0351 +é " +^e 6,11 0 0352 +ê " +:e 6,10 0 0353 +ë " +`i 4,11 0 0354 +ì " +'i 4,11 0 0355 +í " +^i 4,11 0 0356 +î " +:i 4,10 0 0357 +ï " +Sd 7,11 0 0360 +ð " +~n 9,10 0 0361 +ñ " +`o 7,11 0 0362 +ò " +'o 7,11 0 0363 +ó " +^o 7,11 0 0364 +ô " +~o 7,10 0 0365 +õ " +:o 7,10 0 0366 +ö " +di 8,8 0 0367 +÷ " +/o 7,8,1 0 0370 +ø " +`u 9,11 0 0371 +ù " +'u 9,11 0 0372 +ú " +^u 9,11 0 0373 +û " +:u 9,10 0 0374 +ü " +'y 7,11,3 0 0375 +ý " +Tp 7,11,3 0 0376 +þ " +:y 7,10,3 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/devhtml/NR b/gnu/usr.bin/groff/devhtml/NR new file mode 100644 index 00000000000..dd756b794bf --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/NR @@ -0,0 +1,306 @@ +name NR +spacewidth 4 +charset +--- 4,1 0 040 +! 3,11 0 041 +" 5,11 0 042 +# 8,11 0 043 +sh " +$ 8,12,2 0 044 +Do " +% 12,11 0 045 +& 13,11 0 046 +' 4,11 0 047 +( 5,11,2 0 050 +) 6,11,2 0 051 +* 7,11 0 052 ++ 9,7 0 053 +, 4,2,2 0 054 +\- 9,4 0 055 +. 4,2 0 056 +/ 4,11 0 057 +sl " +0 8,11 0 060 +1 8,11 0 061 +2 8,11 0 062 +3 8,11 0 063 +4 8,11 0 064 +5 8,11 0 065 +6 8,11 0 066 +7 8,11 0 067 +8 8,11 0 070 +9 8,11 0 071 +: 4,7 0 072 +; 4,7,2 0 073 +< 10,7 0 074 += 9,6 0 075 +eq " +> 10,7 0 076 +? 6,11 0 077 +@ 13,11 0 0100 +at " +A 10,11 0 0101 +B 10,11 0 0102 +C 11,11 0 0103 +D 11,11 0 0104 +E 10,11 0 0105 +F 10,11 0 0106 +G 11,11 0 0107 +H 12,11 0 0110 +I 6,11 0 0111 +J 7,11 0 0112 +K 11,11 0 0113 +L 10,11 0 0114 +M 16,11 0 0115 +N 13,11 0 0116 +O 11,11 0 0117 +P 10,11 0 0120 +Q 11,11,2 0 0121 +R 11,11 0 0122 +S 8,11 0 0123 +T 10,11 0 0124 +U 13,11 0 0125 +V 10,11 0 0126 +W 16,11 0 0127 +X 13,11 0 0130 +Y 10,11 0 0131 +Z 9,11 0 0132 +[ 4,11,2 0 0133 +lB " +\ 8,11 0 0134 +rs " +] 4,11,2 0 0135 +rB " +^ 7,11 0 0136 +a^ " +ha " +_ 7,0,2 0 0137 +` 4,11 0 0140 +oq " +a 8,7 0 0141 +b 7,11 0 0142 +c 7,7 0 0143 +d 8,11 0 0144 +e 7,7 0 0145 +f 5,11 0 0146 +g 8,7,3 0 0147 +h 9,11 0 0150 +i 4,10 0 0151 +j 4,10,3 0 0152 +k 9,11 0 0153 +l 4,11 0 0154 +m 14,7 0 0155 +n 9,7 0 0156 +o 7,7 0 0157 +p 8,7,3 0 0160 +q 7,7,3 0 0161 +r 7,7 0 0162 +s 6,7 0 0163 +t 5,9 0 0164 +u 9,7 0 0165 +v 8,7 0 0166 +w 12,7 0 0167 +x 8,7 0 0170 +y 8,7,3 0 0171 +z 7,7 0 0172 +{ 4,11,2 0 0173 +lC " +| 9,11 0 0174 +or " +ba " +} 5,11,2 0 0175 +rC " +~ 9,5 0 0176 +a~ " +ap " +ti " +r! 4,8,3 0 0241 +¡ " +ct 8,9,2 0 0242 +¢ " +Po 8,11 0 0243 +£ " +Cs 8,9 0 0244 +¤ " +Ye 8,11 0 0245 +¥ " +bb 9,11 0 0246 +¦ " +sc 7,11,2 0 0247 +§ " +ad 6,10 0 0250 +¨ " +co 14,11 0 0251 +© " +Of 6,11 0 0252 +ª " +Fo 7,6 0 0253 +« " +no 9,5 0 0254 +¬ " +- 5,4 0 055 +hy " + " +rg 14,11 0 0256 +® " +a- 5,9 0 0257 +¯ " +de 6,11 0 0260 +° " ++- 9,7 0 0261 +± " +S2 5,11 0 0262 +² " +S3 5,11 0 0263 +³ " +aa 5,11 0 0264 +´ " +µ 9,7,3 0 0265 +ps 9,11,2 0 0266 +¶ " +md 4,5 0 0267 +· " +ac 5,1,3 0 0270 +¸ " +S1 5,11 0 0271 +¹ " +Om 5,11 0 0272 +º " +Fc 7,6 0 0273 +» " +14 12,11 0 0274 +¼ " +12 12,11 0 0275 +½ " +34 12,11 0 0276 +¾ " +r? 6,8,3 0 0277 +¿ " +`A 10,14 0 0300 +À " +'A 10,14 0 0301 +Á " +^A 10,14 0 0302 +Â " +~A 10,14 0 0303 +Ã " +:A 10,13 0 0304 +Ä " +oA 10,14 0 0305 +Å " +AE 15,11 0 0306 +Æ " +,C 11,11,3 0 0307 +Ç " +`E 10,14 0 0310 +È " +'E 10,14 0 0311 +É " +^E 10,14 0 0312 +Ê " +:E 10,14 0 0313 +Ë " +`I 6,14 0 0314 +Ì " +'I 6,14 0 0315 +Í " +^I 6,14 0 0316 +Î " +:I 6,14 0 0317 +Ï " +-D 11,11 0 0320 +Ð " +~N 13,14 0 0321 +Ñ " +`O 11,14 0 0322 +Ò " +'O 11,14 0 0323 +Ó " +^O 11,14 0 0324 +Ô " +~O 11,14 0 0325 +Õ " +:O 11,14 0 0326 +Ö " +mu 9,7 0 0327 +× " +/O 11,11 0 0330 +Ø " +`U 13,14 0 0331 +Ù " +'U 13,14 0 0332 +Ú " +^U 13,14 0 0333 +Û " +:U 13,14 0 0334 +Ü " +'Y 10,14 0 0335 +Ý " +TP 10,11 0 0336 +Þ " +ss 8,11 0 0337 +ß " +`a 8,11 0 0340 +à " +'a 8,11 0 0341 +á " +^a 8,11 0 0342 +â " +~a 8,10 0 0343 +ã " +:a 8,10 0 0344 +ä " +oa 8,11 0 0345 +å " +ae 12,7 0 0346 +æ " +,c 7,7,3 0 0347 +ç " +`e 7,11 0 0350 +è " +'e 7,11 0 0351 +é " +^e 7,11 0 0352 +ê " +:e 7,10 0 0353 +ë " +`i 4,11 0 0354 +ì " +'i 4,11 0 0355 +í " +^i 4,11 0 0356 +î " +:i 4,10 0 0357 +ï " +Sd 7,11 0 0360 +ð " +~n 9,10 0 0361 +ñ " +`o 7,11 0 0362 +ò " +'o 7,11 0 0363 +ó " +^o 7,11 0 0364 +ô " +~o 7,10 0 0365 +õ " +:o 7,10 0 0366 +ö " +di 9,7 0 0367 +÷ " +/o 7,8,1 0 0370 +ø " +`u 9,11 0 0371 +ù " +'u 9,11 0 0372 +ú " +^u 9,11 0 0373 +û " +:u 9,10 0 0374 +ü " +'y 8,11,3 0 0375 +ý " +Tp 8,11,3 0 0376 +þ " +:y 8,10,3 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/devhtml/S b/gnu/usr.bin/groff/devhtml/S new file mode 100644 index 00000000000..59af889e130 --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/S @@ -0,0 +1,226 @@ +name S +special +spacewidth 4 +charset +--- 4,1 0 040 +! 5,10 0 041 +fa 9,10 0 042 +# 7,10 0 043 +sh " +te 8,10 0 044 +% 12,10 0 045 +& 11,10 0 046 +st 6,7 0 047 +( 5,10,3 0 050 +) 5,10,3 0 051 +** 7,8 0 052 ++ 8,7 0 053 +pl " +, 3,2,2 0 054 +\- 8,4 0 055 +mi " +. 3,2 0 056 +/ 4,10 0 057 +sl " +0 7,10 0 060 +1 7,10 0 061 +2 7,10 0 062 +3 7,10 0 063 +4 7,10 0 064 +5 7,10 0 065 +6 7,10 0 066 +7 7,10 0 067 +8 7,10 0 070 +9 7,10 0 071 +: 4,7 0 072 +; 4,7,2 0 073 +< 8,7 0 074 += 8,5 0 075 +eq " +> 8,7 0 076 +? 6,10 0 077 +=~ 8,7 0 0100 +*A 11,10 0 0101 +*B 9,10 0 0102 +*X 11,10 0 0103 +*D 9,10 0 0104 +*E 9,10 0 0105 +*F 11,10 0 0106 +*G 9,10 0 0107 +*Y 11,10 0 0110 +*I 5,10 0 0111 ++h 9,10 0 0112 +*K 10,10 0 0113 +*L 10,10 0 0114 +*M 13,10 0 0115 +*N 11,10 0 0116 +*O 10,10 0 0117 +*P 11,10 0 0120 +*H 10,10 0 0121 +*R 8,10 0 0122 +*S 9,10 0 0123 +*T 9,10 0 0124 +--- 9,10 0 0125 +ts 7,7,3 0 0126 +*W 11,10 0 0127 +*C 9,10 0 0130 +*Q 11,10 0 0131 +*Z 9,10 0 0132 +[ 5,10,3 0 0133 +lB " +tf 10,7 0 0134 +3d " +] 5,10,3 0 0135 +rB " +pp 10,10 0 0136 +_ 7,0,3 0 0137 +radicalex 7,12 0 0140 +*a 9,7 0 0141 +*b 8,11,3 0 0142 +*x 8,7,3 0 0143 +*d 7,11 0 0144 +*e 6,7 0 0145 +*f 9,10,3 0 0146 +*g 6,7,3 0 0147 +*y 8,7,3 0 0150 +*i 5,7 0 0151 ++f 9,7,3 0 0152 +*k 8,7 0 0153 +*l 8,10 0 0154 +*m 8,7,2 0 0155 +µ " +*n 8,7 0 0156 +*o 8,7 0 0157 +*p 8,7 0 0160 +*h 7,10 0 0161 +*r 8,7,3 0 0162 +*s 8,7 0 0163 +*t 6,7 0 0164 +*u 8,7 0 0165 ++p 11,8 0 0166 +*w 11,7 0 0167 +*c 7,12,3 0 0170 +*q 9,7,3 0 0171 +*z 7,11,3 0 0172 +lC 7,10,3 0 0173 +{ " +ba 3,10,3 0 0174 +or " +| " +rC 7,10,3 0 0175 +} " +ap 8,5 0 0176 +*U 9,10 0 0241 +fm 4,10 0 0242 +<= 8,9 0 0243 +f/ 4,10 0 0244 +if 10,6 0 0245 +Fn 7,10,3 0 0246 +CL 11,7 0 0247 +DI 11,7 0 0250 +HE 11,7 0 0251 +SP 11,7 0 0252 +<> 15,7 0 0253 +<- 14,7 0 0254 +ua 9,12,3 0 0255 +arrowverttp " +-> 14,7 0 0256 +da 9,12,3 0 0257 +arrowvertbt " +de 6,10 0 0260 +° " ++- 8,9 0 0261 +± " +sd 6,10 0 0262 +>= 8,9 0 0263 +mu 8,7 0 0264 +× " +pt 10,6 0 0265 +pd 7,11 0 0266 +bu 7,6 0 0267 +di 8,7 0 0270 +÷ " +!= 8,7 0 0271 +== 8,6 0 0272 +~= 8,7 0 0273 +~~ " +--- 15,2 0 0274 +arrowvertex 9,12,3 0 0275 +an 15,4 0 0276 +CR 10,9 0 0277 +Ah 12,10 0 0300 +Im 10,11,1 0 0301 +Re 12,11 0 0302 +wp 12,9,3 0 0303 +c* 11,9 0 0304 +c+ 11,9 0 0305 +es 12,11 0 0306 +ca 10,7 0 0307 +cu 10,7 0 0310 +sp 10,7 0 0311 +ip 10,7,2 0 0312 +--- 10,8,1 0 0313 +sb 10,7 0 0314 +ib 10,7,2 0 0315 +mo 10,7 0 0316 +nm 10,8,1 0 0317 +/_ 11,10 0 0320 +gr 10,11 0 0321 +rg 12,10 0 0322 +co 12,10 0 0323 +tm 11,10 0 0324 +--- 12,11,1 0 0325 +sr 8,12 0 0326 +md 4,5 0 0327 +no 10,5 0 0330 +¬ " +AN 9,7 0 0331 +OR 9,7 0 0332 +hA 15,7 0 0333 +lA 14,7 0 0334 +uA 9,12 0 0335 +rA 14,7 0 0336 +dA 9,12 0 0337 +lz 7,11 0 0340 +la 5,12,3 0 0341 +--- 12,10 0 0342 +--- 12,10 0 0343 +--- 11,10 0 0344 +--- 10,11,1 0 0345 +parenlefttp 6,12,3 0 0346 +parenleftex 6,12,3 0 0347 +parenleftbt 6,12,3 0 0350 +bracketlefttp 6,12,3 0 0351 +lc " +bracketleftex 6,12,3 0 0352 +bracketleftbt 6,12,3 0 0353 +lf " +bracelefttp 7,12,3 0 0354 +lt " +braceleftmid 7,12,3 0 0355 +lk " +braceleftbt 7,12,3 0 0356 +lb " +bracerightex 7,12,3 0 0357 +braceleftex " +bv " +--- 12,12 0 0360 +ra 5,12,3 0 0361 +is 4,12,1 0 0362 +--- 10,12,3 0 0363 +--- 10,12,3 0 0364 +--- 10,12,3 0 0365 +parenrighttp 6,12,3 0 0366 +parenrightex 6,12,3 0 0367 +parenrightbt 6,12,3 0 0370 +bracketrighttp 6,12,3 0 0371 +rc " +bracketrightex 6,12,3 0 0372 +bracketrightbt 6,12,3 0 0373 +rf " +bracerighttp 7,12,3 0 0374 +rt " +bracerightmid 7,12,3 0 0375 +rk " +bracerightbt 7,12,3 0 0376 +rb " diff --git a/gnu/usr.bin/groff/devhtml/TB b/gnu/usr.bin/groff/devhtml/TB new file mode 100644 index 00000000000..fbc4c8b20e7 --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/TB @@ -0,0 +1,306 @@ +name TB +spacewidth 3 +charset +--- 3,1 0 040 +! 4,10 0 041 +" 7,10 0 042 +# 7,10 0 043 +sh " +$ 7,11,1 0 044 +Do " +% 14,10 0 045 +& 12,10 0 046 +' 4,10 0 047 +( 5,10,3 0 050 +) 5,10,3 0 051 +* 7,10 0 052 ++ 8,7 0 053 +, 3,2,2 0 054 +\- 9,4 0 055 +. 3,2 0 056 +/ 4,10 0 057 +sl " +0 7,10 0 060 +1 7,10 0 061 +2 7,10 0 062 +3 7,10 0 063 +4 7,10 0 064 +5 7,10 0 065 +6 7,10 0 066 +7 7,10 0 067 +8 7,10 0 070 +9 7,10 0 071 +: 4,7 0 072 +; 4,7,2 0 073 +< 8,7 0 074 += 8,5 0 075 +eq " +> 8,7 0 076 +? 7,10 0 077 +@ 14,10,2 0 0100 +at " +A 10,10 0 0101 +B 9,10 0 0102 +C 10,10 0 0103 +D 10,10 0 0104 +E 9,10 0 0105 +F 8,10 0 0106 +G 11,10 0 0107 +H 11,10 0 0110 +I 5,10 0 0111 +J 7,10,1 0 0112 +K 11,10 0 0113 +L 9,10 0 0114 +M 13,10 0 0115 +N 10,10 0 0116 +O 11,10 0 0117 +P 9,10 0 0120 +Q 11,10,3 0 0121 +R 10,10 0 0122 +S 8,10 0 0123 +T 9,10 0 0124 +U 10,10 0 0125 +V 10,10 0 0126 +W 14,10 0 0127 +X 10,10 0 0130 +Y 10,10 0 0131 +Z 9,10 0 0132 +[ 5,10,3 0 0133 +lB " +\ 4,10 0 0134 +rs " +] 5,10,3 0 0135 +rB " +^ 8,10 0 0136 +a^ " +ha " +_ 7,0,3 0 0137 +` 4,10 0 0140 +oq " +a 7,7 0 0141 +b 8,10 0 0142 +c 6,7 0 0143 +d 7,10 0 0144 +e 6,7 0 0145 +f 5,10 0 0146 +g 7,7,3 0 0147 +h 8,10 0 0150 +i 4,10 0 0151 +j 4,10,3 0 0152 +k 8,10 0 0153 +l 4,10 0 0154 +m 12,7 0 0155 +n 8,7 0 0156 +o 7,7 0 0157 +p 8,7,3 0 0160 +q 7,7,3 0 0161 +r 6,7 0 0162 +s 6,7 0 0163 +t 5,9 0 0164 +u 7,7 0 0165 +v 7,7 0 0166 +w 10,7 0 0167 +x 7,7 0 0170 +y 7,7,3 0 0171 +z 6,7 0 0172 +{ 7,10,3 0 0173 +lC " +| 3,10,2 0 0174 +or " +ba " +} 7,10,3 0 0175 +rC " +~ 8,7 0 0176 +a~ " +ap " +ti " +r! 4,7,3 0 0241 +¡ " +ct 7,9,2 0 0242 +¢ " +Po 8,10 0 0243 +£ " +Cs 8,8 0 0244 +¤ " +Ye 8,10 0 0245 +¥ " +bb 3,10,2 0 0246 +¦ " +sc 7,10,2 0 0247 +§ " +ad 5,10 0 0250 +¨ " +co 12,10 0 0251 +© " +Of 5,10 0 0252 +ª " +Fo 9,6 0 0253 +« " +no 9,5 0 0254 +¬ " +- 4,4 0 055 +hy " + " +rg 12,10 0 0256 +® " +a- 5,9 0 0257 +¯ " +de 6,10 0 0260 +° " ++- 8,9 0 0261 +± " +S2 4,10 0 0262 +² " +S3 4,10 0 0263 +³ " +aa 5,11 0 0264 +´ " +µ 7,7,3 0 0265 +ps 8,10,3 0 0266 +¶ " +md 4,6 0 0267 +· " +ac 5,0,3 0 0270 +¸ " +S1 4,10 0 0271 +¹ " +Om 5,10 0 0272 +º " +Fc 9,6 0 0273 +» " +14 10,10 0 0274 +¼ " +12 10,10 0 0275 +½ " +34 10,10 0 0276 +¾ " +r? 7,7,3 0 0277 +¿ " +`A 10,14 0 0300 +À " +'A 10,14 0 0301 +Á " +^A 10,14 0 0302 +Â " +~A 10,13 0 0303 +Ã " +:A 10,13 0 0304 +Ä " +oA 10,14 0 0305 +Å " +AE 14,10 0 0306 +Æ " +,C 10,10,3 0 0307 +Ç " +`E 9,14 0 0310 +È " +'E 9,14 0 0311 +É " +^E 9,14 0 0312 +Ê " +:E 9,13 0 0313 +Ë " +`I 5,14 0 0314 +Ì " +'I 5,14 0 0315 +Í " +^I 5,14 0 0316 +Î " +:I 5,13 0 0317 +Ï " +-D 11,10 0 0320 +Ð " +~N 10,13 0 0321 +Ñ " +`O 11,14 0 0322 +Ò " +'O 11,14 0 0323 +Ó " +^O 11,14 0 0324 +Ô " +~O 11,13 0 0325 +Õ " +:O 11,13 0 0326 +Ö " +mu 8,7 0 0327 +× " +/O 11,11,1 0 0330 +Ø " +`U 10,14 0 0331 +Ù " +'U 10,14 0 0332 +Ú " +^U 10,14 0 0333 +Û " +:U 10,13 0 0334 +Ü " +'Y 10,14 0 0335 +Ý " +TP 9,10 0 0336 +Þ " +ss 8,10 0 0337 +ß " +`a 7,11 0 0340 +à " +'a 7,11 0 0341 +á " +^a 7,11 0 0342 +â " +~a 7,10 0 0343 +ã " +:a 7,10 0 0344 +ä " +oa 7,11 0 0345 +å " +ae 11,7 0 0346 +æ " +,c 7,7,3 0 0347 +ç " +`e 7,11 0 0350 +è " +'e 7,11 0 0351 +é " +^e 7,11 0 0352 +ê " +:e 7,10 0 0353 +ë " +`i 4,11 0 0354 +ì " +'i 4,11 0 0355 +í " +^i 4,11 0 0356 +î " +:i 4,10 0 0357 +ï " +Sd 7,10 0 0360 +ð " +~n 8,10 0 0361 +ñ " +`o 7,11 0 0362 +ò " +'o 7,11 0 0363 +ó " +^o 7,11 0 0364 +ô " +~o 7,10 0 0365 +õ " +:o 7,10 0 0366 +ö " +di 8,7 0 0367 +÷ " +/o 7,8,1 0 0370 +ø " +`u 7,11 0 0371 +ù " +'u 7,11 0 0372 +ú " +^u 7,11 0 0373 +û " +:u 7,10 0 0374 +ü " +'y 7,11,3 0 0375 +ý " +Tp 8,10,3 0 0376 +þ " +:y 7,10,3 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/devhtml/TBI b/gnu/usr.bin/groff/devhtml/TBI new file mode 100644 index 00000000000..56c55cf30db --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/TBI @@ -0,0 +1,306 @@ +name TBI +spacewidth 3 +charset +--- 3,1 0 040 +! 7,10 0 041 +" 7,10 0 042 +# 8,10 0 043 +sh " +$ 7,11,1 0 044 +Do " +% 14,10 0 045 +& 10,10 0 046 +' 5,10 0 047 +( 6,10,3 0 050 +) 6,10,3 0 051 +* 7,10 0 052 ++ 9,7 0 053 +, 4,2,2 0 054 +\- 9,4 0 055 +. 3,2 0 056 +/ 6,10 0 057 +sl " +0 7,10 0 060 +1 7,10 0 061 +2 7,10 0 062 +3 7,10 0 063 +4 7,10 0 064 +5 7,10 0 065 +6 7,10 0 066 +7 7,10 0 067 +8 7,10 0 070 +9 7,10 0 071 +: 5,7 0 072 +; 4,7,2 0 073 +< 8,6 0 074 += 10,5 0 075 +eq " +> 8,6 0 076 +? 8,10 0 077 +@ 15,10,2 0 0100 +at " +A 9,10 0 0101 +B 9,10 0 0102 +C 9,10 0 0103 +D 10,10 0 0104 +E 10,10 0 0105 +F 9,10 0 0106 +G 10,10 0 0107 +H 11,10 0 0110 +I 5,10 0 0111 +J 7,10,1 0 0112 +K 11,10 0 0113 +L 9,10 0 0114 +M 13,10 0 0115 +N 11,10 0 0116 +O 10,10 0 0117 +P 9,10 0 0120 +Q 10,10,3 0 0121 +R 10,10 0 0122 +S 8,10 0 0123 +T 10,10 0 0124 +U 10,10 0 0125 +V 10,10 0 0126 +W 13,10 0 0127 +X 9,10 0 0130 +Y 8,10 0 0131 +Z 8,10 0 0132 +[ 6,10,3 0 0133 +lB " +\ 6,10 0 0134 +rs " +] 5,10,3 0 0135 +rB " +^ 8,10 0 0136 +a^ " +ha " +_ 7,0,2 0 0137 +` 5,10 0 0140 +oq " +a 8,7 0 0141 +b 7,10 0 0142 +c 6,7 0 0143 +d 7,10 0 0144 +e 7,7 0 0145 +f 5,10,3 0 0146 +g 6,7,3 0 0147 +h 8,10 0 0150 +i 4,10 0 0151 +j 4,10,3 0 0152 +k 7,10 0 0153 +l 4,10 0 0154 +m 11,7 0 0155 +n 8,7 0 0156 +o 7,7 0 0157 +p 7,7,3 0 0160 +q 7,7,3 0 0161 +r 6,7 0 0162 +s 6,7 0 0163 +t 4,9 0 0164 +u 7,7 0 0165 +v 6,7 0 0166 +w 9,7 0 0167 +x 6,7 0 0170 +y 6,7,3 0 0171 +z 6,7 0 0172 +{ 7,10,3 0 0173 +lC " +| 4,10 0 0174 +or " +ba " +} 7,10,3 0 0175 +rC " +~ 10,5 0 0176 +a~ " +ap " +ti " +r! 7,7,3 0 0241 +¡ " +ct 7,8,1 0 0242 +¢ " +Po 7,10 0 0243 +£ " +Cs 8,8 0 0244 +¤ " +Ye 7,10 0 0245 +¥ " +bb 4,10 0 0246 +¦ " +sc 8,10,3 0 0247 +§ " +ad 6,9 0 0250 +¨ " +co 12,10 0 0251 +© " +Of 6,10 0 0252 +ª " +Fo 8,6 0 0253 +« " +no 9,5 0 0254 +¬ " +- 5,4 0 055 +hy " + " +rg 12,10 0 0256 +® " +a- 6,9 0 0257 +¯ " +de 6,10 0 0260 +° " ++- 9,9 0 0261 +± " +S2 4,10 0 0262 +² " +S3 4,10 0 0263 +³ " +aa 6,10 0 0264 +´ " +µ 7,7,3 0 0265 +ps 8,10,3 0 0266 +¶ " +md 4,5 0 0267 +· " +ac 5,0,3 0 0270 +¸ " +S1 4,10 0 0271 +¹ " +Om 6,10 0 0272 +º " +Fc 8,6 0 0273 +» " +14 10,10 0 0274 +¼ " +12 10,10 0 0275 +½ " +34 10,10 0 0276 +¾ " +r? 8,7,3 0 0277 +¿ " +`A 9,13 0 0300 +À " +'A 9,13 0 0301 +Á " +^A 9,13 0 0302 +Â " +~A 9,13 0 0303 +Ã " +:A 9,13 0 0304 +Ä " +oA 9,13 0 0305 +Å " +AE 14,10 0 0306 +Æ " +,C 9,10,3 0 0307 +Ç " +`E 10,13 0 0310 +È " +'E 10,13 0 0311 +É " +^E 10,13 0 0312 +Ê " +:E 10,13 0 0313 +Ë " +`I 5,13 0 0314 +Ì " +'I 5,13 0 0315 +Í " +^I 5,13 0 0316 +Î " +:I 5,13 0 0317 +Ï " +-D 10,10 0 0320 +Ð " +~N 11,13 0 0321 +Ñ " +`O 10,13 0 0322 +Ò " +'O 10,13 0 0323 +Ó " +^O 10,13 0 0324 +Ô " +~O 10,13 0 0325 +Õ " +:O 10,13 0 0326 +Ö " +mu 9,7 0 0327 +× " +/O 10,11,1 0 0330 +Ø " +`U 10,13 0 0331 +Ù " +'U 10,13 0 0332 +Ú " +^U 10,13 0 0333 +Û " +:U 10,13 0 0334 +Ü " +'Y 8,13 0 0335 +Ý " +TP 9,10 0 0336 +Þ " +ss 7,10,3 0 0337 +ß " +`a 8,10 0 0340 +à " +'a 8,10 0 0341 +á " +^a 8,11 0 0342 +â " +~a 8,10 0 0343 +ã " +:a 8,10 0 0344 +ä " +oa 8,11 0 0345 +å " +ae 11,7 0 0346 +æ " +,c 6,7,3 0 0347 +ç " +`e 7,10 0 0350 +è " +'e 7,10 0 0351 +é " +^e 7,11 0 0352 +ê " +:e 7,10 0 0353 +ë " +`i 4,10 0 0354 +ì " +'i 4,10 0 0355 +í " +^i 4,11 0 0356 +î " +:i 4,10 0 0357 +ï " +Sd 7,10 0 0360 +ð " +~n 8,10 0 0361 +ñ " +`o 7,10 0 0362 +ò " +'o 7,10 0 0363 +ó " +^o 7,11 0 0364 +ô " +~o 7,10 0 0365 +õ " +:o 7,10 0 0366 +ö " +di 9,7 0 0367 +÷ " +/o 7,8,1 0 0370 +ø " +`u 7,10 0 0371 +ù " +'u 7,10 0 0372 +ú " +^u 7,11 0 0373 +û " +:u 7,10 0 0374 +ü " +'y 6,10,2 0 0375 +ý " +Tp 7,10,3 0 0376 +þ " +:y 6,10,2 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/devhtml/TI b/gnu/usr.bin/groff/devhtml/TI new file mode 100644 index 00000000000..fddf4b74fbf --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/TI @@ -0,0 +1,306 @@ +name TI +spacewidth 3 +charset +--- 3,1 0 040 +! 5,10 0 041 +" 6,10 0 042 +# 7,10 0 043 +sh " +$ 7,11,1 0 044 +Do " +% 12,10 0 045 +& 11,10 0 046 +' 5,10 0 047 +( 5,10,3 0 050 +) 5,10,3 0 051 +* 7,10 0 052 ++ 10,7 0 053 +, 4,2,1 0 054 +\- 9,4 0 055 +. 3,2 0 056 +/ 4,10 0 057 +sl " +0 7,10 0 060 +1 7,10 0 061 +2 7,10 0 062 +3 7,10 0 063 +4 7,10 0 064 +5 7,10 0 065 +6 7,10 0 066 +7 7,10 0 067 +8 7,10 0 070 +9 7,10 0 071 +: 4,7 0 072 +; 4,7,1 0 073 +< 10,7,1 0 074 += 10,5 0 075 +eq " +> 10,7,1 0 076 +? 7,10 0 077 +@ 13,10,3 0 0100 +at " +A 9,10 0 0101 +B 8,10 0 0102 +C 9,10 0 0103 +D 10,10 0 0104 +E 9,10 0 0105 +F 9,10 0 0106 +G 10,10 0 0107 +H 10,10 0 0110 +I 5,10 0 0111 +J 6,10 0 0112 +K 10,10 0 0113 +L 8,10 0 0114 +M 12,10 0 0115 +N 11,10 0 0116 +O 10,10 0 0117 +P 9,10 0 0120 +Q 10,10,3 0 0121 +R 9,10 0 0122 +S 7,10 0 0123 +T 8,10 0 0124 +U 10,10 0 0125 +V 9,10 0 0126 +W 11,10 0 0127 +X 9,10 0 0130 +Y 8,10 0 0131 +Z 8,10 0 0132 +[ 6,10,3 0 0133 +lB " +\ 4,10 0 0134 +rs " +] 6,10,3 0 0135 +rB " +^ 6,10 0 0136 +a^ " +ha " +_ 7,0,4 0 0137 +` 5,10 0 0140 +oq " +a 7,7 0 0141 +b 7,10 0 0142 +c 6,7 0 0143 +d 7,10 0 0144 +e 7,7 0 0145 +f 5,10,3 0 0146 +g 6,7,3 0 0147 +h 7,10 0 0150 +i 4,10 0 0151 +j 4,10,3 0 0152 +k 7,10 0 0153 +l 4,10 0 0154 +m 10,7 0 0155 +n 7,7 0 0156 +o 7,7 0 0157 +p 7,7,3 0 0160 +q 7,7,3 0 0161 +r 5,7 0 0162 +s 6,7 0 0163 +t 5,9 0 0164 +u 7,7 0 0165 +v 6,7 0 0166 +w 9,7 0 0167 +x 7,7 0 0170 +y 7,7,3 0 0171 +z 6,7 0 0172 +{ 6,10,3 0 0173 +lC " +| 4,10,3 0 0174 +or " +ba " +} 6,10,3 0 0175 +rC " +~ 8,5 0 0176 +a~ " +ap " +ti " +r! 6,7,3 0 0241 +¡ " +ct 7,9,2 0 0242 +¢ " +Po 7,10 0 0243 +£ " +Cs 7,8 0 0244 +¤ " +Ye 7,10 0 0245 +¥ " +bb 4,10,3 0 0246 +¦ " +sc 7,11,2 0 0247 +§ " +ad 5,10 0 0250 +¨ " +co 12,10 0 0251 +© " +Of 5,10 0 0252 +ª " +Fo 7,6 0 0253 +« " +no 9,6 0 0254 +¬ " +- 5,4 0 055 +hy " + " +rg 12,10 0 0256 +® " +a- 5,10 0 0257 +¯ " +de 6,10 0 0260 +° " ++- 10,9 0 0261 +± " +S2 4,10 0 0262 +² " +S3 4,10 0 0263 +³ " +aa 4,10 0 0264 +´ " +µ 7,7,3 0 0265 +ps 8,10,3 0 0266 +¶ " +md 4,4 0 0267 +· " +ac 5,0,3 0 0270 +¸ " +S1 4,10 0 0271 +¹ " +Om 5,10 0 0272 +º " +Fc 7,6 0 0273 +» " +14 10,10 0 0274 +¼ " +12 10,10 0 0275 +½ " +34 10,10 0 0276 +¾ " +r? 7,7,3 0 0277 +¿ " +`A 9,13 0 0300 +À " +'A 9,13 0 0301 +Á " +^A 9,13 0 0302 +Â " +~A 9,13 0 0303 +Ã " +:A 9,12 0 0304 +Ä " +oA 9,13 0 0305 +Å " +AE 13,10 0 0306 +Æ " +,C 9,10,3 0 0307 +Ç " +`E 9,13 0 0310 +È " +'E 9,13 0 0311 +É " +^E 9,13 0 0312 +Ê " +:E 9,12 0 0313 +Ë " +`I 5,13 0 0314 +Ì " +'I 5,13 0 0315 +Í " +^I 5,13 0 0316 +Î " +:I 5,12 0 0317 +Ï " +-D 10,10 0 0320 +Ð " +~N 11,13 0 0321 +Ñ " +`O 10,13 0 0322 +Ò " +'O 10,13 0 0323 +Ó " +^O 10,13 0 0324 +Ô " +~O 10,13 0 0325 +Õ " +:O 10,12 0 0326 +Ö " +mu 10,7 0 0327 +× " +/O 10,11,1 0 0330 +Ø " +`U 10,13 0 0331 +Ù " +'U 10,13 0 0332 +Ú " +^U 10,13 0 0333 +Û " +:U 10,12 0 0334 +Ü " +'Y 8,13 0 0335 +Ý " +TP 9,10 0 0336 +Þ " +ss 7,10,3 0 0337 +ß " +`a 7,10 0 0340 +à " +'a 7,10 0 0341 +á " +^a 7,11 0 0342 +â " +~a 7,10 0 0343 +ã " +:a 7,9 0 0344 +ä " +oa 7,10 0 0345 +å " +ae 10,7 0 0346 +æ " +,c 6,7,3 0 0347 +ç " +`e 7,10 0 0350 +è " +'e 7,10 0 0351 +é " +^e 7,11 0 0352 +ê " +:e 7,9 0 0353 +ë " +`i 4,10 0 0354 +ì " +'i 4,10 0 0355 +í " +^i 4,11 0 0356 +î " +:i 4,9 0 0357 +ï " +Sd 7,10 0 0360 +ð " +~n 7,10 0 0361 +ñ " +`o 7,10 0 0362 +ò " +'o 7,10 0 0363 +ó " +^o 7,11 0 0364 +ô " +~o 7,10 0 0365 +õ " +:o 7,9 0 0366 +ö " +di 10,7 0 0367 +÷ " +/o 7,8,1 0 0370 +ø " +`u 7,10 0 0371 +ù " +'u 7,10 0 0372 +ú " +^u 7,11 0 0373 +û " +:u 7,9 0 0374 +ü " +'y 7,10,3 0 0375 +ý " +Tp 7,10,3 0 0376 +þ " +:y 7,9,3 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/devhtml/TR b/gnu/usr.bin/groff/devhtml/TR new file mode 100644 index 00000000000..c5c5f54e6b9 --- /dev/null +++ b/gnu/usr.bin/groff/devhtml/TR @@ -0,0 +1,306 @@ +name TR +spacewidth 3 +charset +--- 3,1 0 040 +! 5,10 0 041 +" 6,10 0 042 +# 7,10 0 043 +sh " +$ 7,11,1 0 044 +Do " +% 12,10 0 045 +& 11,10 0 046 +' 4,10 0 047 +( 5,10,3 0 050 +) 5,10,3 0 051 +* 7,10 0 052 ++ 8,7 0 053 +, 4,1,2 0 054 +\- 9,4 0 055 +. 4,1 0 056 +/ 4,10,2 0 057 +sl " +0 7,10 0 060 +1 7,10 0 061 +2 7,10 0 062 +3 7,10 0 063 +4 7,10 0 064 +5 7,10 0 065 +6 7,10 0 066 +7 7,10 0 067 +8 7,10 0 070 +9 7,10 0 071 +: 4,7 0 072 +; 4,7,2 0 073 +< 8,7 0 074 += 8,5 0 075 +eq " +> 8,7 0 076 +? 6,10 0 077 +@ 13,10,2 0 0100 +at " +A 11,10 0 0101 +B 9,10 0 0102 +C 10,10 0 0103 +D 10,10 0 0104 +E 9,10 0 0105 +F 8,10 0 0106 +G 11,10 0 0107 +H 10,10 0 0110 +I 5,10 0 0111 +J 6,10 0 0112 +K 10,10 0 0113 +L 9,10 0 0114 +M 13,10 0 0115 +N 11,10 0 0116 +O 10,10 0 0117 +P 8,10 0 0120 +Q 10,10,3 0 0121 +R 9,10 0 0122 +S 8,10 0 0123 +T 9,10 0 0124 +U 10,10 0 0125 +V 9,10 0 0126 +W 13,10 0 0127 +X 10,10 0 0130 +Y 9,10 0 0131 +Z 8,10 0 0132 +[ 5,10,3 0 0133 +lB " +\ 4,10 0 0134 +rs " +] 5,10,3 0 0135 +rB " +^ 7,10 0 0136 +a^ " +ha " +_ 7,0,3 0 0137 +` 4,10 0 0140 +oq " +a 7,7 0 0141 +b 7,10 0 0142 +c 7,7 0 0143 +d 7,10 0 0144 +e 7,7 0 0145 +f 4,10 0 0146 +g 7,7,3 0 0147 +h 7,10 0 0150 +i 3,10 0 0151 +j 4,10,3 0 0152 +k 7,10 0 0153 +l 3,10 0 0154 +m 11,7 0 0155 +n 7,7 0 0156 +o 7,7 0 0157 +p 7,7,3 0 0160 +q 7,7,3 0 0161 +r 5,7 0 0162 +s 6,7 0 0163 +t 4,8 0 0164 +u 7,7 0 0165 +v 7,7 0 0166 +w 11,7 0 0167 +x 7,7 0 0170 +y 7,7,3 0 0171 +z 6,7 0 0172 +{ 7,10,3 0 0173 +lC " +| 3,10 0 0174 +or " +ba " +} 7,10,3 0 0175 +rC " +~ 8,5 0 0176 +a~ " +ap " +ti " +r! 5,7,3 0 0241 +¡ " +ct 7,8,1 0 0242 +¢ " +Po 8,10 0 0243 +£ " +Cs 7,8 0 0244 +¤ " +Ye 7,10 0 0245 +¥ " +bb 3,10 0 0246 +¦ " +sc 7,10,3 0 0247 +§ " +ad 5,10 0 0250 +¨ " +co 12,10 0 0251 +© " +Of 4,10 0 0252 +ª " +Fo 7,6 0 0253 +« " +no 9,6 0 0254 +¬ " +- 4,4 0 055 +hy " + " +rg 12,10 0 0256 +® " +a- 4,9 0 0257 +¯ " +de 6,10 0 0260 +° " ++- 8,7 0 0261 +± " +S2 4,10 0 0262 +² " +S3 4,10 0 0263 +³ " +aa 5,11 0 0264 +´ " +µ 7,7,3 0 0265 +ps 7,10,3 0 0266 +¶ " +md 4,5 0 0267 +· " +ac 5,0,3 0 0270 +¸ " +S1 4,10 0 0271 +¹ " +Om 5,10 0 0272 +º " +Fc 7,6 0 0273 +» " +14 10,10 0 0274 +¼ " +12 10,10 0 0275 +½ " +34 10,10 0 0276 +¾ " +r? 6,7,3 0 0277 +¿ " +`A 11,14 0 0300 +À " +'A 11,14 0 0301 +Á " +^A 11,14 0 0302 +Â " +~A 11,14 0 0303 +Ã " +:A 11,13 0 0304 +Ä " +oA 11,14 0 0305 +Å " +AE 13,10 0 0306 +Æ " +,C 10,10,3 0 0307 +Ç " +`E 9,14 0 0310 +È " +'E 9,14 0 0311 +É " +^E 9,14 0 0312 +Ê " +:E 9,13 0 0313 +Ë " +`I 5,14 0 0314 +Ì " +'I 5,14 0 0315 +Í " +^I 5,14 0 0316 +Î " +:I 5,13 0 0317 +Ï " +-D 10,10 0 0320 +Ð " +~N 11,14 0 0321 +Ñ " +`O 10,14 0 0322 +Ò " +'O 10,14 0 0323 +Ó " +^O 10,14 0 0324 +Ô " +~O 10,14 0 0325 +Õ " +:O 10,13 0 0326 +Ö " +mu 8,7 0 0327 +× " +/O 10,11,1 0 0330 +Ø " +`U 10,14 0 0331 +Ù " +'U 10,14 0 0332 +Ú " +^U 10,14 0 0333 +Û " +:U 10,13 0 0334 +Ü " +'Y 9,14 0 0335 +Ý " +TP 8,10 0 0336 +Þ " +ss 7,10 0 0337 +ß " +`a 7,11 0 0340 +à " +'a 7,11 0 0341 +á " +^a 7,11 0 0342 +â " +~a 7,11 0 0343 +ã " +:a 7,10 0 0344 +ä " +oa 7,11 0 0345 +å " +ae 11,7 0 0346 +æ " +,c 7,7,3 0 0347 +ç " +`e 7,11 0 0350 +è " +'e 7,11 0 0351 +é " +^e 7,11 0 0352 +ê " +:e 7,10 0 0353 +ë " +`i 3,11 0 0354 +ì " +'i 3,11 0 0355 +í " +^i 3,11 0 0356 +î " +:i 3,10 0 0357 +ï " +Sd 7,10 0 0360 +ð " +~n 7,11 0 0361 +ñ " +`o 7,11 0 0362 +ò " +'o 7,11 0 0363 +ó " +^o 7,11 0 0364 +ô " +~o 7,11 0 0365 +õ " +:o 7,10 0 0366 +ö " +di 8,7 0 0367 +÷ " +/o 7,8,1 0 0370 +ø " +`u 7,11 0 0371 +ù " +'u 7,11 0 0372 +ú " +^u 7,11 0 0373 +û " +:u 7,10 0 0374 +ü " +'y 7,11,3 0 0375 +ý " +Tp 7,10,3 0 0376 +þ " +:y 7,10,3 0 0377 +ÿ " diff --git a/gnu/usr.bin/groff/doc/groff.texinfo b/gnu/usr.bin/groff/doc/groff.texinfo new file mode 100644 index 00000000000..d3b7367c3f8 --- /dev/null +++ b/gnu/usr.bin/groff/doc/groff.texinfo @@ -0,0 +1,5762 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header (This is for running Texinfo on a region.) +@setfilename groff +@settitle The GNU Troff Manual +@setchapternewpage odd +@footnotestyle separate +@c %**end of header (This is for running Texinfo on a region.) + + +@dircategory Miscellaneous +@direntry +* Groff: (groff). The GNU troff document formatting system. +@end direntry + + +@smallbook + + +@iftex +@finalout +@end iftex + + +@ifinfo +This Info file documents GNU troff version 1.12. + +Published by the Free Software Foundation +59 Temple Place, Suite 330 +Boston, MA 02111-1307 USA + +Copyright (C) 1994, 1999 Free Software Foundation, Inc. + +Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission notice +identical to this one except for the removal of this paragraph (this +paragraph not being relevant to the printed manual). + +@end ignore +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that this permission notice may be stated in a translation +approved by the Foundation. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +section entitled ``GNU General Public License'' is included exactly as +in the original, and provided that the entire resulting derived work is +distributed under the terms of a permission notice identical to this +one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that the section entitled ``GNU General Public License'' may be +included in a translation approved by the Free Software Foundation +instead of in the original English. +@end ifinfo + + +@titlepage +@title groff +@subtitle The GNU implementation of @code{groff} +@subtitle Edition 1.12 +@subtitle October 1999 +@author by Trent A.@w{ }Fisher +@author and the maintainer of groff + +@c Include the Distribution inside the titlepage environment so +@c that headings are turned off. Headings on and off do not work. + +@page +@vskip 0pt plus 1filll +Copyright @copyright{} 1994, 1999 Free Software Foundation, Inc. + +@sp 2 +Version 1.13 of @code{groff}, @* +October 1999 +@sp 2 +Published by the Free Software Foundation @* +59 Temple Place, Suite 330 @* +Boston, MA 02111-1307 USA + + +Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +section entitled ``GNU General Public License'' is included +exactly as in the original, and provided that the entire resulting +derived work is distributed under the terms of a permission notice +identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that the section entitled ``GNU General Public License'' may be +included in a translation approved by the Free Software Foundation +instead of in the original English. + +Cover art by Etienne Suvasa. +@end titlepage +@page + + + +@node Top, Copying, (dir), (dir) + +@ifinfo +This Info file documents groff version 1.13, the GNU implementation of +the troff typesetting system. + +This is an in-progress document; contributions, comments, or +contributions are welcome. Send them to bug-groff@@gnu.org. +@end ifinfo + +@menu +* Copying:: +* Introduction:: +* Invoking groff:: +* Tutorial for Macro Users:: +* -man:: +* -ms:: +* -me:: +* -mm:: +* Programming Tutorial:: +* geqn:: +* gtbl:: +* gpic:: +* grap:: +* grefer:: +* gsoelim:: +* Devices:: +* File formats:: +* Installation:: +* Request Index:: +* Register Index:: +* String Index:: +* Macro Index:: +* Program Index:: +* Concept Index:: +@end menu + + + +@node Copying, Introduction, Top, Top +@cindex copying +@unnumbered GNU GENERAL PUBLIC LICENSE +@center Version 2, June 1991 + +@display +Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc. +59 Temple Place, Suite 330, Boston, MA 02111, USA + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. +@end display + +@unnumberedsec Preamble + +The licenses for most software are designed to take away your freedom to +share and change it. By contrast, the GNU General Public License is +intended to guarantee your freedom to share and change free software -- +to make sure the software is free for all its users. This General +Public License applies to most of the Free Software Foundation's +software and to any other program whose authors commit to using it. +(Some other Free Software Foundation software is covered by the GNU +Library General Public License instead.) You can apply it to your +programs, too. + +When we speak of free software, we are referring to freedom, not price. +Our General Public Licenses are designed to make sure that you have the +freedom to distribute copies of free software (and charge for this +service if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone +to deny you these rights or to ask you to surrender the rights. These +restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis +or for a fee, you must give the recipients all the rights that you have. +You must make sure that they, too, receive or can get the source code. +And you must show them these terms so they know their rights. + +We protect your rights with two steps: (1)@w{ }copyright the software, +and (2)@w{ }offer you this license which gives you legal permission to +copy, distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + +Finally, any free program is threatened constantly by software patents. +We wish to avoid the danger that redistributors of a free program will +individually obtain patent licenses, in effect making the program +proprietary. To prevent this, we have made it clear that any patent +must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and +modification follow. + +@iftex +@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end iftex +@ifinfo +@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end ifinfo + +@enumerate 0 +@item +This License applies to any program or other work which contains a +notice placed by the copyright holder saying it may be distributed under +the terms of this General Public License. The ``Program'', below, +refers to any such program or work, and a ``work based on the Program'' +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, either +verbatim or with modifications and/or translated into another language. +(Hereinafter, translation is included without limitation in the term +``modification''.) Each licensee is addressed as ``you''. + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of running +the Program is not restricted, and the output from the Program is +covered only if its contents constitute a work based on the Program +(independent of having been made by running the Program). Whether that +is true depends on what the Program does. + +@item +You may copy and distribute verbatim copies of the Program's source code +as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this +License and to the absence of any warranty; and give any other +recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + +@item +You may modify your copy or copies of the Program or any portion of it, +thus forming a work based on the Program, and copy and distribute such +modifications or work under the terms of Section@w{ }1 above, provided +that you also meet all of these conditions: + +@enumerate a +@item +You must cause the modified files to carry prominent notices stating +that you changed the files and the date of any change. + +@item +You must cause any work that you distribute or publish, that in whole or +in part contains or is derived from the Program or any part thereof, to +be licensed as a whole at no charge to all third parties under the terms +of this License. + +@item +If the modified program normally reads commands interactively when run, +you must cause it, when started running for such interactive use in the +most ordinary way, to print or display an announcement including an +appropriate copyright notice and a notice that there is no warranty (or +else, saying that you provide a warranty) and that users may +redistribute the program under these conditions, and telling the user +how to view a copy of this License. (Exception: if the Program itself +is interactive but does not normally print such an announcement, your +work based on the Program is not required to print an announcement.) +@end enumerate + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, and +can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based on +the Program, the distribution of the whole must be on the terms of this +License, whose permissions for other licensees extend to the entire +whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of a +storage or distribution medium does not bring the other work under the +scope of this License. + +@item +You may copy and distribute the Program (or a work based on it, under +Section@w{ }2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + +@enumerate a +@item +Accompany it with the complete corresponding machine-readable source +code, which must be distributed under the terms of Sections 1 and 2 +above on a medium customarily used for software interchange; or, + +@item +Accompany it with a written offer, valid for at least three years, to +give any third party, for a charge no more than your cost of physically +performing source distribution, a complete machine-readable copy of the +corresponding source code, to be distributed under the terms of Sections +1 and 2 above on a medium customarily used for software interchange; or, + +@item +Accompany it with the information you received as to the offer to +distribute corresponding source code. (This alternative is allowed only +for noncommercial distribution and only if you received the program in +object code or executable form with such an offer, in accord with +Subsection b above.) +@end enumerate + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to control +compilation and installation of the executable. However, as a special +exception, the source code distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies the +executable. + +If distribution of executable or object code is made by offering access +to copy from a designated place, then offering equivalent access to copy +the source code from the same place counts as distribution of the source +code, even though third parties are not compelled to copy the source +along with the object code. + +@item +You may not copy, modify, sublicense, or distribute the Program except +as expressly provided under this License. Any attempt otherwise to +copy, modify, sublicense or distribute the Program is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this License +will not have their licenses terminated so long as such parties remain +in full compliance. + +@item +You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute +the Program or its derivative works. These actions are prohibited by +law if you do not accept this License. Therefore, by modifying or +distributing the Program (or any work based on the Program), you +indicate your acceptance of this License to do so, and all its terms and +conditions for copying, distributing or modifying the Program or works +based on it. + +@item +Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further restrictions +on the recipients' exercise of the rights granted herein. You are not +responsible for enforcing compliance by third parties to this License. + +@item +If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent license +would not permit royalty-free redistribution of the Program by all those +who receive copies directly or indirectly through you, then the only way +you could satisfy both it and this License would be to refrain entirely +from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is implemented +by public license practices. Many people have made generous +contributions to the wide range of software distributed through that +system in reliance on consistent application of that system; it is up to +the author/donor to decide if he or she is willing to distribute +software through any other system and a licensee cannot impose that +choice. + +This section is intended to make thoroughly clear what is believed to be +a consequence of the rest of this License. + +@item +If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original +copyright holder who places the Program under this License may add an +explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + +@item +The Free Software Foundation may publish revised and/or new versions of +the General Public License from time to time. Such new versions will be +similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and ``any +later version'', you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Program does not specify a version +number of this License, you may choose any version ever published by the +Free Software Foundation. + +@item +If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask +for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make +exceptions for this. Our decision will be guided by the two goals of +preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + +@iftex +@heading NO WARRANTY +@end iftex +@ifinfo +@center NO WARRANTY +@end ifinfo + +@item +BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW@. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER +EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE@. +THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH +YOU@. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL +NECESSARY SERVICING, REPAIR OR CORRECTION. + +@item +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR +DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL +DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM +(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED +INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF +THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR +OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +@end enumerate + +@iftex +@heading END OF TERMS AND CONDITIONS +@end iftex +@ifinfo +@center END OF TERMS AND CONDITIONS +@end ifinfo + + +@page +@unnumberedsec How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + +To do so, attach the following notices to the program. It is safest to +attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the +``copyright'' line and a pointer to where the full notice is found. + +@smallexample +@var{one line to give the program's name and an idea of what it does.} +Copyright (C) 19@var{yy} @var{name of author} + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE@. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place, Suite 330, Boston, MA 02111, USA. +@end smallexample + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + +@smallexample +Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author} +Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type +`show w'. This is free software, and you are welcome to redistribute it +under certain conditions; type `show c' for details. +@end smallexample + +The hypothetical commands @samp{show w} and @samp{show c} should show +the appropriate parts of the General Public License. Of course, the +commands you use may be called something other than @samp{show w} and +@samp{show c}; they could even be mouse-clicks or menu items---whatever +suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a ``copyright disclaimer'' for the program, if +necessary. Here is a sample; alter the names: + +@smallexample +@group +Yoyodyne, Inc., hereby disclaims all copyright +interest in the program `Gnomovision' +(which makes passes at compilers) written +by James Hacker. + +@var{signature of Ty Coon}, 1 April 1989 +Ty Coon, President of Vice +@end group +@end smallexample + +This General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications +with the library. If this is what you want to do, use the GNU Library +General Public License instead of this License. + + + +@node Introduction, Invoking groff, Copying, Top +@chapter Introduction +@cindex introduction + +GNU @code{troff} (or @code{groff}) is a system for typesetting +documents. @code{troff} is very flexible and has been in existence (and +use) for about 3@w{ }decades. It is quite widespread and firmly +entrenched in the @sc{Unix} community. + + + +@menu +* What Is groff?:: +* History:: +* groff Capabilities:: +* Macro Packages:: +* Preprocessors:: +* Postprocessors:: +* Credits:: +@end menu + +@node What Is groff?, History, Introduction, Introduction +@section What Is @code{groff}? +@cindex what is @code{groff}? +@cindex @code{groff} -- what is it? + + +@code{groff} is of an older generation of document preparation systems, +which operate more like compilers than the more recent interactive +WYSIWYG @footnote{What You See Is What You Get} systems. @code{groff} +and its contemporary counterpart, @TeX{}, both work using a @dfn{batch} +paradigm: The input (or @dfn{source}) files are normal text files with +embedded formatting commands. These files can then be processed by +@code{groff} to produce a typeset document on a variety of devices. + +Likewise, @code{groff} should not be confused with a @dfn{word +processor}, since that term connotes an integrated system which includes +an editor and a text formatter. Also, many word processors follow the +WYSIWYG paradigm which was discussed earlier. + +Although WYSIWYG systems may be easier to use, they have a number of +disadvantages compared to @code{troff}: + +@itemize @bullet{} +@item +They must be used on a bitmapped display to do any operations on your +document. +@item +Most of the WYSIWYG systems are either non-free or are not very +portable. +@item +@code{troff} is firmly entrenched in all @sc{Unix} systems. +@item +It is difficult to have a wide range of capabilities available within +the confines of a GUI/window system. +@item +It is more difficult to make global changes to a document. +@end itemize + +@quotation +``GUIs normally make it simple to accomplish simple actions and +impossible to accomplish complex actions.'' --Doug Gwyn (22/Jun/91 in +@code{comp.unix.wizards}) +@end quotation + + + +@node History, groff Capabilities, What Is groff?, Introduction +@section History +@cindex history + +@code{troff} can trace its origins back to a formatting program called +@code{runoff} which ran on MIT's CTSS system. This name came from the +common phrase of the time ``I'll run off a document.'' + +The first version of @sc{Unix} was developed on a PDP-7 which was +sitting around Bell Labs. In 1971 the developers wanted to get a PDP-11 +for further work on the operating system. In order to justify the cost +for this system, they proposed that they would implement a document +formatting system for the AT&T patents division. This first formatting +program was a reimplementation of @code{runoff}. In accordance with +@sc{Unix}'s penchant for abreviations, it was named @code{roff} (an +abreviation of @code{runoff}). + +When they needed a more flexible language, a new version of @code{roff} +called @code{nroff} (Newer @code{roff}) was written. It had a much more +complicated syntax, but provided the basis for all future versions. +When they got a Graphic Systems CAT Phototypesetter, J.@w{ }F.@w{ +}Ossanna wrote a version of @code{nroff} which would drive it. It was +dubbed @code{troff} for typesetter @code{roff}, although many people +have speculated that it actually means Times @code{roff} because of +@code{troff}'s use of the Times font family by default. As such, the +name @code{troff} is pronounced t-roff rather than trough. + +With @code{troff} came @code{nroff} (they were actually the same program +except for some @samp{#ifdefs}), which was for producing output for line +printers and ascii terminals. It understood everything @code{troff} +did, and ignored the commands which were not aplicable (i.e.@: font +changes). + +Since there are several things which cannot be done easily in +@code{troff}, work on several preprocessors began. These programs would +transform certain parts of a document into @code{troff}, which made a +very natural use of pipes in @sc{Unix}. + +The @code{eqn} preprocessor allowed mathematical formul@ae{} to be +specified in a much simpler and more intuitive manner. @code{tbl} is a +preprocessor for formatting tables. The @code{refer} preprocessor (and +the similar program, @code{bib}) processes citations in a document +according to a bibliographic database. + +Unfortunately, Ossanna's @code{troff} was written in PDP-11 assembly +language and produced output specifically for the CAT phototypesetter. +He rewrote it in C, although it was now 7000@w{ }lines of uncommented +code and still dependent on the CAT. As the CAT became less common, and +was no longer supported by the manufacturer, the need to make it support +other devices became a priority. However, before this could be done, he +was killed in an auto accident. + +@pindex ditroff +So, Brian Kernighan took on the task of rewriting @code{troff}. The +newly rewritten version produced a device independent code which was +very easy for postprocessors to read and translate to the appropriate +printer codes. Also, this new version of @code{troff} (called +@code{ditroff}) had several extentions, which included drawing +functions. + +Due to the additional abilities of the new version of @code{troff}, +several new preprocessors appeared. The @code{pic} preprocessor +provides a wide range of drawing functions. Likewise the @code{ideal} +preprocessor did the same, although via a much different paradigm. The +@code{grap} preprocessor took specifications for graphs, but, unlike +other preprocessors, produced @code{pic} code. + +James Clark began work on a GNU implementation of @code{ditroff} in +early@w{ }1989. The first version, @code{groff}@w{ }0.3.1, was released +June@w{ }1990. @code{groff} included + +@itemize @bullet{} +@item +A replacement for @code{ditroff} with many extentions. +@item +The @code{soelim}, @code{pic}, @code{tbl}, and @code{eqn} preprocessors. +@item +Postprocessors for ascii devices, PostScript, @TeX{} DVI, and X@w{ +}windows. GNU @code{troff} also eliminated the need for a separate +@code{nroff} program with a postprocessor which would produce ascii +output. +@item +A version of the @code{-me} macros and an implementation of the +@code{-man} macros. +@end itemize + +Also, a front-end was included which could construct the, sometimes +painfully long, pipelines required for all the post- and preprocessors. + +Development of GNU @code{troff} progressed rapidly, and saw the +additions of a replacement for @code{refer}, an implementation of the +@code{-ms} and @code{-mm} macros, and a program to deduce how to format +a document (@code{grog}). + +It was declared a stable (i.e.@: non beta) package with the release of +version@w{ }1.04 around November@w{ }1991. + + + +@node groff Capabilities, Macro Packages, History, Introduction +@section @code{groff} Capabilities +@cindex @code{groff} capabilities +@cindex capabilities of @code{groff} + +So what exactly is @code{groff} capable of doing? @code{groff} provides +a wide range of low-level text formatting operations. Using these, you +can perform a wide range of formatting tasks, such as footnotes, table +of contents, multiple columns, etc. + +@itemize @bullet{} +@item +Text filling, adjusting, and centering +@item +Hyphenation +@item +Page control +@item +Font and character size control +@item +Vertical spacing (i.e.@: double spacing) +@item +Line length and indenting +@item +Macros, strings, diversions, and traps +@item +Number registers +@item +Tabs, leaders, and fields +@item +Input and output conventions and character translation +@item +Overstrike, bracket, line drawing, and zero-width functions +@item +Local horizontal and vertical motions and the width function +@item +Three-part titles +@item +Output line numbering +@item +Conditional acceptance of input +@item +Environment switching +@item +Insertions from the standard input +@item +Input/output file switching +@item +Output and error messages +@end itemize + + +@node Macro Packages, Preprocessors, groff Capabilities, Introduction +@section Macro Packages +@cindex macro packages + +Since @code{groff} provides such low level facilities, it can be quite +difficult to use by itself. However, @code{groff} provides a +@dfn{macro} facility which allows you to specify how certain routine +operations (e.g.@w{ }starting paragraphs, printing headers and footers, +etc.)@: should be done. These macros can be collected together into a +@dfn{macro package}. There are a number of macro packages available; +the most common (and the ones described in this manual) are @code{-man}, +@code{-me}, @code{-ms}, and @code{-mm}. + + +@node Preprocessors, Postprocessors, Macro Packages, Introduction +@section Preprocessors +@cindex preprocessors + +Although @code{groff} provides most functions needed to format a +document, some operations would be unwieldy (i.e.@: drawing pictures). +Therefore, programs called preprocessors were written which understand +their own language and produce the necessary groff operations. These +preprocessors are able to differentiate their own input from the rest of +the document via markers. + +To use a preprocessor, @sc{Unix} pipes are used to feed the output from +the preprocessor into @code{groff}. Any number of preprocessors may be +used on a given document; in this case, the preprocessors are linked +together into one pipeline. However, in @code{groff}, the user does not +need to construct the pipe, but only tell @code{groff} what +preprocessors to use. + +@code{groff} currently has preprocessors for producing tables +(@code{tbl}), typesetting equations (@code{eqn}), drawing pictures +(@code{pic}), and for processing bibliographies (@code{refer}). An +associated program which is useful when dealing with preprocessors is +@code{soelim}. + +There are other preprocessors in existence, but there are, +unfortunately, no free implementations available. They are for drawing +pictures (@code{ideal} and @code{gremlin}), for drawing graphs +(@code{grap}), and chemical structures (@code{chem}). + + +@node Postprocessors, Credits, Preprocessors, Introduction +@section Postprocessors +@cindex postprocessors + +@code{groff} actually produces device independent code which may be fed +into a postprocessor which will produce output for a particular device. +Currently, @code{groff} has postprocessors for PostScript, ascii +terminals, X@w{ }windows (for previewing), @TeX{} DVI format, and HTML. + + +@node Credits, , Postprocessors, Introduction +@section Credits +@cindex credits + + +Large portions of this manual were taken from existing documents, most +notably, the manual pages for the @code{groff} package by James Clark, +and Eric Allman's papers on the @code{-me} macro package. + + + +@node Invoking groff, Tutorial for Macro Users, Introduction, Top +@chapter Invoking @code{groff} +@cindex invoking @code{groff} +@cindex @code{groff} invocation + + +@pindex groff +@pindex gtroff +This section focuses on how to invoke the @code{groff} front end. This +front end takes care of the details of constructing the pipeline among +the preprocessors, @code{gtroff} and the postprocessor. + +It has become a tradition that GNU programs get the prefix @dfn{g} to +distinguish it from its original counterparts provided by the host +(@pxref{Environment}, for more details). Thus, for example, @code{geqn} +is GNU @code{eqn}. On operating systems like Linux or the Hurd, which +don't contain proprietary software, this prefix is omitted since GNU +@code{troff} is the only used incarnation of @code{troff}. Exception: +@code{groff} is never replaced by `roff'. + + +@menu +* Options:: +* Environment:: +* Invocation Examples:: +@end menu + +@node Options, Environment, Invoking groff, Invoking groff +@section Options +@cindex options + + +@pindex groff +@pindex gtroff +@pindex gpic +@pindex geqn +@pindex gtbl +@pindex grefer +@pindex gsoelim +@code{groff} is a front-end to the groff document formatting system. +Normally it runs the @code{gtroff} program and a postprocessor +appropriate for the selected device. The default device is @samp{ps}. +It can optionally preprocess with any of @code{gpic}, @code{geqn}, +@code{gtbl}, @code{grefer}, or @code{gsoelim}. + +This section only documents options to the @code{groff} front end. Many +of the arguments to @code{groff} are passed on to @code{gtroff}, +therefore those are also included. Arguments to pre- or postprocessors +can be found in @ref{Invoking gpic}, @ref{Invoking geqn}, @ref{Invoking +gtbl}, @ref{Invoking grefer}, @ref{Invoking gsoelim}, @ref{Invoking +grotty}, @ref{Invoking grops}, @ref{Invoking grohtml}, @ref{Invoking +grodvi}, and @ref{Invoking gxditview} + +The command line format for @code{groff} is: + +@example +groff [ -abehilpstvzCENRSVXZ ] [ -F@var{dir} ] [ -m@var{name} ] + [ -T@var{def} ] [ -f@var{fam} ] [ -w@var{name} ] [ -W@var{name} ] + [ -M@var{dir} ] [ -d@var{cs} ] [ -r@var{cn} ] [ -n@var{num} ] + [ -o@var{list} ] [ -P@var{arg} ] [ -L@var{arg} ] + [ @var{files}@dots{} ] +@end example + +The command line format for @code{gtroff} is as follows. As you can +see, many of the options to @code{groff} are actually passed on to +@code{gtroff}. + +@example +gtroff [ -abivzCER ] [ -w@var{name} ] [ -W@var{name} ] [ -d@var{cs} ] + [ -f@var{fam} ] [ -m@var{name} ] [ -n@var{num} ] + [ -o@var{list} ] [ -r@var{cn} ] [ -T@var{name} ] + [ -F@var{dir} ] [ -M@var{dir} ] [ @var{files}@dots{} ] +@end example + +Options without an argument can be grouped behind a single @samp{-}. A +filename of @samp{-} denotes the standard input. + +@pindex grog +The @code{grog} command can be used to guess the correct @code{groff} +command to use to format a file. + +@table @samp +@item -h +Print a help message. +@item -e +Preprocess with @code{geqn}. +@item -t +Preprocess with @code{gtbl}. +@item -p +Preprocess with @code{gpic}. +@item -s +Preprocess with @code{gsoelim}. +@item -R +Preprocess with @code{grefer}. No mechanism is provided for passing +arguments to @code{grefer} because most @code{grefer} options have +equivalent commands which can be included in the file. @xref{grefer}, +for more details. + +@pindex troffrc +Note that @code{gtroff} also accepts a @samp{-R} option, which is not +accessible via @code{groff}. This option prevents the loading of the +@file{troffrc} file. +@item -v +Make programs run by @code{groff} print out their version number. +@item -V +Print the pipeline on stdout instead of executing it. +@item -z +Suppress output from @code{gtroff}. Only error messages will be printed. +@item -Z +Do not postprocess the output of @code{gtroff}. Normally @code{groff} +will automatically run the appropriate postprocessor. +@item -P@var{arg} +Pass @var{arg} to the postprocessor. Each argument should be passed +with a separate @samp{-P} option. Note that groff does not prepend +@samp{-} to @var{arg} before passing it to the postprocessor. +@item -l +Send the output to a printer. The command used for this is specified by +the print command in the device description file. +@item -L@var{arg} +Pass @var{arg} to the spooler. Each argument should be passed with a +separate @samp{-L} option. Note that @code{groff} does not prepend a +@samp{-} to @var{arg} before passing it to the postprocessor. +@item -T@var{dev} +Prepare output for device @var{dev}. The default device is @samp{ps}. +The following are the output devices currently available: +@table @samp +@item ps +For PostScript printers and previewers. +@item dvi +For TeX dvi format. +@item X75 +For a 75 dpi X11 previewer. +@item X100 +For a 100dpi X11 previewer. +@item ascii +For typewriter-like devices. +@item latin1 +For typewriter-like devices using the ISO Latin-1 character set. +@item lj4 +For an HP LaserJet4-compatible (or other PCL5-compatible) printer. +@item html +To produce HTML output. +@end table + +The postprocessor to be used for a device is specified by the +@code{postpro} command in the device description file. (@xref{Font +Files}, for more info.) This can be overridden with the @samp{-X} +option. +@item -X +Preview with @code{gxditview} instead of using the usual postprocessor. +This is unlikely to produce good results except with @samp{-Tps}. +@item -N +Don't allow newlines with @code{eqn} delimiters. This is the same as +the @samp{-N} option in @code{geqn}. +@item -S +Safer mode. Pass the @samp{-S} option to @code{gpic} and use the +@samp{-msafer} macros with @code{gtroff}. +@item -a +Generate an ASCII approximation of the typeset output. +@item -b +Print a backtrace with each warning or error message. This backtrace +should help track down the cause of the error. The line numbers given +in the backtrace may not always be correct: @code{troff}'s idea of line +numbers gets confused by @code{as} or @code{am} requests. +@item -i +Read the standard input after all the named input files have been +processed. +@item -w@var{name} +Enable warning @var{name}. Available warnings are described in +@ref{Debugging}. Multiple @samp{-w} options are allowed. +@item -W@var{name} +Inhibit warning @var{name}. Multiple @samp{-W} options are allowed. +@item -E +Inhibit all error messages. +@item -C +Enable compatibility mode. +@item -d@var{cs} +@itemx -d@var{name}=s +Define @var{c} or @var{name} to be a string @var{s}; @var{c} must be a +one-letter @var{name}. +@item -f@var{fam} +Use @var{fam} as the default font family. +@item -m@var{name} +Read in the file @file{tmac.@var{name}}. Normally this will be searched +for in @code{groff}'s lib directory. +@item -n@var{num} +Number the first page @var{num}. +@item -o@var{list} +Output only pages in @var{list}, which is a comma-separated list of page +ranges; @var{n} means print page @var{n}, @samp{@var{m}-@var{n}} means +print every page between @var{m} and @var{n}, @samp{-@var{n}} means +print every page up to @var{n}, @samp{@var{n}-} means print every page +from @var{n}. @code{troff} will exit after printing the last page in +the list. +@item -r@var{cn} +@itemx -r@var{name}=@var{n} +Set number register @var{c} or @var{name} to @var{n}; @var{c} must be a +one-letter @var{name}; @var{n} can be any troff numeric expression. +@item -F@var{dir} +Search @var{dir} for subdirectories dev@var{name} (@var{name} is the +name of the device) for the @file{DESC} file and font files before the +normal directory. +@item -M@var{dir} +Search directory @var{dir} for macro files before the normal directory. +@end table + + + +@node Environment, Invocation Examples, Options, Invoking groff +@section Environment +@cindex environment + + +There are also several environment variables which can modify groff's +behavior. + +@table @code +@item GROFF_COMMAND_PREFIX +If this is set to @var{X}, then @code{groff} will run +@var{X}@code{troff} instead of @code{gtroff}. This also applies to +@code{tbl}, @code{pic}, @code{eqn}, @code{refer}, and @code{soelim}. It +does not apply to @code{grops}, @code{grodvi}, @code{grotty}, +@code{grohtml}, @code{grolj4}, and @code{gxditview}. +@item GROFF_TMAC_PATH +A colon separated list of directories in which to search for macro +files. +@item GROFF_TYPESETTER +Default device. +@item GROFF_FONT_PATH +A colon separated list of directories in which to search for the +@code{dev}@var{name} directory. +@item PATH +The search path for commands executed by groff. +@item GROFF_TMPDIR +The directory in which temporary files will be created. If this is not +set and @code{TMPDIR} is set, temporary files will be created in that +directory. Otherwise temporary files will be created in @code{/tmp}. +The @code{grops} and @code{grefer} commands can create temporary files. +@end table + + +@node Invocation Examples, , Environment, Invoking groff +@section Invocation Examples +@cindex invocation examples +@cindex examples of invocation + + +This section will list several common uses of @code{groff} and the +command line which will accomplish it. + +@example +groff file +groff -X -me file +groff -mm -rD1 -z file +groff -tps -me file | lpr -Plw2 +... any more?? ... +@end example + +@subsection @code{grog} + +@code{grog} reads files and guesses which of the @code{groff} +preprocessors and/or macro packages are are required for formatting +them, and prints the @code{groff} command including those options on the +standard output. The options generated are one of @samp{-e}, +@samp{-man}, @samp{-me}, @samp{-mm}, @samp{-ms}, @samp{-p}, @samp{-s}, +and @samp{-t}. + +A filename of @samp{-} is taken to refer to the standard input. If no +files are specified the standard input will be read. Any specified +options will be included in the printed command. No space is allowed +between options and their arguments. For example, + +@example +grog -Tdvi paper.ms +@end example + +will guess the approriate command to print @file{paper.ms} and then run +it after adding the @samp{-Tdvi} option. + + +@node Tutorial for Macro Users, -man, Invoking groff, Top +@chapter Tutorial for Macro Users +@cindex tutorial for macro users +@cindex macro tutorial for users +@cindex user's tutorial for macros +@cindex user's macro tutorial + +Most users tend to use a macro package to format their papers. This +means that the whole breadth of @code{groff} is not neccessary for most +people. This chapter covers the material needed to efficiently use a +macro package. + + +@menu +* Basics:: +* Common Features:: +@end menu + +@node Basics, Common Features, Tutorial for Macro Users, Tutorial for Macro Users +@section Basics +@cindex basics + + +This section covers some of the basic concepts you will need to +understand to use a macro package.@footnote{This section is derived from +@cite{Writing Papers with nroff using -me} by Eric P.@w{ }Allman} +References are made throughout to more detailed information, if desired. + +@code{groff} reads an input file prepared by the user and outputs a +formatted paper suitable for publication or framing. The input consists +of text, or words to be printed, and embedded commands (@dfn{requests} +and @dfn{escapes}), which tell @code{groff} how to format the printed +copy. For more detail on this @pxref{Embedded Commands}. + +The word @dfn{argument} is used in this manual to mean a word or number +which appears on the same line as a request which modifies the meaning +of that request. For example, the request + +@example +.sp +@end example + +@noindent +spaces one line, but + +@example +.sp 4 +@end example + +@noindent +spaces four lines. The number@w{ }4 is an argument to the @code{sp} +request which says to space four lines instead of one. Arguments are +separated from the request and from each other by spaces. More details +on this can be found in @ref{Request Arguments}. + +The primary function of @code{groff} is to collect words from input +lines, fill output lines with those words, justify the right hand margin +by inserting extra spaces in the line, and output the result. For +example, the input: + +@example +Now is the time +for all good men +to come to the aid +of their party. +Four score and seven +years ago,... +@end example + +@noindent +will be read, packed onto output lines, and justified to produce: + +@quotation +Now is the time for all good men to come to the aid of their party. +Four score and seven years ago,... +@end quotation + +@cindex break +@cindex line break +Sometimes you may want to start a new output line even though the line +you are on is not yet full; for example, at the end of a paragraph. To +do this you can cause a @dfn{break}, which starts a new output line. +Some requests cause a break automatically, as do blank input lines and +input lines beginning with a space. + +Not all input lines are text to be formatted. Some of the input lines +are requests which describe how to format the text. Requests always +have a period or an apostrophe (@samp{'}) as the first character of the +input line. + +The text formatter also does more complex things, such as automatically +numbering pages, skipping over page boundaries putting footnotes in the +correct place, and so forth. + +Here a few hints for preparing text for input to @code{groff}. First, +keep the input lines short. Short input lines are easier to edit, and +@code{groff} will pack words onto longer lines for you anyhow. In +keeping with this, it is helpful to begin a new line after every period, +comma, or phrase, since common corrections are to add or delete +sentences or phrases. Secondly, do not hyphenate words at the end of +lines -- @code{groff} is smart enough to hyphenate words for you as +needed, but is not smart enough to take hyphens out and join a word back +together. Also, words such as ``mother-in-law'' should not be broken +over a line, since then you will get a space where not wanted, such as +``mother- in-law''. + +@findex ls +@cindex double spacing +@cindex spacing +Groff will double space output text automatically if you use the request +@samp{.ls 2}. You can revert to single spaced mode by typing @samp{.ls +1}. + +A number of requests allow you to change the way the printed copy looks, +sometimes called the @dfn{layout} of the output page. Most of these +requests adjust the placing of @dfn{white space} (blank lines or +spaces). + +@findex bp +@cindex new page +The @samp{.bp} request starts a new page. + +@findex sp +@cindex blank lines +@cindex empty lines +The request @samp{.sp @var{N}} leaves @var{N} lines of blank space. +@var{N} can be omitted (meaning skip a single line) or can be of the +form @var{N}i (for @var{N} inches) or @var{N}c (for @var{N} +centimeters). For example, the input: + +@example +.sp 1.5i +My thoughts on the subject +.sp +@end example + +@noindent +leaves one and a half inches of space, followed by the line ``My +thoughts on the subject'', followed by a single blank line. + +@findex ce +@cindex centering lines +Text lines can be centered by using the @samp{.ce} request. The line +after @samp{.ce} is centered (horizontally) on the page. To center more +than one line, use @samp{.ce @var{N}} (where @var{N} is the number of +lines to center), followed by the @var{N} lines. If you want to center +many lines but don't want to count them, type: + +@example +.ce 1000 +lines to center +.ce 0 +@end example + +@noindent +The @samp{.ce 0} request tells @code{groff} to center zero more lines, +in other words, stop centering. + +@findex br +@cindex line break +@cindex break +All of these requests cause a break; that is, they always start a new +line. If you want to start a new line without performing any other +action, use @samp{.br}. + + +@node Common Features, , Basics, Tutorial for Macro Users +@section Common Features +@cindex common features +@cindex features, common + + +Groff provides very low level operations for formatting a document. +There are many common routine operations which are done in all documents. +These common operations are written into @dfn{macros} and collected into a +@dfn{macro package}. + +All macro packages provide certain common capabilities which fall +into the following categories. + +@subsection Paragraphs +@cindex paragraphs + +One of the most common and most used capability is starting a +paragraph. There are a number of different types of paragraphs, +any of which can be initiated with macros supplied by the macro +package. Normally paragraphs start with a blank line and the first +line indented, like the text in this manual. There are also block +style paragraphs, which omit the indentation: + +@example +Some men look at constitutions with sanctimonious +reverence, and deem them like the ark of the covenant, too +sacred to be touched. +@end example + +And there are also indented paragraphs which begin with a tag or label +at the margin and the remaining text indented. + +@example +one This is the first paragraph. Notice how the first + line of the resulting paragraph lines up with the + other lines in the paragraph. +longlabel + This paragraph had a long label. The first + character of text on the first line will not line up + with the text on second and subsequent lines, + although they will line up with each other. +@end example + +A variation of this is a bulleted list.... + +@subsection Sections and Chapters + +Most macro packages supply some form of section headers. +The simplest kind is simply the heading on a line by itself in bold +type. Others supply automatically numbered section heading or +different heading styles at different levels. +Some, more sophisticated, macro packages supply macros for starting +chapters and appendicies. + +@subsection Headers and Footers + +Every macro packages gives you some way to manipulate the headers and +footers (or @dfn{titles} on each page. Some packages will allow you +to have different ones on the even and odd pages (for material +printed in a book form). +The titles are called three-part titles, that is, there is a +left-justified part, a centered part, and a right-justified part. +An automatically generated page number may be put in any of these +fields with the @samp{%} character. + +@subsection Page Layout + +Most macro packages let you specify top and bottom margins and other +details about the appearance of the printed pages. + +@subsection Displays +@cindex displays + +Displays are sections of text to be set off from the body +of the paper. Major quotes, tables, and figures are types of +displays, as are all the examples used in this document. + +@cindex quotes, major +@cindex major quotes +Major quotes are quotes which are several lines long, +and hence are set in from the rest of the text without +quote marks around them. + +@cindex list +A list is an indented, single spaced, unfilled display. Lists should +be used when the material to be printed +should not be filled and justified like normal text, such +as columns of figures or the examples used in this paper. + +@cindex keep +A keep is a display of lines which are kept on a single page if +possible. An example of where you would use a +keep might be a diagram. Keeps differ from lists in that +lists may be broken over a page boundary whereas keeps will +not. + +@cindex keep, floating +@cindex floating keep +Floating keeps move relative to the text. Hence, they +are good for things which will be referred to by name, such +as ``See figure 3''. A floating keep will appear at the bottom of the +current page if it will fit; otherwise, it will +appear at the top of the next page. Meanwhile, the surrounding text +will `flow' around the keep, thus leaving now blank areas. + +@subsection Footnotes and annotations +@cindex footnotes +@cindex annotations + +There are a number of requests to save text for later +printing. Footnotes are printed at the bottom of the current +page. Delayed text is intended to be a variant form of foot- +note; the text is printed only when explicitly called for, +such as at the end of each chapter. + +Delayed text is very similar to a footnote except that +it is printed when called for explicitly. This allows a +list of references to appear (for example) at the end of +each chapter, as is the convention in some disciplines. + +Most macro packages which supply this functionality also supply a +means of automatically numbering either type of annotation. + +@subsection Table of Contents + +Tables of contents are a type of +delayed text having a tag (usually the page number) attached +to each entry after a row of dots. The table accumulates +throughought the paper until printed, usually after the paper has +ended. Many macro packages will provide the abilitly to have several +tables of contents (i.e. one standard one, one for tables, &c.) + +@subsection Indexes + +While some macro packages will use the term @dfn{index}, none +actually provide that functionality. The facilities they call +indexes are actually more appropriate for tables of contents. + +@subsection Paper formats + +Some macro packages provide stock formats for various kinds of +documents. Many of them provide a common format for the title and +opening pages of a technical paper. The -mm macros in particular +provide formats for letters and memorandums. + +@subsection Multiple Columns + +Some macro packages (except -man) provide the ability to have two or +more columns on a page. + +@subsection Font and Size changes + +The builtin font and size functions are not always intuitive, so all +macro packages provide macros to make these operations simpler. + +@subsection Predefined Strings + +Most macro packages provide various predefined strings for a variety +of uses, examples are sub- and super-scripts, printable dates, quotes +and various special characters. + +@subsection Preprocessor Support + +All macro packages provide support for the various preprocessors. + +@subsection Configuration and Customization + +Some macro packages provide means of customizing many of details of +how the package behaves. This ranges from setting the default type +size to changing the appearance of section headers. + + +@node -man, -ms, Tutorial for Macro Users, Top +@chapter -man +@cindex @code{-man} + + + +@node -ms, -me, -man, Top +@chapter -ms +@cindex @code{-ms} + + + +@node -me, -mm, -ms, Top +@chapter -me +@cindex @code{-me} + + + +@node -mm, Programming Tutorial, -me, Top +@chapter -mm +@cindex @code{-mm} + + + +@node Programming Tutorial, geqn, -mm, Top +@chapter Programming Tutorial +@cindex programming tutorial +@cindex tutorial for programming + +This chapter covers @strong{all} of the facilities of groff. +If you are intending to use a macro package, you probably do not want +to read this chapter. + + +@menu +* Text:: +* Input Conventions:: +* Measurements:: +* Expressions:: +* Identifiers:: +* Embedded Commands:: +* Registers:: +* Manipulating Filling and Adjusting:: +* Manipulating Hyphenation:: +* Manipulating Spacing:: +* Tabs and Fields:: +* Character Translations:: +* Line Layout:: +* Page Layout:: +* Page Control:: +* Fonts:: +* Sizes:: +* Strings:: +* Conditionals and Loops:: +* Writing Macros:: +* Page Motions:: +* Drawing Functions:: +* Traps:: +* Diversions:: +* Environments:: +* I/O:: +* Postprocessor Access:: +* Miscellany:: +* Debugging:: +* Implementation Differences:: +* Summary:: +@end menu + +@node Text, Input Conventions, Programming Tutorial, Programming Tutorial +@section Text +@cindex text + +@code{groff} input files contain text with control commands +interspersed throughout. But, even without control codes, +@code{groff} will still do several things with your text: +filling and adjusting, +adding additional space after sentences, +hyphenating +and +inserting implicit line breaks. + + +@menu +* Filling and Adjusting:: +* Hyphenation:: +* Sentences:: +* Tab Stops:: +* Implicit Line Breaks:: +@end menu + +@node Filling and Adjusting, Hyphenation, Text, Text +@subsection Filling and Adjusting +@cindex filling and adjusting +@cindex adjusting and filling + + +When troff reads in text it collects words from input and fits as many +of them together on one output line as it can. This is known as +@dfn{filling}. + +Once troff has a @dfn{filled} line it will try to @dfn{adjust} it. +which means it will widen the spacing between words until +the text reaches the right margin (in the default adjustment mode). +Extra spaces between words are preserved, but +spaces at the end of lines are ignored. +Spaces at the front of a line will cause a @dfn{break} +(breaks will be explained in @ref{Implicit Line Breaks}) + +@c distribute these through the text +@xref{Manipulating Filling and Adjusting} + +@node Hyphenation, Sentences, Filling and Adjusting, Text +@subsection Hyphenation +@cindex hyphenation + + +Since the odds of finding a set of words, for every output line, +which will fit nicely on a +line without inserting excessive amounts of space between words +is not great, +troff will hyphenate words so that lines can be justified +without there being too much space between words. +It uses an internal hyphenation algorithm, to indicate which words can +be hyphenated and how to do so. +When a word is hyphenated the first part of the word will be added +to the current filled line being output (with an attached hyphen), +and the other portion will be added to the next line to be filled. + +@c distribute these through the text +@xref{Manipulating Hyphenation} + +@node Sentences, Tab Stops, Hyphenation, Text +@subsection Sentences +@cindex sentences + + +Although it is often debated, +some typesetting rules say there should be different amounts of space +after various puctuation marks. +For example, a period at the end of a sentence +should have twice as much space following it +as would a comma or a period as part of an abbreviation. + +@cindex sentence spaces +@cindex spaces between sentences +Troff does this by flagging certain characters (normally +@samp{!}, @samp{?} and @samp{.}) +as @dfn{end of sentence} characters. +When troff encounters one of these characters at the end of a line it +will append two @dfn{sentence spaces} in the formatted output. +(thus, one of the conventions mentioned in @ref{Input Conventions}). + +@c also describe how characters like ) are treated here -jjc +@c gotta do some research on this -trent + + + +@node Tab Stops, Implicit Line Breaks, Sentences, Text +@subsection Tab Stops +@cindex tab stops +@cindex stops, tabulator + + +Groff translates tabs in the input into movements to the next tab +stop. These tab stops are initially located every half inch across +the page. +Using this you can make simple tables. However, this can often be +deceptive as the appearance (and width) of your text on a terminal and +the results from groff can vary greatly. + +Also, a possible sticking point is that lines beginning with tab +characters will still be filled, again producing unexpected results. +For example, the following input + +@example + 1 2 3 + 4 5 +@end example + +@noindent +will produce + +@example + 1 2 3 4 5 +@end example + +@c Tab stops are with respect to the input line. -jjc +@c did that last section address that?? -trent + + + +@c distribute these through the text +@xref{Tabs and Fields} + +@node Implicit Line Breaks, , Tab Stops, Text +@subsection Implicit Line Breaks +@cindex implicit line breaks +@cindex implicit breaks of lines +@cindex line, implicit breaks +@cindex break +@cindex break, implicit +@cindex line break + +An important concept in troff is the @dfn{break}. When a @dfn{break} +occurs, troff will output the partially filled line (unadjusted), +and resume collecting and filling text on the next output line. + +@cindex blank line +@cindex empty line +@cindex line, blank +There are several ways to cause a break in troff. +A blank line will not only cause a break, but it will also cause a +one line vertical space (effectively a blank line) to be output. + +A line which begins with a space will cause a break and the space +will be output at the beginning of the next line. +Note that this space isn't adjusted, even in fill mode. + +The end of file will also cause a break (otherwise the last line of +your document may vanish!) + +Certain @dfn{requests} also cause breaks, implicitly or explicity. +This will be discussed later. + +@c distribute these through the text +@xref{Manipulating Filling and Adjusting} + +@node Input Conventions, Measurements, Text, Programming Tutorial +@section Input Conventions +@cindex input conventions +@cindex conventions for input + + +Since groff does filling automatically, it is traditional in groff not +to try and type things in as nicely formatted paragraphs. These are +some conventions commonly used when typing groff text: + +@itemize @bullet{} +@item +Break lines after punctuation, particularily at the ends of +sentences, and in other logical places. Keep separate phrases on +lines by themselves, as entire phrases are often added or deleted +when editing. +@item +Try to keep lines less than 40-60 characters, +to allow space for inserting more text. +@item +Do not try to do any formatting in a WYSIWYG manner (i.e. don't +try and use spaces to get proper indentation). +@end itemize + + +@node Measurements, Expressions, Input Conventions, Programming Tutorial +@section Measurements +@cindex measurements + + +@cindex units of measurement +@cindex basic units +@cindex machine units +Troff (like any other programs) requires numeric parameters to +specify various measurements. Most numeric parameters +@footnote{those that specify vertical or horizontal motion or a type +size} may have a measurement unit attached. +These units are specified as a single +character which immediately follows the number or expression. +Each of these units are understood, by troff, to be a multiple of its +@dfn{basic unit}. So, whenever a different measurement unit is +specified troff converts this into its basic units. +This basic unit, represented by a @samp{u} is a +device dependent measurement which is quite small, ranging from +1/75th to 1/72000th of an inch. + +Some of the measurement units are compleatly independent of any of +the current settings (e.g. type size) of groff. + +@table @samp +@item i +@cindex inch +Inches. An antiquated measurement unit still in use in certain +backwards countries. +@item c +@cindex centimeter +Centimeters. +@item p +@cindex points +Points. This is a typesetter's measurement used for measure type size. +It is 72 points to an inch. +@item P +@cindex pica +Pica. Another typesetting measurement. 6 Picas to an inch. +@item s +@item z +@end table + +The other measurements understood by troff are dependent on settings +currently in effect in troff. These are very useful for specifying +measurements which should look proper with any size of text. + +@table @samp +@item m +@cindex em +Ems. This unit is equal to the current font size in points. +So called because it is @emph{approximately} the width of the letter +@samp{m} in the current font. +@item n +@cindex en +Ens. This is half of an em. +@item v +@cindex vertical space +@cindex space, vertical +Vertical space. This is equivalent to the current line spacing. +@xref{Sizes}, for more information about this. +@item M +100ths of an em. +@end table + +@c distribute these through the text +@xref{Fractional Type Sizes} + +@menu +* Default Units:: +@end menu + +@node Default Units, , Measurements, Measurements +@subsection Default Units +@cindex default units +@cindex units, default + + +Many requests take a default unit. While this can be helpful at +times, it can cause strange errors in some expressions. +For example, the line length request expects em's. +Here are several attempts to get 3.5 inches and the results: + +@example +3.5i @result{} 3.5i +7/2 @result{} 0i +7/2i @result{} 0i +7i/2 @result{} .1i +7i/2u @result{} 3.5i +@end example + +As you can see, the safest way to specify measurements is to always +attach a scaling indicator. + +@node Expressions, Identifiers, Measurements, Programming Tutorial +@section Expressions +@cindex expressions + + +Troff has most of operators common to other languages: + +@itemize @bullet +@item +Arithmetic: +, -, /, *, % +@item +Comparison: <, >, >=, <=, =, == (the last two are the same) +@item +Logical: &, : +@item +Unary operators: -, +, ! (if/while only??) +@item +Maximum and minimum: >?, <? +@item +Scaling: (@var{c};@var{e}) +Evaluate @var{e} using @var{c} as the default scaling indicator. +If @var{c} is missing, ignore scaling indicators in the +evaluation of @var{e}. +@end itemize + +Parenthesis may be used as in any other language. +However, in groff they are necessary to ensure order of evaluation. +Groff has no operator precedence, +expressions are evaluated left to right. +This means that @samp{3+5*4} is evaluated as if it were parenthesized +like @samp{(3+5)*4}, not as @samp{3+(5*4)}, like you may expect. + +For many requests which cause a motion on the page, the unary +operators work differently. +The @samp{+} and @samp{-} operators indicate a motion relative to the +current position (down or up, respectively). The @samp{|} operator +indicates an absolute position on the page or input line. (????) +@code{+} and @code{-} are also treated differently by @code{nr} (?) + +Due to the way arguments are parsed, spaces are not allowed in +expressions, unless the entire expression is surrounded by parenthesis. + +@c distribute these through the text +@xref{Request Arguments} +@c distribute these through the text +@xref{Conditionals and Loops} + +@node Identifiers, Embedded Commands, Expressions, Programming Tutorial +@section Identifiers +@cindex identifiers + +Like any other language troff, has rules for properly formed +identifiers. +In troff an identifier can be made up of most any printable +character. +The only exception is characters which are interpreted by troff +(backslash, square bracket and ?). So, for example, any of the following +are valid. + +@example +br +PP +(l +end-list +@@_ +@end example + +You can test whether an identifier is valid in groff with the +@code{\A} escape. It expands to 1 or 0 according whether its argument +(given in quotes) is or is not acceptable as the name of a string, +macro, diversion, number register, environment or font. It will return +0 if no argument is given. This is useful if you want to lookup user +input in some sort of associative table. + +Identifiers in groff can be any length, but, in some contexts, +groff needs to told +where identifiers end and text begins (and in different ways +depending on their length) + +@itemize @bullet{} +@item +Single character +@item +Two characters +Must be prefixed with @samp{(} in some situations. +@item +Arbitrary length (groff only) +Must be bracketed with @samp{[}, @samp{]} in some situations. +Any length identifier can be put in brackets. +@end itemize + +Unlike many other programming languages, undefined identifiers are +silently ignored or expanded to nothing. + + +@c distribute these through the text +@xref{Interpolating Registers} +@c distribute these through the text +@xref{Strings} + +@node Embedded Commands, Registers, Identifiers, Programming Tutorial +@section Embedded Commands +@cindex embedded commands +@cindex commands, embedded + + +With most documents you need more funtionality beyond filling, +adjusting and implicit line breaking. +In order to gain further functionality, groff allows commands to be +embeded into your text, in two ways. + +The first is a @dfn{request} which takes up an entire line, and does +some large scale operation (e.g. break lines, start new pages). + +The other is an @dfn{escape} which can be embedded anywhere +in your text, or even as an argument to a request. (Not always?) +Escapes generally do more minor operations like sub- and super- +scripts, print a symbol, &c. + + + +@menu +* Requests:: +* Macros:: +* Escapes:: +@end menu + +@node Requests, Macros, Embedded Commands, Embedded Commands +@subsection Requests +@cindex requests + + +@cindex control character +@cindex character, control +A request line begins with a control character, +which is either a single quote (@samp{'}) or a period (@samp{.}). +These can be changed @pxref{Character Translations}, for details. +After this there may be optional tabs or spaces followed by an +identifier which is the name of the request. +This may be followed by any number of space separated arguments. + +@findex \& +If you want to begin a line with a control character without it being +interpreted, precede it with a @code{\&}. This represents a zero +width space, which means it will not affect you output. + +In most cases you will use the period as a control character. +Several requests will cause a break, using the single quote control +character will prevent this. + + +@menu +* Request Arguments:: +@end menu + +@node Request Arguments, , Requests, Requests +@subsubsection Request Arguments +@cindex request arguments +@cindex arguments to requests + + +Argument to requests (and macros) are processed much like the shell: +The line is split into arguments according to spaces. +An argument which is intended to contain spaces can either be enclosed +in quotes (single or double), or have the spaces @dfn{escaped} with +backslashes. + +So, for example: + +@example +.uh The Mouse Problem +.uh "The Mouse Problem" +.uh The\ Mouse\ Problem +@end example + +The first line is the @code{.uh} macro being called with 3 arguments, +@samp{The}, @samp{Mouse}, and @samp{Problem}. +The latter two have the same effect or calling the @code{.uh} macro +with one argument @samp{The Mouse Problem}. + +Note, however, that the @code{.ds} request works differently. + +@c distribute these through the text +@xref{Strings} + +@node Macros, Escapes, Requests, Embedded Commands +@subsection Macros +@cindex macros + + +Troff has a @dfn{macro} facility for defining a series of lines which +can be invoked by name. +They are called in the same manner as requests +and arguments may be passed in the same manner. + + +@c distribute these through the text +@xref{Writing Macros} +@c distribute these through the text +@xref{Request Arguments} + +@node Escapes, , Macros, Embedded Commands +@subsection Escapes +@cindex escapes + + +@findex \e +@findex \\ +Escapes may occur anywhere in the input to groff. +They begin with a backslash and are followed by a single character +which indicates the function to be performed. +If you want to have a backslash appear in your document, you should +use the escape sequence @code{\e}. Merely escaping the backslash +with another backslash will work in @emph{some} curcumstances. + +Many escapes have no parameters, those that do, do so in one of two +ways. For escapes which require an identifier there must be a way for +groff to tell where the identifier ends and the text begins. +It assumes that the next single character is the identifier, but if +that character is an open parenthesis, it takes the next two +characters as the identifier; and if the next character is an open +bracket, all characters until a close bracket are taken as the +identifier. Note that in the second case there is no closing +parenthesis. For example: + +@example +\fB +\n(XX +\*[TeX] +@end example + +Other escapes may require several arguments and/or some special +format. In these cases the @dfn{argument} is enclosed in single +quotes (not required??) and the enclosing text is decoded according +to what that escape expects. + +@example +\l'1.5i\(bu' +@end example + +@findex \\ +@findex \e +@findex \E +If you want to have a backslash appear in your output, you can use several +escapes: @code{\\}, @code{\e} or @code{\E}. +These are very similar, and only differ with respect to being used in +macros or diversions (@xref{Copy-in Mode}, and @ref{Diversions}, for +more information) + + + +@c distribute these through the text +@xref{Identifiers} + +@menu +* Comments:: +@end menu + +@node Comments, , Escapes, Escapes +@subsubsection Comments +@cindex comments + + +@findex \" +Probably one of the most@footnote{Unfortunately, this is a lie. But +hopefully future troff hackers will believe it :-)} +common forms of escapes is the comment. +They begin with the @code{\"} escape and end at the end of the input +line. + +This may sound simple, but it can be tricky to keep the comments from +interfering with the apperarance of your final outupt. + +If the escape is to the right of some text or a request, that portion +of the line will be ignored, but the space leading up to it will be +noticed by groff. This only affects the @code{.ds} request (any +others?). + +One possibly irritating idiosyncracy is that you mustn't use tabs to +line up your comments. +Tabs are not treated as white space between request and macro +arguments. + +If you have a comment on a line by itself, it will be treated as a +blank line, because after eliminating the comment, that is all that +remains. So, it is common to start the line with @code{.\"} which +will cause the line to be treated as an undefined request. + +Another commenting scheme seen sometimes is three consecutive single +quotes (@code{'''}) at the begining of a line. This works, but groff +will give a warning about an undefined macro, which is harmless, but +irritating. + +@findex \# +Now to avoid all this groff has a new comment mechanism using the +@code{\#} escape. This escape works the same as @code{\"} except +that the newline is also ignored. + +@findex ig +For large blocks of text, the @code{ig} request may be useful. +@c distribute these through the text +@xref{Strings} + +@node Registers, Manipulating Filling and Adjusting, Embedded Commands, Programming Tutorial +@section Registers +@cindex registers + + +Registers are groff's numeric variables. groff has a number of +builtin registers, supplying anything from the date to details of +formatting parameters. + +@c distribute these through the text +@xref{Identifiers} + +@menu +* Setting Registers:: +* Interpolating Registers:: +* Auto-increment:: +* Assigning Formats:: +* Builtin Registers:: +@end menu + +@node Setting Registers, Interpolating Registers, Registers, Registers +@subsection Setting Registers +@cindex setting registers +@cindex registers, setting + + +@findex nr +@findex \R +Registers are defined/set via the @code{nr} +request or the @code{\R} escape, for example, the following two lines +are equivalent: + +@example +.nr a 1 +\R'a 1' +@end example + +@findex rr +The @code{rr} request will +remove the register specified by the argument. + +@findex rnn +The @code{rnn} request will rename a number register. +The format is @samp{.rnn @var{x} @var{y}}, which will +rename number register @var{x} to @var{y}. + +@findex aln +Aliases can be created for a number register. The format is +@samp{.aln @var{xx} @var{yy}}, which will create an alias @var{xx} for +number register object named @var{yy}. The new name and the old name +will be exactly equivalent. If @var{yy} is undefined, a warning of +type @samp{reg} will be generated, and the request will be ignored. +@xref{Debugging}, for information about warnings. + + +@node Interpolating Registers, Auto-increment, Setting Registers, Registers +@subsection Interpolating Registers +@cindex interpolating registers +@cindex registers, interpolating + + +@findex \n +Numeric registers are @dfn{interpolated} via the @code{\n} escape. +@c the following is wrong. Should I say any more than the above?? +@c This means that the value of the number register in expanded in-place +@c on the input line before any other actions, i.e. before requests and +@c escapes are interpreted. + +@example +.nr as \na+\na +\n(as +@end example + + +@node Auto-increment, Assigning Formats, Interpolating Registers, Registers +@subsection Auto-increment +@cindex auto-increment +@cindex increment, automatic + +Number registers can also be auto incremented/decremented. You can +specify the increment/decrement factor with third argument to the +@code{nr} request. The default value is 0. For example: + +@example +.nr a 0 1 +.nr xx 0 5 +\n+a, \n+a, \n+a, \n+a, \n+a +.br +\n+(xx, \n+(xx, \n+(xx, \n+(xx, \n+(xx +@end example + +Produces: + +@example +1, 2, 3, 4, 5 +5, 10, 15, 20, 25 +@end example + +If you want to change the increment factor without changing the value +of a register, the following can be used. + +@example +.nr a \na 10 +@end example + + +@node Assigning Formats, Builtin Registers, Auto-increment, Registers +@subsection Assigning Formats +@cindex assigning formats +@cindex formats, assigning + + +@findex af +When a register is used in the text of an input file +(as opposed to part of an expression) +it is textually replaced (or interpolated) with a representation of +that number. +This output format can be changed to a variety of formats +(numbers, roman numerals, etc) +This is done using the @code{af} request. +The first argument to @code{af} is the name of the number register to +be changed, +and the second argument is the output format. +The following output formats are available: + +@table @samp +@item 1 +This is the default format, decimal numbers: +1, 2, 3, @dots{} +@item 001 +Decimal numbers with as many leading zeros as specified. +So, @samp{001} would result in 001, 002, 003, @dots{} +@item I +@cindex roman numerals +@cindex numerals, roman +Upper-case roman numerals: +0, I, II, III, IV, @dots{} +@item i +Lower-case roman numerals: +0, i, ii, iii, iv, @dots{} +@item A +Upper-case letters: +A, B, C, @dots{}, Z, AA, AB, @dots{} +@item a +Lower-case letters: +a, b, c, @dots{}, z, aa, ab, @dots{} +@end table + +The following example will produce @samp{10, X, j, 010}. + +@example +.nr a 10 +.af a 1 \" the default format +\na, +.af a I +\na, +.af a a +\na, +.af a 001 +\na +@end example + +@findex \g +The @code{\g} escape returns the current format of the specified +register. For example, @samp{\ga} after the following example would +produce @samp{001}. + + + +@node Builtin Registers, , Assigning Formats, Registers +@subsection Builtin Registers +@cindex builtin registers +@cindex registers, builtin + + +The following are some builtin registers, which are not listed +elsewhere in this manual. Any registers which begin with a @samp{.} +are read-only. A compleat listing of all builtin registers can be +found in @ref{Register Index}. + +@table @code +@item .H +@vindex .H +Horizontal resolution in basic units. +@item .V +@vindex .V +Vertical resolution in basic units. +@item dw +@vindex dw +Day of the week (1-7). +@item dy +@vindex dy +Day of the year (1-31). +@item mo +@vindex mo +Current month (1-12). +@item yr +@vindex yr +Last two digits of the current year (see you in 7 years :-) +@item .c +@vindex .c +@itemx c. +@vindex c. +The current @emph{input} line number. +@item ln +@vindex ln +The current @emph{output} line number. +@item .x +@vindex .x +The major version number. For example, if the version number is 1.03 +then @code{.x} will contain 1. +@item .y +@vindex .y +The minor version number. For example, if the version number is 1.03 +then @code{.y} will contain 03. +@item .g +@vindex .g +Always 1. +Macros should use this to determine whether they are running +under GNU troff. +@item .A +@vindex .A +If the current output device is ascii, this is set to 1, +zero otherwise. +@item .P +@vindex .P +This register indicates whether the current page is actualy being +printed, i.e. if the @samp{-o} option is being used to only print +selected pages. +@xref{Options}, for more information. +@end table + +@node Manipulating Filling and Adjusting, Manipulating Hyphenation, Registers, Programming Tutorial +@section Manipulating Filling and Adjusting +@cindex manipulating filling and adjusting +@cindex filling and adjusting, manipulating +@cindex adjusting and filling, manipulating + + +@findex br +@cindex break +@cindex line break +Several ways of causing @dfn{breaks} were given in +@ref{Implicit Line Breaks}. +The @code{br} request will likewise cause a break. +Several other requests will also cause breaks, implicitly. +They are +@code{bp}, +@code{ce}, +@code{fi}, +@code{fl}, +@code{in}, +@code{nf}, +@code{sp} and +@code{ti}. + +@findex nf +@findex fi +@vindex .u +Initially, groff will fill and ajust text to both margins. +Filling can be disabled via the @code{nf} request +and re-enabled with the @code{fi} request. +These implicitly disable and re-enable adjusting. +Both of these will cause break in text currently being filled. +The number register @code{.u} is equal to 1 in fill mode and 0 in +no-fill mode. + +@findex ad +@findex na +@vindex .j +Adjusting can be disabled with the @code{ad} request and re-enabled +with the @code{na} request. +The @code{ad} request takes a single argument to indicate how to +adjust text. +The current adjustment mode is available in the number register +@code{.j}. + +@table @samp +@item l +@cindex ragged-right +Adjust text to the left margin. This produces what is traditionally +called ragged-right text. +@item r +Adjust text to the right margin. +@item c +Center filled text. +@item b +@itemx n +Justify to both margins. This is groff's default. +@end table + +With no argument to @code{ad}, troff will adjust lines the same way +it was the last time it was filling. For example: + +@example +text +.ad r +text +.ad c +text +.na +text +.ad \" back to centering +text +@end example + +@findex \p +The escape @code{\p} will cause a break and cause the remaining text +to be adjusted. + +@findex ss +The @code{ss} request allows you to change the minimum size of a +space between filled words. +This request takes it's units as one twelfth of the +spacewidth parameter for the current font. Initially both the word +space size and the sentence space size are 12. + +When two arguments are given to the @code{ss} request, the second argument +gives the sentence space size. If the second argument is not given, the +sentence space size will be the same as the word space size. +The sentence space size +is used in two circumstances: if the end of a sentence occurs at the end +of a line in fill mode, then both an inter-word space and a sentence +space will be added; if two spaces follow the end of a sentence in the +middle of a line, then the second space will be a sentence space. Note +that the behaviour of @sc{Unix} troff will be exactly that exhibited by GNU +troff if a second argument is never given to the @code{ss} request. In GNU +troff, as in @sc{Unix} troff, you should always follow a sentence with either +a newline or two spaces. + +@vindex .ss +@vindex .sss +The number registers @code{.ss} and @code{.sss} are +the values of the parameters set by the first and second +arguments of the @code{ss} request. + +@findex ce +The @code{ce} request will center text. +While the @samp{ad c} request will also center text, it has the side +effect of filling the text. The @code{.ce} request will not fill the +text it affects. +This request causes a break. + +With no arguments, @code{ce} will fill the next line of text. +The single argument @code{ce} takes is a number indicating the +number of lines to be centered. With no argument centering is +disabled. + +A common idiom is to turn on centering for a large number of lines, +and then turn off centering when you are done with the centered text. +This is useful for any request which takes a number of lines as an +argument. + +@example +.ce 1000 +replace this +with +something +more interesting +@dots{} +.ce 0 +@end example + +@vindex .ce +The @code{.ce} number register contains the number of lines remaining +to be centered, as set by the @code{ce} request. + + +@findex rj +@vindex .rj +A similar request is @code{rj} request which will justify unfilled +text to the right margin. Its arguments are identical to the +@code{ce} request. +The @code{.rj} number register is +the number of lines to be right-justified as set by the @code{rj} +request. + + + +@node Manipulating Hyphenation, Manipulating Spacing, Manipulating Filling and Adjusting, Programming Tutorial +@section Manipulating Hyphenation +@cindex manipulating hyphenation +@cindex hyphenation, manipulating + + +As discussed in @ref{Hyphenation}, groff will hyphenate words. +There are a number of ways to modify the how hyphenation is done. + +@findex nh +@findex hy +@vindex .hy +This hyphenation can be turned off with the @code{nh} request, and +turned back on with the @code{hy} request. However, troff's +hyphenation facilities are far more flexible than this. The @code{hy} +request can be used to tell troff to restrict hypenation to certain +cases. The request takes a single numeric argument. +The current hyphenation restrictions can be found in the number +register @code{.hy} + +@table @samp +@item 1 +The default argument, which +indicates to hyphenate without restrictions. +@item 2 +Do not hyphenate the last word on a page or column. +@item 4 +Do not hyphenate the last two characters of a word. +@item 8 +Do not hyphenate the first two characters of a word. +@end table + +@findex hlm +@vindex .hlc +@vindex .hlm +The @code{hlm} request will +set the maximum number of consecutive hyphenated lines to the value +given as the first argument. +If this number is +negative, there is no maximum. The default value is -1. +This value is +associated with the current environment. Only lines output from an +environment count towards the maximum associated with that environment. +Hyphens resulting from @code{\%} are counted; explicit hyphens are not. +The current setting of this is available in the @code{.hlm} request. +Also the number of immediately preceding consecutive hyphenated lines +are available in the number register @code{.hlc}. + +@findex hw +The @code{hw} request allows you to specify how a specific word is +to be hyphenated. It takes only one argument which is the word with +hyphens at the hyphenation points. For example: +@samp{.hw in-sa-lub-rious}. +@c In old versions of troff there was a +@c limited amount of space to store such information, fortunately, +@c with groff, this is no longer a restriction. + +@findex \% +@cindex hyphenation character +@cindex character, hyphenation +You can also tell troff how to hyphenate words on the fly with the +use of the @code{\%} escape, also known as the @dfn{hyphenation +character}. Preceding a word with this character will prevent it +from being hyphenated, putting it in a word will indicate to troff +that the word may be hyphenated at that point. Note that this +mechanism will only affect one word, if you want to change the +hyphenation of a word for the entire document, use the @code{hw} +request. + +@findex hc +The @code{hc} request allows you to change the hyphenation character. +The character specified as an argument will then work the same as the +@code{\%} escape, and, thus, no longer appear in the output. Without +an argument it will return the hyphenation character to @code{\%}. + +@findex hpf +To further customize hyphenation the @code{hpf} request will read in +a file of hyphenation patterns. +This file will be searched for in the +same way that @file{tmac.@var{name}} is searched for when the +@samp{-m@var{name}} option is specified. + +It should have the same format as the argument to the +\patterns primitive in @TeX{}; the letters appearing in this file are +interpreted as hyphenation codes. +A @samp{%} character in the patterns file +introduces a comment that continues to the end of the line. + +@findex hla +@findex hpf +@pindex troffrc +The set of +hyphenation patterns is associated with the current language set by the +@code{hla} request. The @code{hpf} request is usually invoked by the +@file{troffrc} file. + +@findex hcode +@code{.hcode @var{c1 code1 c2 code2...}} +Set the hyphenation code of character @var{c1} to code1 and that of +@var{c2} to @var{code2}. +A hyphenation code must be a single input character (not a +special character) other than a digit or a space. Initially each +lower-case letter has a hyphenation code, which is itself, and each +upper-case letter has a hyphenation code which is the lower case +version of itself. + +@findex hym +@vindex .hym +The @code{hym} request will set the hyphenation margin to the value +given as the first argument: when the current adjustment mode is not +@samp{b}, the line will not be hyphenated if the line is no more than +that amount short. +The default hyphenation margin is 0. The default scaling +indicator for this request is m. The hyphenation margin is associated +with the current environment. The current hyphenation margin is +available in the @code{.hym} register. + +@findex hys +@vindex .hys +The @code{hys} request set the hyphenation space to the value given as +the first argument: when the current adjustment mode is b, don't +hyphenate the line if the line can be justified by adding no more than +that amount of extra space to each word space. The default +hyphenation space is 0. The default scaling indicator for this +request is m. The hyphenation space is associated with the current +environment. The current hyphenation space is available in the +@code{.hys} register. + +@findex shc +The @code{shc} request will set the soft hyphen character to the +argument given as an argument. If the argument is omitted, the soft +hyphen character will be set to the default @code{\(hy}. The soft +hyphen character is the character which will be inserted when a word +is hyphenated at a line break. If the soft hyphen character does not +exist in the font of the character immediately preceding a potential +break point, then the line will not be broken at that point. Neither +definitions (specified with the @code{char} request) nor translations +(specified with the @code{tr} request) are considered when finding the soft +hyphen character. + +@findex hla +@vindex .hla +@pindex troffrc +The @code{hla} request will set the current hyphenation language to +that given by the first argument. Hyphenation exceptions specified +with the @code{hw} request and hyphenation patterns specified with the +@code{hpf} request are both associated with the current hyphenation +language. The @code{hla} request is usually invoked by the +@file{troffrc} file. The current hyphenation language is available +in the number register @code{.hla}. + + + +@node Manipulating Spacing, Tabs and Fields, Manipulating Hyphenation, Programming Tutorial +@section Manipulating Spacing +@cindex manipulating spacing +@cindex spacing, manipulating + + +@findex sp +The @code{sp} request will cause troff to space downwards the +distance specified as the first argument. With no argument it will +advance 1 line. +A negative argument will cause troff to move up the page the +specified distance. +If the argument is preceded by a @samp{|} troff will move that +distance from the top of the page. + +@findex ls +@vindex .L +Often you may want your output to be double or triple spaced. +The @code{ls} request will cause troff to output @var{n}-1 blank +lines after each line of text, where @var{n} is the argument given to +the @code{ls} request. With no argument troff will go back to single +spacing. The number register @code{.L} contains the current line +spacing setting. + +@findex \x +@vindex .a +Sometimes, extra vertical spacing is only needed occasionaly, +i.e. to allow space for a tall construct (like an equation). +The @code{\x} escape will do this. +The escape is given a numerical argument (like @samp{\x'3p'}). +If this number is positive extra vertical space will be inserted +below the current line. A negative number will add space above. +If this escape is used multiple times on the same line, the maximum +values are used. +The @code{.a} number register contains the most recent +extra vertical @strong{emph} line space. + +@example +... example of inline equation ... +@end example + +@findex ns +@findex rs +@cindex no-space mode +@cindex mode, no-space +Spacing (via either @code{sp} or via blank lines) can be disabled +with the @code{ns} request. This will enable @dfn{no-space mode}. +This mode will end when actual text is output or the @code{rs} +request is encountered. No-space mode will also prevent requests to +advance to the next page unless they are accompanied by a page number +(@pxref{Page Control}, for more information.) + + +@node Tabs and Fields, Character Translations, Manipulating Spacing, Programming Tutorial +@section Tabs and Fields +@cindex tabs and fields +@cindex fields and tabs + + +@findex \t +Tab stops are much like those on a typewriter: a tab character (or the +@code{\t} escape) on input will cause horizontal motion to the next +tab stop. + +@findex ta +Tab stops can be changed with the @code{ta} request. +This request takes a series of numbers as arguments which indicate +where each tab stop is to be (overriding any previous settings). +These can be specified absolutely, +i.e. as the distance from the left margin. +For example, the following wil set tab stops every one inch. + +@example +.ta 1i 2i 3i 4i 5i 6i +@end example + +Tab stops can also be specified relatively (using a leading @samp{+}) +which means that the specified tab stop will be set that distance +from the previous tab stop. For example the following is equivalent +to the previous example. + +@example +.ta 1i +1i +1i +1i +1i +1i +@end example + +After the specified tab stops repeat values may be set for tabs beyond +the last one specified. This is most commonly used to specify tabs +set at equal intervals. The compleat syntax for setting tabs is +@code{ta @var{n1} @var{n2} @dots{} @var{nn} T @var{r1} @var{r2} +@dots{} @var{rn}} This will set tabs at positions @var{n1}, @var{n2}, +@dots{}, @var{nn} and then set tabs at @var{nn}+@var{r1}, +@var{nn}+@var{r2}, @dots{}, @var{nn}+@var{rn} and then at +@var{nn}+@var{rn}+@var{r1}, @var{nn}+@var{rn}+@var{r2}, @dots{}, +@var{nn}+@var{rn}+@var{rn}, and so on. For example the following is, +yet again, the same as the previous examples. + +@example +.ta T 1i +@end example + +The material in each tab column may be justified to the right or left +or centered in the column. This is specified by appending an +@samp{R}, @samp{L} or @samp{C} to the number specifying that tab stop. +The default justification is @samp{L}. + +@example +.ta 1i 2iC 2iR +@end example + +@vindex .tabs +The number register @code{.tabs} contains +a string representation of the current tab settings suitable for use as +an argument to the @code{ta} request. + +@findex tc +Normally troff will fill the space to the next tab stop with spaces. +In some cases you may wish to change this. The @code{tc} request +will do this. With no argument troff will revert to using spaces. + +@subsection Leaders +@cindex leaders + +@findex lc +Sometimes you may wish to use the @code{tc} request to fill a tab +stop with a given character, but also, you want to use normal tab +stops on the rest of the line. For this groff provides an alternate +tab mechanism, called @dfn{leaders} which will do just that. +They are used exclusively to produce a repeated run of characters to +the next tab stop. + +You can declare what character will be repeated with the @code{lc} +request. If you do not give it an argument, the leaders will act the +same as tabs. + +@findex \a +The difference is that a leader is invoked by using the @code{\a} +escape. + +@cindex table of contents +@cindex contents, table of +So for a table of contents you may want to have tab stops defined so +that the section number is one tab stop, the title is the second with +the remaining space being filled with a line of dots and then the +page number slightly separated from the dots. + +@example +.lc . +.ta .5iR 5i +.25i +1.1\tFoo\a\t12 +@end example + +@subsection Fields +@cindex fields + +@findex fc +Fields are a more general way of laying out tabular data. +@code{fc} + +@node Character Translations, Line Layout, Tabs and Fields, Programming Tutorial +@section Character Translations +@cindex character translations +@cindex translations of characters + + +@findex cc +@findex c2 +The control character (@samp{.}) and the no-break control character +(@samp{'}) can be changed with the @code{cc} and @code{c2} requests, +respectively. +The single argument is the new character to be used, with no argument +the normal control character is restored. + +@findex ec +@findex eo +The @code{eo} request will compleatly disable the escape mechanism. +The @code{ec} request can be used to change the escape character from +the default @samp{\} to what is specified as an argument. + +@findex tr +The @code{tr} request will translate characters. + +@findex trnt +@findex \! +@code{trnt} +This is the same as the @code{tr} request except that the +translations do not +apply to text that is transparently throughput into a diversion with +@code{\!}. @xref{Diversions}, for more information. +For example, + +@example +.tr ab +.di x +\!.tm a +.di +.x +@end example + +will print @samp{b}; if @code{trnt} is used instead of @code{tr} it +will print @samp{a}. + + +@node Line Layout, Page Layout, Character Translations, Programming Tutorial +@section Line Layout +@cindex line layout +@cindex layout, line + + +@cindex dimensions, line +@cindex line dimensions +The following drawing shows the dimensions which troff uses for +placing a line of output onto the page. They are labeled with the +request which manipulates that dimension. + +@example +@group + | -->| in |<-- | + -->| po |<-----------ll------------>| + +----+----+----------------------+----+ + | : : : | + +----+----+----------------------+----+ +@end group +@end example + +These dimensions are: + +@ftable @code +@item po +@vindex .o +@dfn{Page offset}--This is the leftmost postition of text on the final +output. This can be adjusted with the @code{po} request, and the +current setting can be found in the builtin number register @code{.o} +Note, that this request does not cause a break, so changing the page +offset in the middle of text being filled may not do what you expect. +@item in +@vindex .i +@dfn{Indentation}--This is the distance from the left margin where text +will be printed. This can be adjusted with the @code{in} request, and +the current setting can be found in the builtin number register. +@code{.i} +This request causes a break. + +@findex ti +@findex .in +There is also the request @code{ti} which will cause one output line +to be indented, after which the indentation returns to 0. +This request causes a break. +The number register @code{.in} is the indent that applies to the +current output line. +@item ll +@findex .l +@findex .ll +@dfn{Line length}--This is the distance from the left margin to right +margin. This can be adjusted with the @code{.ll} request, and the +current setting can be found in the builtin number register @code{.l} +Note, as the figure implies, line length is not affected by the current +indentation. +The number register @code{.ll} is +the line length that applies to the current output line. +@end ftable + +@example +.in +.5i +.ll -.5i +A bunch of really boring text which should +be indented from both margins. +replace me with a better (and more) example! +.in -.5i +.ll +.5i +@end example + + +@node Page Layout, Page Control, Line Layout, Programming Tutorial +@section Page Layout +@cindex page layout +@cindex layout, page + + +Troff provides some very primitive operations for controlling page +layout. + +@findex pl +@vindex .p +Troff lets you specify the @dfn{page length} via the @code{pl} request. +This is the length of the physical output page. +The current setting can +be found in the builtin number register @code{.p}. Note that this only +specifies the size of the page, not the not the top and bottom margins. +Those are not done by groff directly, @xref{Traps}, for further +information on how to do this. + +@cindex headers +@cindex footers +@cindex titles +Troff provides several operations which help in setting up top and +bottom titles (or headers and footers) + +@findex tl +The @code{tl} request will print a @dfn{title line}, which consists +of three parts: a left justified portion, a centered portion and a +right justified portion. The argument to @code{tl} is specified as +@code{'@var{left}'@var{center}'@var{right}'} +The @samp{%} character is replaced with the current page number. + +@findex lt +@vindex .lt +The title line is printed using its own line length, which is +specified with the @code{lt} request. The current setting of this is +available in the @code{.lt} number register. + +@findex pn +The @code{pn} request will change the page number of the @emph{next} +page. The only argument is the page number. + +@vindex % +@vindex .pn +The current page number is stored in the number register @code{%}. +The number register @code{.pn} contains the +number of the next page: +either the value set by a @code{pn} request, or +the number of the current page plus 1. + +@findex pc +The @code{pc} request will change the page number character (used by +the @code{tl} request) to a different character. With no argument, +this mechanism is disabled. + + +@c distribute these through the text +@xref{Traps} + +@node Page Control, Fonts, Page Layout, Programming Tutorial +@section Page Control +@cindex page control +@cindex control, page + + +@findex bp +To stop processing the current page, and move to the next page, you +can invoke the @code{bp} request. This request will also cause a +break. This request can also take an argument of what the next page +should be numbered. +The only difference +between @code{bp} and @code{pn} is that @code{pn} does not cause a +break or actually eject a page. + +@example +.de newpage +'bp +'sp .5i +.tl 'left top'center top'right top' +'sp .3i +.. +@end example + +@cindex orphan +@findex ne +Often you may want to make sure that you have a certain amount of +space before a new page occurs. This is most useful to make sure +that there is not a single @dfn{orphan} line left at the bottom of a +page. The @code{ne} request will ensure that there is a certain +distance, specified by the first argument, before the next page is +triggered (@pxref{Traps}, for further information). +The default unit for @code{ne} is v's and the default argument +is 1v. + +For example, to make sure that no fewer than 2 lines get orphaned, +you can do the following before each paragraph. + +@example +.ne 2 +.ti +5n +text +@end example + +@findex sv +@findex os +The @code{sv} is similar to the @code{ne} request, it reserves the +specified amount of vertical space. If the desired amount of space +exists before the next trap (bottom page boundary), the space will be +output immediately. If there is not enough space, it is stored for +later output via the @code{os} request. +The default argument is 1v and the default units are v's. + + +@node Fonts, Sizes, Page Control, Programming Tutorial +@section Fonts +@cindex fonts + + +@findex ft +@findex \f +Groff gives you the ability to switch fonts at any point in your +text. There are two ways to do this, via the @code{ft} request and +the @code{\f} escape. + +Fonts are generaly specified as uppercase strings, which are usually +1 to 4 characters representing an abreviation of acronym of the font +name. + +The basic set of fonts are R, I, B, and BI. These are Times Roman, +Italic, Bold, and Bold Italic. There is also at least one symbol +font which contains various special symbols (greek, mathematics). +These latter fonts cannot be used directly, but should be used via an +escape. + + +@menu +* Changing Fonts:: +* Font Families:: +* Font Positions:: +* Using Symbols:: +* Artificial Fonts:: +* Ligatures and Kerning:: +@end menu + +@node Changing Fonts, Font Families, Fonts, Fonts +@subsection Changing Fonts +@cindex changing fonts +@cindex fonts, changing + + +@findex ft +You can change fonts with both the @code{ft} request. +With no arguments it +will switch to the previous font (also known as P). + +@example +eggs, bacon, +.ft B +spam +.ft +and sausage. +@end example + +@findex \f +The @code{\f} escape is useful for changing fonts in the middle of words + +@example +eggs, bacon, \fBspam\fP and sausage. +@end example + +Both of the above examples will produce the same output. + +Sometimes when putting letters of different fonts, you need more or +less space at such boundaries. There are two escapes to help with +this. + +@findex \/ +The @code{\/} escape +increases the width of the preceding character so that the spacing +between that character and the following character will be correct if +the following character is a roman character. For example, if an italic +f is immediately followed by a roman right parenthesis, then in many +fonts the top right portion of the f will overlap the top left of the +right parenthesis. +It is a good idea to use this escape sequence +whenever an italic character is immediately followed by a roman +character without any intervening space. + +@c producing @i{f}), which is ugly. Inserting \/ produces f) and avoids this problem. + +@findex \, +The @code{\,} escape +modifies the spacing of the following character so that the spacing +between that character and the preceding character will correct if the +preceding character is a roman character. +It is a good idea +to use this escape sequence whenever a roman character is immediately +followed by an italic character without any intervening space. + +@c For example, inserting \, between the parenthesis and the f changes (f to (f. + +@findex ftr +The @code{ftr} request will translate fonts, it is called as +@samp{.ftr @var{F G}}, which +Translate font @var{F} to @var{G}. +Whenever a font named @var{F} is referred to in @code{\f} +escape sequence, +or in the @code{ft}, @var{ul}, @var{bd}, @var{cs}, @var{tkf}, +@var{special}, @var{fspecial}, @var{fp}, +or @var{sty} requests, font @var{G} will be used. If @var{G} is +missing, or equal to @var{F} then font @var{F} will not be translated. + + +@node Font Families, Font Positions, Changing Fonts, Fonts +@subsection Font Families +@cindex font families +@cindex families, font + + +Due to the variety of fonts available, groff has added the concept of +font families. Each of these families has four styles (R, I, B and BI), + +The fonts are specified as the concatenation of the font family and +style. Specifying a font without the family part will cause groff to +use that style of the current family. +By default, groff uses the Times family. + +This way, you can just use the basic four fonts and select a +different font family on the command line. + +@findex fam +@vindex .fam +You can also switch font families with the @code{fam} request +The current font family is available in the number register +@code{.fam}. +This is a string-valued register. + +@example +spam, +.fam H +spam, +.ft B +spam, +.fam T +spam, +.ft AR +baked beans, +.ft R +and spam. +@end example + + + +@node Font Positions, Using Symbols, Font Families, Fonts +@subsection Font Positions +@cindex font positions +@cindex positions, font + + +For the sake of old phototypesetters and compatability with old +versions of troff, groff has the concept of font +@dfn{positions}, on which various fonts are mounted. +The last one or two are reserved for the symbol font(s). + +@findex fp +New fonts can be mounted with the @code{fp} request. +These numeric positions can then be referred to with font changing commands. +When groff starts it is using font number one. + +@example +.fp 1 H +.fp 2 HI +.fp 3 HB +wink, wink, +.ft 2 +nudge, nudge, +.ft +.ft 3 +say no more! +.ft +@end example + +(note that after these font changes have taken place the original +font is restored.) + +@vindex .f +The current font in use, as a font position. +This can be useful to remember the current font, for later recall. + +@example +.nr save-font \n(.f +... lots 'o text ... +.ft \n[save-font] +@end example + +@vindex .fp +The number of the next free font position is available in the number +register @code{.fp}. This is useful when mounting a new font, like so: + +@example +.fp \n[.fp] NEATOFONT +@end example + +@pindex DESC +Fonts not listed in the @file{DESC} file are automatically mounted on +the next available font position when they are referenced. +If a font is to be +mountfed explicitly with the @code{fp} request on an unused font position, it +should be mounted on the first unused font position, which can be found +in the @code{.fp} register; although troff does not enforce this strictly, +it will not allow a font to be mounted at a position whose number is +much greater than that of any currently used position. + +The @code{fp} request has an optional third argument. +This argument gives the +external name of the font, which is used for finding the font +description file. The second argument gives the internal name of the +font which is used to refer to the font in troff after it has been +mounted. If there is no third argument then the internal name will be +used as the external name. This feature allows you to use fonts with +long names in compatibility mode. + + + +@node Using Symbols, Artificial Fonts, Font Positions, Fonts +@subsection Using Symbols +@cindex using symbols +@cindex symbols, using + + +@findex \( +@findex \[ +Symbols can be inserted by using a special escape sequence. +This escape is simply the escape character (a backslash) followed by +an identifier. The symbol identifiers have to be two or more +characters, since single characters conflict with all the other +escapes. The identifier can be either preceded by a parenthesis if +it is two character, or surrounded by square brackets. +So, the symbol for pi can be produced either by @code{\(*p} or +@code{\[*p]}. + +@example +area = \(*p\fIr\fP\u2\d +@end example + +@findex \C +The escape @code{\C'@var{xxx}'} will typeset character named +@var{xxx}. Normally it is more convenient to use @code{\[@var{xxx}]}. +But @code{\C} has the advantage that it is compatible with recent +versions of ditroff and is available in compatibility mode. + +@findex \N +The escape @code{\N'@var{n}'} will typeset the character with code +@var{n} in the current font. @var{n} can be any integer. Most devices only +have characters with codes between 0 and 255. If the current font +does not contain a character with that code, special fonts will not be +searched. The @code{\N} escape sequence can be conveniently used on +conjunction with the @code{char} request: + +@example +.char \[phone] \f(ZD\N'37' +@end example + +The code of each character is given in the fourth column in the font +description file after the charset command. It is possible to include +unnamed characters in the font description file by using a name of +@samp{---}; the @code{\N} escape sequence is the only way to use these. + +@findex cflags +Each character has certain properties associated with it. +These properties can be modified with the @code{cflags} request. +The first argument is the the sum of the desired flags and the +remaining arguments are the characters to have those properties. +@table @code +@item 1 +the character ends sentences (initially characters @samp{.?!} have this +property); +@item 2 +lines can be broken before the character (initially no characters have +this property); +@item 4 +lines can be broken after the character (initially characters +@samp{-\(hy\(em} have this property); +@item 8 +the character overlaps horizontally (initially characters +@samp{\(ul\(rn\(ru} have this property); +@item 16 +the character overlaps vertically (initially character @samp{\(br} has +this property); +@item 32 +an end of sentence character followed by any number of characters with +this property will be treated as the end of a sentence if followed by a +newline or two spaces; in other words the character is transparent for +the purposes of end of sentence recognition; this is the same as having +a zero space factor in @TeX{} (initially characters +@samp{"')]*\(dg\(rq} have this property). +@end table + +@findex char +You can create new characters with the @code{char} request. It is +called as @samp{.char @var{c} @var{string}} Define character @var{c} +to be @var{string}. Every time character @var{c} needs to be printed, +@var{string} will be processed in a temporary environment and the +result will be wrapped up into a single object. Compatibility mode +will be turned off and the escape character will be set to \ while +@var{string} is being processed. Any emboldening, constant spacing or +track kerning will be applied to this object rather than to individual +characters in @var{string}. A character defined by this request can +be used just like a normal character provided by the output device. +In particular other characters can be translated to it with the +@code{tr} request; it can be made the leader character by the +@code{lc} request; repeated patterns can be drawn with the character +using the @code{\l} and @code{\L} escape sequences; words containing +the character can be hyphenated correctly, if the @code{hcode} request +is used to give the character a hyphenation code. There is a special +anti-recursion feature: use of character within the character's +definition will be handled like normal characters not defined with +@code{char}. + +@findex rchar +A character definition can be removed with the @code{rchar} request. Its +arguments are the characters to be removed. This undoes the effect of +a @code{char} request. + +@c distribute these through the text +@xref{Special Characters} + +@node Artificial Fonts, Ligatures and Kerning, Using Symbols, Fonts +@subsection Artificial Fonts +@cindex artificial fonts +@cindex fonts, artificial + + +There are a number of requests for artificially creating fonts. +These are largely vestigal remains from the days when output devices +did not have a wide variety of fonts, and when nroff and troff were +separate programs. +These are no longer necessary in GNU Troff. + +@findex ul +The @code{ul} request will print subsequent lines in italics on a +device capable of it, or underline the text on an ascii output device. +The single argument is the number of lines to be ``underlined,'' +with no argument, the next line will be underlined. + +@findex cu +The @code{cu} request is similar to @code{ul} ... + +@findex uf +The @code{uf} request will set the underline font used by @code{ul} +and @code{cu}. + +@findex bd +The @code{bd} request artificially creates a bold font by printing +each character twice, slightly offset. +The first argument specifies the font to embolden, and the second is +the number of basic units, minus one, by which the two characters +will be offset. If the second argument is missing, emboldening will +be turned off. + + +@node Ligatures and Kerning, , Artificial Fonts, Fonts +@subsection Ligatures and Kerning +@cindex ligatures and kerning +@cindex kerning and ligatures + + +@findex lg +@vindex .lg +@code{lg} +@code{.lg} +The current ligature mode. + +What is kerning?? + +If the font description file contains pairwise kerning information, +characters from that font will be kerned. Kerning between two +characters can be inhibited by placing a @code{\&} between them. + +@findex kern +@vindex .kern +@code{kern} +If n is non-zero or missing, enable pairwise kerning, otherwise disable +it. +@code{.kern} +1 if pairwise kerning is enabled, 0 otherwise. + +@findex tkf +.tkf f s1 n1 s2 n2 +Enable track kerning for font f. When the current font is f the width +of every character will be increased by an amount between n1 and n2; +when the current point size is less than or equal to s1 the width will +be increased by n1; when it is greater than or equal to s2 the width +will be increased by n2; when the point size is greater than or equal to +s1 and less than or equal to s2 the increase in width is a linear +function of the point size. + + +@node Sizes, Strings, Fonts, Programming Tutorial +@section Sizes +@cindex sizes + + +@cindex baseline +Groff uses two dimensions with each line of text, type size and +vertical spacing. The type size is the height from the text +@dfn{baseline} to the top of the tallest character (decenders may drop +below this baseline). Vertical spacing is the amount of space groff +allows for a line of text, normally, this is about 20% larger than the +current type size. Ratios smaller than this can result in +hard-to-read text, larger that this, it will spread your text out more +vertically (useful for term papers). By default, troff uses 10 point +type on 12 point spacing. + +@cindex leading +The difference between type size and vertical spacing is known, by +typesetters, as @dfn{leading}. + + +@menu +* Changing Type Sizes:: +* Fractional Type Sizes:: +@end menu + +@node Changing Type Sizes, Fractional Type Sizes, Sizes, Sizes +@subsection Changing Type Sizes +@cindex changing type sizes +@cindex type sizes, changing + + +@findex ps +@findex vs +@findex \s +@vindex .s +@vindex .v +Using the @code{ps} request and the @code{\s} escape you can change +the type size. The @code{vs} request will change the vertical +spacing. The default unit for the @code{ps} and @code{vs} requests are +points. +The number registers @code{.s} and @code{.v} contain the current +type size and vertical spacing. + +These requests take parameters in units of points. You can specify +sizes as an absolute size, or as a relative change from the current +size. The size 0 means go back to the previous size. With no +argument it will revert to the previous size. + +@example +snap, snap, +.ps +2 +grin, grin, +.ps +2 +wink, wink, \s+2nudge, nudge,\s+8 say no more! +.ps 10 +@end example + +The @code{\s} escape may be called in a variety of ways. +Much like other escapes there must be a way to determine where the +argument ends and the text begins. +Any of the following forms are valid: +@code{\s@var{n}}, +@code{\s+@var{n}}, +@code{\s-@var{n}}, +@code{\s(@var{nn}}, +@code{\s+(@var{nn}}, +@code{\s-(@var{nn}}, +@code{\s[+@var{nnn}]}, +@code{\s[-@var{nnn}]}, +@code{\s+[@var{nnn}]}, +@code{\s-[@var{nnn}]}. + +Some devices may only have certain permissible sizes, in which case +groff will round to the nearest permissible size. + +@example +... .sz macro example?? ... +@end example + +@node Fractional Type Sizes, , Changing Type Sizes, Sizes +@subsection Fractional Type Sizes +@cindex fractional type sizes +@cindex type sizes, fractional + + +A @dfn{scaled point} is equal to 1/@var{sizescale} points, where +@var{sizescale} is specified in the @file{DESC} file (1 by default.) +There is a new scale indicator @samp{z} which has the effect of +multiplying by @var{sizescale}. Requests and escape sequences in +troff interpret arguments that represent a pointsize as being in units +of scaled points, but they evaluate each such argument using a default +scale indicator of @samp{z}. Arguments treated in this way are the +argument to the @code{ps} request, the third argument to the @code{cs} +request, the second and fourth arguments to the @code{tkf} request, +the argument to the @code{\H} escape sequence, and those variants of +the @code{\s} escape sequence that take a numeric expression as their +argument. + +For example, suppose @var{sizescale} is 1000; then a scaled point will be +equivalent to a millipoint; the request @samp{.ps 10.25} is equivalent to +@samp{.ps 10.25z} and so sets the pointsize to 10250 scaled points, which is +equal to 10.25 points. + +The number register @code{\n(.s} returns the pointsize in points as +decimal fraction. There is also a new number register @code{\n[.ps]} +that returns the pointsize in scaled points. + +It would make no sense to use the @samp{z} scale indicator in a +numeric expression whose default scale indicator was neither @samp{u} +nor @samp{z}, and so troff disallows this. Similarily it would make +no sense to use a scaling indicator other than @samp{z} or @samp{u} in a +numeric expression whose default scale indicator was @samp{z}, and so +troff disallows this as well. + +There is also new scale indicator @samp{s} which multiplies by the +number of units in a scaled point. So, for example, @samp{\n[.ps]s} +is equal to 1m. Be sure not to confuse the @samp{s} and @samp{z} +scale indicators. + +@code{\s'+@var{n}'} +@code{\s'-@var{n}'} +@code{\s+'@var{n}'} +@code{\s-'@var{n}'} +Set the point size to @var{n} scaled points; @var{n} is a numeric +expression with a default scale indicator of @samp{z}. + +@code{\n[.ps]} +The current pointsize in scaled points. + +@code{\n[.psr]} +The last-requested pointsize in scaled points. + +@code{\n[.sr]} +The last requested pointsize in points as a decimal fraction. This is a +string-valued register. + + +@c distribute these through the text +@xref{Font Files} + +@node Strings, Conditionals and Loops, Sizes, Programming Tutorial +@section Strings +@cindex strings + + +@findex ds +Groff has string variables, which are entirely for user convenience +(i.e. there are no builtin strings) They are defined via the +@code{ds} request. + +@example +.ds UX \s-1UNIX\s0\u\s-3tm\s0\d +@end example + +@findex \* +The are interpolated, or expanded in-place, via the @code{\*} escape: + +@example +The \*(UX Operating System +@end example + +Will produce: + +@example +The UNIXtm Operating System +@end example + +If the string named by the @code{\*} does not exist, the escape will +be replaced by nothing. + +@cindex comments, with @code{ds} +NOTE: Unlike other requests the third argument takes up the entire +line including trailing spaces. This means that comments on a line +with such a request can introduce unwanted space into a string. + +@example +.ds UX \s-1UNIX\s0\u\s-3tm\s0\d \" trademark of you-know-who +@end example + +Instead you should either put the comment on another line or +have the comment escape adjacent with the end of the string. + +@example +.ds UX \s-1UNIX\s0\u\s-3tm\s0\d\" trademark of you-know-who +@end example + +If you need leading space you can start the string with a double +quote. No trailing quote is needed, in fact any trailing quote is +included in your string. + +@cindex canibalism +@example +.ds sign " Yours in a white wine sauce, +@end example + +@findex as +@cindex appending to strings +@cindex strings, appending +You can also append onto a string with the @code{as} request. +It works the same as the @code{ds} request except that it appends the +second argument onto the string named by the first argument. + +@example +.as sign " with shallots, onions and garlic, +@end example + +@findex \@key{ret} +Strings are not limited to a sigle line of text. A string can span +several lines by escaping the newlines with a backslash. The +resulting string will be stored @emph{without} the newlines. + +@example +.ds foo lots and lots \ +of text are on these \ +next several lines +@end example + +@findex rn +@code{rn} + +@findex rm +@code{rm} + +@findex als +@code{als} + +@findex chop +@code{chop} + +@c distribute these through the text +@xref{Identifiers} +@c distribute these through the text +@xref{Comments} + +@node Conditionals and Loops, Writing Macros, Strings, Programming Tutorial +@section Conditionals and Loops +@cindex conditionals and loops +@cindex loops and conditionals + + +@findex if +@findex while +In @code{if} and @code{while} requests, there are several more operators +available: + +@table @code +@item e +@itemx o +True if the current page is even or odd numbered (respectively) +@item n +@itemx t +True if the document is being processed by +nroff (or an ascii device) or troff. +@item '@var{xxx}'@var{yyy}' +True if the string @var{xxx} is equal to the string @var{yyy}. +Other characters can be used in place of the single quotes. +(Which?) +The strings are `formatted' before being compared. (?) +@item r@var{xxx} +True if there is a number register named @var{xxx}. +@item d@var{xxx} +True if there is a string, macro, diversion, or request named @var{xxx}. +@item c@var{ch} +True if there is a character @var{ch} available; @var{ch} is +either an ASCII character or a special character @code{\(@var{ch}} or +@code{\[@var{ch}]}; the condition will also be true if @var{ch} has been +defined by the @code{char} request. +@end table + + +@menu +* if-else:: +* while:: +@end menu + +@node if-else, while, Conditionals and Loops, Conditionals and Loops +@subsection if-else +@cindex if-else + + +Troff has if-then-else constructs like other languages, although +the formatting can be painful. + +@findex if +The @code{if} request is troff's if statement, it is called as +@samp{.if @var{expr} @var{anything}}, where @var{expr} is the +expression to be evaluated, +and @var{anything} (the remainder of the line) +which will be executed if +the @var{expr} evaluates to non-zero (true). +@var{anything} will be interpreted as though it was on a line by +itself. +@xref{Expressions}, for more info. + +Here are some examples: + +@example +.if t .ls 2 \" double spacing in troff +.if 0 .ab how'd this happen?? +@end example + +@findex ie +@findex el +An if-then-else is written using two requests @code{ie} and @code{el} +the first request is the if part and the latter is the else part. + +@example +.ie +.el +@end example + +@findex \@{ +@findex \@} +In many cases you will want more than one request to be executed as a +result of any of these requests, this can be done using the \@{ and +\@} escapes. +The following example shows the possible ways to use these escapes. + +@example +.ie t \@{\ +. ds lq `` +. ds rq '' +.\@} +.el \ +.\@{\ +. ds lq " +. ds rq "\@} +.ds qq " +@end example + + +@c distribute these through the text +@xref{Expressions} + +@node while, , if-else, Conditionals and Loops +@subsection while +@cindex while + + +@findex while +Groff provides a looping construct using the @code{while} request, +which is used much like the @code{if} (and related) requests. +The first argument is an expression which will be evaluated. +The @code{while} request will interpret the remainder of the line +until the expression evaluates to 0 or false. + +@example +.nr a 0 1 +.while (\na<9) \&\n+a, +\&\n+a +@end example + +The preceding example produces: + +@example +1, 2, 3, 4, 5, 6, 7, 8, 9, 10 +@end example + +@findex break +@findex continue +The @code{break} request will +@dfn{break} out of a while loop. +Be sure not to confuse this with the @code{.br} request. +The @code{continue} request will +finish the current iteration of a while loop. + +@c distribute these through the text +@xref{Expressions} + +@node Writing Macros, Page Motions, Conditionals and Loops, Programming Tutorial +@section Writing Macros +@cindex writing macros +@cindex macros, writing + + +@findex de +A macro is a collection of text and embedded commands which can be +invoked multiple times. Macros are used for defining common operations. +Macros are defined using the @code{de} request. This request takes +a name for the macro as the first argument. Subsequent lines are +copied into an internal buffer until the line @code{..} is +encountered. The optional second argument to @code{de} can change +this ending token. + +For example, suppose at the beginning of each paragraph, you want +cause a break, move down a partial line and indent the first line. +Such a macro could be defined as follows: + +@example +.de P +.br +.sp .8v +.. +@end example + +@findex am +The @code{am} request works similarily to @code{de} except it appends +onto the macro named by the first argument. So, if we decide we want +our previously @code{P} macro to actually do indented instead of +block paragraphs we can add the necessary code to our existing macro. + +@example +.am P +.ti +5n +.. +@end example + +@findex als +@cindex aliases, macro +@cindex macro aliases +Macros can be aliased with the @code{als} request. + +@findex rn +@code{rn} + +@findex rm +@code{rm} + +@findex chop +@code{chop} + + +@menu +* Copy-in Mode:: +* Parameters:: +@end menu + +@node Copy-in Mode, Parameters, Writing Macros, Writing Macros +@subsection Copy-in Mode +@cindex copy-in mode +@cindex mode, copy-in + + +@findex \n +@findex \$ +@findex \* +@findex \\ +@findex \@key{RET} +When troff reads in the test for a macro or diversion it copies the +text (including request lines) into an internal buffer, except for +escapes. Escapes will be converted into an internal form, except for +@code{\n}, @code{\$}, @code{\*}, @code{\\} and @code{\@key{RET}} which +are evaluated and inserted into the text where the escape was located. +This is known as @dfn{copy-in} mode. + +What this means is that you can specify when these escapes are to be +evaluated (copy-in time or time of use) by insulating the escapes +with an extra backslash. + +For example, the following will result in the numbers 20 and 10 being +printed. + +@example +.nr x 20 +.de y +.nr x 10 +\&\nx +\&\\nx +.. +.y +@end example + + + +@node Parameters, , Copy-in Mode, Writing Macros +@subsection Parameters +@cindex parameters + + +@findex \$ +@vindex .$ +The arguments to a macro can be examined using a variety of escapes. +The number of arguments is available in the @code{.$} number register. +Any individual argument can be retrieved with one of the following +escapes: + +The escapes @code{\$@var{n}}, @code{\$(@var{nn}} +and @code{\$[@var{nnn}]} +will result in the @var{n}th, @var{nn}th or @var{nnn}th +argument. Macros can have a unlimited number of arguments. +Note that due to copy-in mode, you will want to have two backslashes +on these in actual use, since you do not want them interpolated until +the macro is actually invoked. + +@findex shift +The request @code{shift} will shift the arguments 1 position, or as +many positions as specified by the first argument. +After executing this request, argument +@var{i} will become argument @var{i}-@var{n}; arguments 1 to @var{n} +will no longer be available. +Shifting by negative amounts is currently undefined. + +@findex \$* +@findex \$@@ +In some cases you will want to just use all of the arguments at once. +For example if you pass the arguments along to another macro. +The @code{\$*} escape is +the concatenation of all the arguments separated by spaces. +A similar escape is @code{\$@@}, +which is +the concatenation of all the arguments with each surrounded +by double quotes, and separated by spaces. + +@findex \$0 +@findex als +The @code{\$0} escape is +the name by which the current macro was invoked. The @code{als} +request can make a macro have more than one name. + +@example +.de vl +.ie \\n(.$=1 .ds Vl Pre-Release Version +.el .ds Vl Version \\$3, \\$4. +.. +@end example + +This would be called as + +@example +.vl $Id: groff.texinfo,v 1.1 2000/04/09 07:58:37 millert Exp $ +@end example + + +@c distribute these through the text +@xref{Request Arguments} + +@node Page Motions, Drawing Functions, Writing Macros, Programming Tutorial +@section Page Motions +@cindex page motions +@cindex motions, page + + +@findex sp +Motions up and down the page can be done with the @code{sp} request. +However, this causes a break so that the actual effect is to move to +the left margin and then to the specified location. + +@findex mk +@findex rt +The request @code{mk} can be used to mark a location on a page, for +movement to later. This request takes a register name as an +argument in which to store the current page location, with no +argument it will store the location in an internal register. +The results of this can be used later by the @code{rt} or the +@code{sp} request. The @code{rt} request will return +@strong{upwards} to the location given in the register name given as +an argument, with no argument it will return to the location marked +with the @code{mk} request + +@example +... dual column example ... +@end example + +There are escapes which will give you much finer control of movements +about the page. + +@findex \v +The @code{\v'@var{e}'} will let you do arbitrary vertical motion from +the current location on the page. The argument @var{e} specifies the +distance to move, positive is downwards and negative upwards. The +default unit for this escape is vertical spaces, @code{v}'s. Beware, +however, that troff will leave text processing to continue wherever +the motion ends, so if you don't want to interfere with text +processing, make sure your motions are balanced. + +There are some special case escapes for vertical motion. + +@ftable @code +@item \r +move upwards 1v. +@item \u +move upwards .5v. +@item \d +move down .5v. +@end ftable + +@findex \h +Horizontal motions can be done via the @code{\h'@var{e}'} escape. +The expression @var{e} indicates how far to move: positive is +rightwards and negative leftwards. + +There are a number of special case escapes for horizontal motion: + +@ftable @code +@item \@key{SP} +An unbreakable and unpadable (i.e. not expanded during filling) space. +(Note: it is a backslash followed by a space.) +@item \~ +This produces an unbreakable space that stretches like a normal +interword space when a line is adjusted. +@item \| +a 1/6th em space. +@item \^ +a 1/12th em space. +@item \0 +a space the size of a digit. +@item \& +A zero width space. +@item \) +Like @code{\&} except that it behaves like a character declared with +the @code{cflags} request to be transparent for the purposes of end +of sentence recognition. +@end ftable + +@example +... tex logo example ... +@end example + +@findex \w +@cindex width escape +@cindex escape, width +Often you will want to do horizontal movement based on the width of +some arbitrary text (e.g. given as an argument to a macro). +For that, there is the escape @code{\w'@var{text}'} which will +interpolate to the width of the given @var{text} in basic units. + +@example +... strlen example ... +@end example + +Font changes may occur in @var{text} and not affect current settings. + +Also after use, @code{\w} sets several registers: + +@table @code +@item st +@vindex st +@itemx sb +@vindex sb +The highest and lowest point, respectively, in @var{text}. +@item rst +@vindex rst +@itemx rsb +@vindex rsb +Like the @code{st} and @code{sb} registers, but takes account of the +heights and depths of characters. +@item ct +@vindex ct +is set according to what kinds of characters occur in @var{text}. +@table @asis +@item 0 +all short characters, no decenders or tall characters. +@item 1 +decender +@item 2 +tall character +@item 3 +both a decender and a tall character +@end table +@item ssc +@vindex ssc +The amount of horizontal space (possibly negative) that should be +added to the last character before a subscript. +@item skw +@vindex skw +How far to right of the center of the last character in the @code{\w} +argument, the center of an accent from a roman font should be +placed over that character. +@end table + +@findex \k +@vindex .k +@code{\k} +@code{.k} + +@node Drawing Functions, Traps, Page Motions, Programming Tutorial +@section Drawing Functions +@cindex drawing functions +@cindex functions for drawing + + +Groff provides a number of ways to draw lines, and other figures on +the page. Used in combination with the page motion commands +(@pxref{Page Motions}, for more info) you can draw a wide variety of +figures. However, for complex drawings these operations can be quite +cumbersome, and it may be wise to use the pic preprocessor. +@xref{gpic}, for more information. + +All drawing is done via escapes. + +@findex \l +The @code{\l} will draw a line rightwards from the current location. +The full syntax for this escape is @samp{\l'@var{l}@var{c}'}, where +@var{l} is the length of the line to be drawn, starting at the +current location, positive numbers will draw to the right, and +negative will draw towards the left. This can also be specified +absolutely (i.e. with a leading |) which will draw back to the +begining of the line. + +The optional second parameter @var{c} is a character to draw the line +with. If this second argument is not specified, troff will use the +underscore character. + +If you need to separate the two arguments (to prevent troff from +interpreting a drawing character as a scaling indicator), you can +separate them with @code{\&}. + +And now, for a useful example: + +@example +.de box +\(br\\$*\(br\l'|0\(rn'\l'|0\(ul' +.. +@end example + +Note that this works by outputing a box rule (a vertical line), then +the text given as an argument and then another box rule. +Then the line drawing escapes both draw from the current location to +the beginning of the @emph{input} line. + +@findex \L +Vertical lines are drawn using the @code{\L} escape. It's parameters +are specified the same as the @code{\l} escape. If the length is +positive, the movement will be downwards, and upwards for negative. +The default character is the box rule character. +As with the vertical motion escapes, text processing will blindly +continue where the line ends. + +@example +...box macro... +@end example + +@findex \D +More flexible drawing functions are available via the @code{\D} +escape. While the previous escapes will work on an ascii device, +these escapes will not. + +@table @code +@item \D'l @var{x} @var{y}' +Draw a line from the current location to the relative point specified +by @var{x}, @var{y}. + +@example +...revised box macro... +@end example + +@item \D'c @var{d}' +Draw a circle with a diameter of @var{d} with the leftmost point at +the current position. +@item \D'C @var{d}' +Draw a solid circle with the same parameters as an outlined circle. +@item \D'e @var{dx} @var{dy}' +Draw an ellipse with a horizontal diameter of @var{dx} and a vertical +diameter of @var{dy} with the leftmost point at the current position. +@item \D'E @var{dx} @var{dy}' +Draw a solid elipse with the same parameters as an outlined elipse. +@item \D'a @var{dx1} @var{dy1} @var{dx2} @var{dy2}' +Draw an arc clockwise from the current location through the two +specified locations. +@item \D'~ @var{dx1} @var{dy1} @var{dx2} @var{dy2} ...' +Draw a spline from the current location to +@var{dx1}, @var{dy1} and then to @var{dx2}, @var{dy2}, and so on. +@item \D'f @var{n}' +Set the shade of gray to be used for filling solid objects to @var{n}; +@var{n} must be an integer between 0 and 1000, where 0 corresponds +solid white and 1000 to solid black, and values in between correspond +to intermediate shades of gray. This applies only to solid circles, +solid ellipses and solid polygons. By default, a level of 1000 will +be used. +@item \D'p @var{dx1} @var{dy1} @var{dx2} @var{dy2} ...' +Draw a polygon from the current location to @var{dx1}, @var{dy1} +and then to @var{dx2}, @var{dy2} and so on. When the specified data +points are exhausted, a line is drawn back to the starting point. + +@example +... box example (yes, again)... +@end example + +@itemx \D'P @var{dx1} @var{dy1} @var{dx2} @var{dy2} ...' +Draw a solid polygon with the same parameters as an outlined polygon. + +@example +... shaded box example ... +@end example + +@item \D't @var{n}' +Set the current line thickness to @var{n} machine units. +A value of zero selects the smallest available line thickness. + +@end table + +Current position + +@findex \b +@cindex pile, character +@cindex character pile +The @code{\b} escape will @dfn{pile} a sequence of characters +vertically, and center it vertically on the current line. +This can be used to build large brackets and braces. + +@example +\b'\(lt\(bv\(lk\(bv\(lb' +@end example + + + + +@node Traps, Diversions, Drawing Functions, Programming Tutorial +@section Traps +@cindex traps + + +Traps are locations, which, when reached, will call a specified macro. +These traps can occur at a given location on the page, at a given +location in the current diversion, after a certain number of input +lines or at the end of input. + +@findex ch +Any of these traps can be changed after they have been set with the +@code{ch} request. The first arguemnt is the name of the trap or +macro, and the second is the new value for that trap. + + +@menu +* Page Location Traps:: +* Diversion Traps:: +* Input Line Traps:: +* End-of-input Traps:: +@end menu + +@node Page Location Traps, Diversion Traps, Traps, Traps +@subsection Page Location Traps +@cindex page location traps +@cindex traps, page location + + +Page location traps are frequently used for page headers and +footers. The following is a simple example of this. + +@example +.de hd \" Page header +'sp .5i +.tl 'Title''date' +'sp .3i +.. +.de fo \" Page footer +'sp 1v +.tl ''%'' +'bp +.. +.wh 0 hd \" top of the page +.wh -1i fo \" one inch from bottom +@end example + +@vindex .t +The number register @code{.t} is the distance to the next trap. + +@findex ch +The location of a trap can be changed later on with the @code{ch} +request. +The first argument is the name of the macro to be invoked at the trap +and the second argument is the new location for the trap. +This is useful when you are building up footnotes in a diversion, and +you need to allow more space at the bottom of the page for them. + +@example +... (simplified) footnote example ... +@end example + +@findex vpt +@findex wh +@findex dt +@vindex .vpt +The @code{vpt} request will enable vertical position traps if the argment is +non-zero, disable them otherwise. Vertical position traps are traps +set by the @code{wh} or @code{dt} requests. Traps set by the +@code{it} request are not vertical position traps. The parameter that +controls whether vertical position traps are enabled is global. +Initially vertical position traps are enabled. The current setting of +this is available in the number register @code{.vpt}. + +@vindex .trunc +@findex ne +The number register @code{.trunc} contains +the amount of vertical space truncated by the most recently +sprung vertical position trap, or, if the trap was sprung by a +@code{ne} request, minus the amount of vertical motion produced by +the @code{ne} request. In other words, at the point a trap is +sprung, it represents the difference of what the vertical position +would have been but for the trap, and what the vertical position +actually is. + +@vindex .ne +The number register @code{.ne} contains +the amount of space that was needed in the last @code{ne} request that caused +a trap to be sprung. Useful in conjunction with the @code{.trunc} +register. @xref{Page Control}, for more information. + + + +@node Diversion Traps, Input Line Traps, Page Location Traps, Traps +@subsection Diversion Traps +@cindex diversion traps +@cindex traps, diversion + + +@findex dt +@vindex .t +Traps can also be set @emph{within} a diversion using the @code{dt} +request. Like @code{wh} the first argument is the location of the +trap and the second argument is the name of the macro to be invoked. +The number register @code{.t} will still work within diversions. +@xref{Diversions}, for more information. + +@node Input Line Traps, End-of-input Traps, Diversion Traps, Traps +@subsection Input Line Traps +@cindex input line traps +@cindex traps, input line + + +@findex it +The @code{it} request will set an input line trap. The format for +calling this is @samp{.it @var{n} @var{name}}, where @var{n} is the +number of lines of input which may be read before @dfn{springing} the +trap, @var{name} is the macro to be invoked. Request lines are not +counted as input lines. + +For example, one possible use is to have a macro which will print the +next @var{n} lines in a bold font. + +@example +.de B +.it B-end \\$1 +.ft B +.. +.de B-end +.ft R +.. +@end example + +@node End-of-input Traps, , Input Line Traps, Traps +@subsection End-of-input Traps +@cindex end-of-input traps +@cindex traps, end-of-input + + +@findex em +The @code{em} request will set a trap at the end of input. +The macro specified as an arguement will be executed after the last +line of the input file has been processed. + +For example, if your document had to have a section at the bottom of +the last page for someone to approve you document, you could set it +up with @code{em}. + +@example +.de approval +.ne 5v +.sp |(\\n(.t-6v) +.in +4i +.lc _ +.br +Approved:\t\a +.sp +Date:\t\t\a +.. +.em approval +@end example + + +@node Diversions, Environments, Traps, Programming Tutorial +@section Diversions +@cindex diversions + + +In Troff you can divert text into a named storage area, due to the +similarity to defining macros it is sometimes said to be stored in a +macro. This is used for saving text for output at a later time, +which is useful for keeping blocks of text on the same page, +footnotes, tables of contents and indexes. + +@findex di +@findex da +Diversion is initiated by the @code{di} request, like the @code{de} +request it takes an argument of a macro name to divert subsequent +text to into. The @code{da} macro will append to an existing diversion. + +@example +... end-note example ... +@end example + +@vindex .z +@vindex .d +@vindex nl +@vindex .h +Diversions may be nested. +The number register @code{.z} contains the name of the current diversion. +The number register @code{.d} contains the current vertical place in +the diversion. If not in a diversion it is the same as the register +@code{nl}. +@code{.h} + +@vindex dn +@vindex dl +After compleating a diversion, the builtin number registers @code{dn} +and @code{dl} contain the vertical and horizontal size of the diversion. + +@example +.\" Center text both horizontally & vertically +.de (c +.br +.nf +.di @@c +.. +.de )c +.br +.di +.nr @@s (((\\n(.tu-\\n(dnu)/2u)-1v) +.sp \\n(@@su +.ce 1000 +.nf +.@c +.br +.ce 0 +.sp \\n(@@su +.br +.fi +.rr @@s +.. +@end example + +@findex \! +Requests, macros and escapes are interpreted when read into a +diversion. +There are two ways to prevent this, either way will take the given +text and @dfn{transparently} embed it into the diversion. +The first method is to prefix the line with @code{\!}. This will +cause the entire line to be transparently inserted into the diversion. +This is useful for macros you do not want invoked until the diverted +text is actually output. + +@c anything is read in copy mode. (what about \! ??) + +@findex \? +The other way is to surround the text by the @code{\?} escape, i.e. +@samp{\?@var{anything}\?}. +@var{anything} may not contain +newlines; use @code{\!} if you want to embed newlines in a diversion. The +escape sequence @code{\?} is also recognised in copy mode and turned into a +single internal code; it is this code that terminates anything. Thus +the followin example will print 4. + +@example +.nr x 1 +.nf +.di d +\?\\?\\\\?\\\\\\\\nx\\\\?\\?\? +.di +.nr x 2 +.di e +.d +.di +.nr x 3 +.di f +.e +.di +.nr x 4 +.f +@end example + +@findex rn +@code{rn} + +@findex rm +@code{rm} + +@findex als +@code{als} + +@findex chop +@code{chop} + +@findex asciify +@code{asciify} +This request only exists in order to make it possible to make certain +gross hacks work with GNU troff. It @dfn{unformats} the diversion +specified as an argument in +such a way that ASCII characters that were formatted and diverted +will be treated like ordinary input characters when the diversion is +reread. For example, the following will set register @code{n} to 1. + +@example +.tr @@. +.di x +@@nr\ n\ 1 +.br +.di +.tr @@@@ +.asciify x +.x +@end example + + +@c distribute these through the text +@xref{Copy-in Mode} + +@node Environments, I/O, Diversions, Programming Tutorial +@section Environments +@cindex environments + + +Often you will need to print some text in a certain format regardless +of what may be in effect at the time, for example, in a trap invoked +macro to print headers and footers. +To solve this groff has @dfn{environments} in which text is processed. +An environment contains most of the parameters that control +text processing. You can switch amongst these environments, by +default groff processes text in environment 0. +The following is the information kept in an environment. + +@itemize @bullet{} +@item +Type size +@item +Font (family and style) +@item +Page parameters +@item +Fill/adjust mode +@item +Tab stops +@item +Partially collected lines +@end itemize + +These environments may be given arbitrary names +(@pxref{Identifiers}, for more info.) +Old versions of troff only had environments named 0, 1 and 2. + +@findex ev +@vindex .ev +The @code{ev} request will switch among these environments. +The single argument is the name of the environment to switch to, with +no argument groff will switch back to the previous enviroment. +There is no limit on the number of named environments; +they will be created the first time that they are referenced. +The @code{.ev} number register contains +the name or number of the current environment. This is a string-valued +register. + +@example +... page break macro, revised ... +@end example + +@example +.ev footnote-env +.fam N +.ps 6 +.vs 8 +.ll -.5i +.ev +... +.ev footnote-env +\(dg Note the large, friendly letters. +.ev +@end example + + + + +@node I/O, Postprocessor Access, Environments, Programming Tutorial +@section I/O +@cindex i/o + + +@findex so +The @code{so} request will read in the file given as an argument and +include it in place of the @code{so} request. This is quite useful +for large documents, i.e. keeping each chapter in a separate file. +@xref{gsoelim}, for more information. + +@findex mso +The @code{mso} request is +the same as the @code{so} request except that file is searched for in +the same way that @file{tmac.@var{name}} is searched for when the +@samp{-m@var{name}} option is specified. + +@findex cf +@findex trf +The @code{cf} and @code{trf} requests are to include a file. +It will transparently output the contents of file filename. Each +line is output +as it would be were it preceded by @code{\!}; however, the lines are not +subject to copy-mode interpretation. If the file does not end with a +newline, then a newline will be added. For example, you can define a +macro @code{x} containing the contents of file @file{f}, using + +@example +.di x +.trf f +.di +@end example + +.cf filename +When used in a diversion, this will embed in the diversion an object +which, when reread, will cause the contents of filename to be +transparently copied through to the output. In @sc{Unix} troff, the contents +of filename is immediately copied through to the output regardless of +whether there is a current diversion; this behaviour is so anomalous +that it must be considered a bug. + + +With @code{trf}, unlike @code{cf}, the file cannot contain characters +such as NUL that are not legal troff input characters. + +@findex nx +The @code{nx} request will force groff to continue processing of the +file specified as an argument. + +@findex rd +The @code{rd} request will read from standard input, and include what +is read as though it were part of the input file. Text is read until +a blank line is encountered. + +@cindex form letters +@cindex letters, form +Using these two requests you can set up form letters. +The form letter template is constructed like this: + +@example +.ce +\*(td +.sp 2 +.nf +.rd +.sp +.rd +.fi +Body of letter. +.bp +.nx repeat.let +@end example + +@findex ex +When this is run, the following file should be redirected in. +Note that requests included in this file are executed as though they +were part of the form letter. The last block of input is the +@code{ex} requests which tells groff to stop processing. If this was +not there, groff would not know when to stop. + +@cindex Beagle Brothers +@example +Trent A. Fisher +708 NW 19th Av., #202 +Portland, OR 97209 + +Dear Trent, + +Len Adollar +4315 Sierra Vista +San Diego, CA 92103 + +Dear Mr. Adollar, + +.ex +@end example + +@findex pi +@code{pi} + +@findex sy +The @code{sy} request will allow arbitrary system commands to be +executed from within a groff document. The output is not saved +anyplace, so it is up to you to do so. + +For example, the following example will introduce the current time +into your document: + +@cindex time +@pindex perl +@example +.sy perl -e 'printf ".nr H %d\\n.nr M %d\\n.nr S %d\\n",\ + (localtime(time))[2,1,0]' > /tmp/x\n[$$] +.so /tmp/x\n[$$] +.sy rm /tmp/x\n[$$] +\nH:\nM:\nS +@end example + +Note that this works by having the perl script (run by @code{sy}) +print out the @code{nr} requests which will set the number registers +@samp{H}, @samp{M} and @samp{S}, and then reads those commands in +with the @code{so} request. + +@vindex systat +The @code{systat} number register contains +The return value of the @code{system()} function executed by the last +@code{sy} request. + +@findex open +The @code{open} request will open +a file (specified as the second argument) for writing and associate +the stream (specified as the first argument) with it. + +@findex opena +The @code{opena} is +like open, but if filename exists, append to it instead of truncating +it. + +@findex write +@findex ds +@cindex copy-in mode +@cindex mode, copy-in +The @code{write} request will write to the file associated with the +stream specified by the first argument. The stream must previously +have been the subject of an open request. The remainder of the line +in interpreted as the @code{ds} request reads its second argument: a +leading @code{"} will be stripped, and it will be read in copy-in mode. + +@findex close +The @code{close} request will +close the stream specified by the first argument; stream will no +longer be an acceptable argument to the @code{write} request. + +@example +... example of open write &c... +@end example + +@findex \v +The @code{\V} escape will +interpolate the contents of the specified environment variable, as returned +by getenv(3). +The argument to @code{\V} is specified as an identifier, i.e. +@samp{\V@var{x}}, @samp{\V(@var{xx}} or @samp{\V[@var{xxx}]}. +@code{\V} is interpreted in copy-in mode. + + +@node Postprocessor Access, Miscellany, I/O, Programming Tutorial +@section Postprocessor Access +@cindex postprocessor access +@cindex access of postprocessor + + +There are two escapes which will allow you to give information +directly to the postprocessor. This is particularly useful for +embedding PostScript into your final document. + +@findex \X +The @code{\X} escape will embed its argument into the gtroff output +preceded with @samp{x X}. + +@findex \Y +The @code{\Y} escape is called with an identifier (i.e. +@code{\Y@var{x}}, +@code{\Y(@var{xx}} or +@code{\Y[@var{xxx}]}). +This is approximately equivalent to @samp{\X'\*[@var{xxx}]'}. +However the contents +of the string or macro @var{xxx} are not interpreted; also it is +permitted for +@var{xxx} to have been defined as a macro and thus contain newlines +(it is not permitted for the argument to @code{\X} to contain newlines). +The inclusion of +newlines requires an extetension to the @sc{Unix} troff output format, and will +confuse drivers that do not know about this extension. + + +@c distribute these through the text +@xref{Devices} + +@node Miscellany, Debugging, Postprocessor Access, Programming Tutorial +@section Miscellany +@cindex miscellany + + +This section contains parts of troff which cannot (yet) be +categorized elsewhere in this manual. + +@findex nm +Line numbers can be printed in the left margin +using the @code{nm} request. +The first argument is the line number of the @emph{next} output line, +this defaults to 1. +The second argument indicates on which lines numbers will be printed, +i.e. 5 means put line numbers on every 5 lines, this defaults to 1. +The third argument is the space to be left between the number and +your text, this defaults to 1. +The fourth argument is the indentation of the line numbers. +Without arguments, line numbers are turned off. + +@findex nn +The @code{nn} request will temporarily turn off line numbering. +The first argument is the number of lines not to be numbered, +this defaults to 1. (does this disable incrementing or display?) + +@example +... line numbering example ... +@end example + +@findex mc +margin characters can be automatically printed to the right of your +text with the @code{mc} request. +The first argument is the character to be printed and the second +argument is the distance away from your text. +With no arguments the margin characters are turned off. +If this occurs before a break, no margin character will be printed. + +This is quite useful for indicating text that has changed, and, in +fact, there are programs available for doing this (they are called +@code{nrchbar} and @code{changebar} and can be found in any +@samp{comp.sources.unix} archive. + +@example +... margin char example ... +@end example + +@findex lf +@pindex soelim +The @code{lf} primary reason for existence is to make debugging +documents which are split into many files, which are then put +together with @code{soelim} and other preprocessors. +The first argument is the name of the file and the second argument is +the input line number in that file. +This way troff can produce error messages which are intelligible to +the user. + +@example +... example of soelim'ed doc ... +@end example + +@node Debugging, Implementation Differences, Miscellany, Programming Tutorial +@section Debugging +@cindex debugging + + +Troff is not easy to debug, but there are some useful features and +strategies for debugging. + +@itemize @bullet{} +@item +@findex tm +The @code{tm} request will send output to stderr, this is very useful for +printing debugging output. +@item +When doing something involved it is useful to leave the debugging +statements in the code and have them turned on by a command line +flag. + +@example +.if \n(DB .tm debugging output +@end example + +Then you can activate these statements with: + +@example +groff -rDB=1 file +@end example + +@item +@findex ab +The @code{ab} request is similar to the @code{tm} request, +except that it will cause groff to stop processing. +With no argument it will print @samp{User Abort}. +@item +@findex ex +The @code{ex} request will also cause groff to stop processing. +@item +If you know you are going to get many errors and no useful output, +you can tell groff to suppress formatted output with the @samp{-z} +flag. +@item +@findex pm +The @code{pm} request will dump out the entire symbol table. +@item +@findex pnr +The @code{pnr} request will print the names and contents of all +currently defined number registers on stderr. +@item +@findex ptr +The @code{ptr} request will +print the names and positions of all traps (not including input line +traps and diversion traps) on stderr. Empty slots in the page trap list +are printed as well, because they can affect the priority of +subsequently planted traps. +@item +@findex fl +The @code{fl} request instructs groff to flush its output immediately. +The intention is that this be used when using troff interactively. +There is little other use for it. +@item +@findex backtrace +The @code{backtrace} request will +print a backtrace of the input stack on stderr. +@item +Groff has command line options for printing out more warnings +(@samp{-w}) and for printing backtraces (@samp{-b}) when a warning or +an error occurs. The most verbose level of warnings is @samp{-ww}. +@item +@findex warn +@vindex .warn +The @code{warn} request controls the level of warnings checked for. +The one argument is the sum of the numbers associated with each +warning that is to be enabled; all other warnings will be disabled. +The number associated with each warning is listed below. +For example, @code{.warn 0} will disable all warnings, and +@code{.warn 1} will disable +all warnings except that about missing characters. If an argument +is not given, all warnings will be enabled. +The number register @code{.warn} contains the current warning level. +@end itemize + +@subsection Warnings +@cindex warnings + +The warnings that can be given by troff are divided into the +following categories. The name associated with each warning is used +by the @samp{-w} and @samp{-W} options; the number is used by the +@code{warn} request, and by the @code{.warn} register. + +@table @samp +@item char +@itemx 1 +Non-existent characters. This is enabled by default. +@item number +@itemx 2 +Invalid numeric expressions. This is enabled by default. +@item break +@itemx 4 +In fill mode, lines which could not be broken so that +their length was less than the line length. This is +enabled by default. +@item delim +@itemx 8 +Missing or mismatched closing delimiters. +@item el +@itemx 16 +Use of the @code{el} request with no matching @code{ie} request. +@xref{if-else}, for more information. +@item scale +@itemx 32 +Meaningless scaling indicators. +@item range +@itemx 64 +Out of range arguments. +@item syntax +@itemx 128 +Dubious syntax in numeric expressions. +@item di +@itemx 256 +@findex di +@findex da +Use of @code{di} or @code{da} without an argument when there is no +current diversion. +@item mac +@itemx 512 +Use of undefined strings, macros and diversions. +When an undefined string, macro or diversion is used, +that string is automatically defined as empty. So, +in most cases, at most one warning will be given for +each name. +@item reg +@itemx 1024 +Use of undefined number registers. When an undefined +number register is used, that register is +automatically defined to have a value of 0. a +definition is automatically made with a value of 0. +So, in most cases, at most one warning will be given +for use of a particular name. +@item tab +@itemx 2048 +Use of a tab character where a number was expected. +@item right-brace +@itemx 4096 +@findex \@} +Use of @code{\@}} where a number was expected. +@item missing +@itemx 8192 +Requests that are missing non-optional arguments. +@item input +@itemx 16384 +Illegal input characters. +@item escape +@itemx 32768 +Unrecognized escape sequences. When an unrecognized +escape sequence is encountered, the escape character +is ignored. +@item space +@itemx 65536 +Missing space between a request or macro and its +argument. This warning will be given when an +undefined name longer than two characters is +encountered, and the first two characters of the name +make a defined name. The request or macro will not +be invoked. When this warning is given, no macro is +automatically defined. This is enabled by default. +This warning will never occur in compatibility mode. +@item font +@itemx 131072 +Non-existent fonts. This is enabled by default. +@item all +All warnings except @samp{di}, @samp{mac} and @samp{reg}. It is +intended that this covers +all warnings that are useful with traditional macro packages. +@item w +All warnings. +@end table + + +@node Implementation Differences, Summary, Debugging, Programming Tutorial +@section Implementation Differences +@cindex implementation differences +@cindex differences in implementation + + +GNU troff has a number of features which cause incompatibilites with +documents written with old versions of troff. + +Long names cause some incompatibilities. @sc{Unix} troff will interpret + +@example +.dsabcd +@end example + +@findex \* +@findex \n +@findex cp +@vindex .C +as defining a string @samp{ab} with contents @samp{cd}. +Normally, GNU troff will interpret this as a call of a macro named +@code{dsabcd}. Also @sc{Unix} troff will interpret @code{\*[} or +@code{\n[} as references to a string or number register called +@samp{[}. In GNU troff, however, this will normally be interpreted as the +start of a long name. In compatibility mode GNU troff will interpret +these things in the traditional way. In compatibility mode, however, +long names are not recognised. Compatibility mode can be turned on with +the @samp{-C} command line option, and turned on or off with the +@code{cp} request. +The number register @code{.C} is 1 if compatibility mode is on, 0 otherwise. + +@findex \A +GNU troff does not allow the use of the escape sequences +@samp{\| \^ \& \@} \@{ \@key{SP} \' \` \- \_ \! \% \c} in names of +strings, macros, +diversions, number registers, fonts or environments; @sc{Unix} troff does. +The @code{\A} escape sequence may be helpful in avoiding use of these escape +sequences in names. + +@cindex fractional point sizes +@cindex point sizes, fractional +@findex ps +Fractional pointsizes cause one noteworthy incompatibility. In @sc{Unix} +troff the @code{ps} request ignores scale indicators and so + +@example +.ps 10u +@end example + +will set the pointsize to 10 points, whereas in GNU troff it will set +the pointsize to 10 scaled points. +@xref{Fractional Type Sizes}, for more information. + +@findex bd +@findex cs +@findex tkf +@findex tr +@findex fp +In GNU troff there is a fundamental difference between unformatted, +input characters, and formatted, output characters. Everything that +affects how an output character will be output is stored with the +character; once an output character has been constructed it is +unaffected by any subsequent requests that are executed, including +@code{bd}, @code{cs}, @code{tkf}, @code{tr}, or @code{fp} +requests. Normally output characters are constructed +from input characters at the moment immediately before the character is +added to the current output line. Macros, diversions and strings are +all, in fact, the same type of object; they contain lists of input +characters and output characters in any combination. An output +character does not behave like an input character for the purposes of +macro processing; it does not inherit any of the special properties that +the input character from which it was constructed might have had. For +example, + +@example +.di x +\\\\ +.br +.di +.x +@end example + +@findex \e +@findex \! +@findex \? +will print @samp{\\} in GNU troff; each pair of input backslashes is +turned into one +output backslash and the resulting output backslashes are not +interpreted as escape +characters when they are reread. @sc{Unix} troff would interpret them as +escape characters when they were reread and would end up printing one +@samp{\}. +The correct way to obtain a printable backslash is to use the +@code{\e} escape +sequence: this will always print a single instance of the current escape +character, regardless of whether or not it is used in a diversion; it +will also work in both GNU troff and @sc{Unix} troff. If you wish for some +reason to store in a diversion an escape sequence that will be +interpreted when the diversion is reread, you can either use the +traditional @code{\!} transparent output facility, or, if this is unsuitable, +the new @code{\?} escape sequence. @xref{Diversions}, for more information. + + +@node Summary, , Implementation Differences, Programming Tutorial +@section Summary +@cindex summary + + +@node geqn, gtbl, Programming Tutorial, Top +@chapter @code{geqn} +@cindex @code{eqn} +@cindex @code{geqn} + + +@menu +* Invoking geqn:: +@end menu + +@node Invoking geqn, , geqn, geqn +@section Invoking @code{geqn} +@cindex invoking @code{geqn} +@cindex @code{geqn}, invoking + + + +@node gtbl, gpic, geqn, Top +@chapter @code{gtbl} +@cindex @code{tbl} +@cindex @code{gtbl} + + +@menu +* Invoking gtbl:: +@end menu + +@node Invoking gtbl, , gtbl, gtbl +@section Invoking @code{gtbl} +@cindex invoking @code{gtbl} +@cindex @code{gtbl}, invoking + + +@node gpic, grap, gtbl, Top +@chapter @code{gpic} +@cindex @code{pic} +@cindex @code{gpic} + + +@menu +* Invoking gpic:: +@end menu + +@node Invoking gpic, , gpic, gpic +@section Invoking @code{gpic} +@cindex invoking @code{gpic} +@cindex @code{gpic}, invoking + + + +@node grap, grefer, gpic, Top +@chapter @code{grap} +@cindex @code{grap} + + + +@node grefer, gsoelim, grap, Top +@chapter @code{grefer} +@cindex @code{refer} +@cindex @code{grefer} + + +@menu +* Invoking grefer:: +@end menu + +@node Invoking grefer, , grefer, grefer +@section Invoking @code{grefer} +@cindex invoking @code{grefer} +@cindex @code{grefer}, invoking + + + +@node gsoelim, Devices, grefer, Top +@chapter @code{gsoelim} +@cindex @code{soelim} +@cindex @code{gsoelim} + + +@menu +* Invoking gsoelim:: +@end menu + +@node Invoking gsoelim, , gsoelim, gsoelim +@section Invoking @code{gsoelim} +@cindex invoking @code{gsoelim} +@cindex @code{gsoelim}, invoking + + + +@node Devices, File formats, gsoelim, Top +@chapter Devices +@cindex devices + + + +@menu +* Special Characters:: +* grotty:: +* grops:: +* grodvi:: +* grolj4:: +* grohtml:: +* gxditview:: +@end menu + +@node Special Characters, grotty, Devices, Devices +@section Special Characters +@cindex special characters +@cindex characters, special + + +@c distribute these through the text +@xref{Font Files} + +@node grotty, grops, Special Characters, Devices +@section @code{grotty} +@cindex @code{grotty} + + + +@menu +* Invoking grotty:: +@end menu + +@node Invoking grotty, , grotty, grotty +@subsection Invoking @code{grotty} +@cindex invoking @code{grotty} +@cindex @code{grotty}, invoking + + + +@node grops, grodvi, grotty, Devices +@section @code{grops} +@cindex @code{grops} + + + +@menu +* Invoking grops:: +* Embedding PostScript:: +@end menu + +@node Invoking grops, Embedding PostScript, grops, grops +@subsection Invoking @code{grops} +@cindex invoking @code{grops} +@cindex @code{grops}, invoking + + + +@node Embedding PostScript, , Invoking grops, grops +@subsection Embedding PostScript +@cindex embedding postscript +@cindex postscript, embedding + + + +@node grodvi, grolj4, grops, Devices +@section @code{grodvi} +@cindex @code{grodvi} + + + +@menu +* Invoking grodvi:: +@end menu + +@node Invoking grodvi, , grodvi, grodvi +@subsection Invoking @code{grodvi} +@cindex invoking @code{grodvi} +@cindex @code{grodvi}, invoking + + + +@node grolj4, grohtml, grodvi, Devices +@section @code{grolj4} +@cindex @code{grolj4} + + + +@menu +* Invoking grolj4:: +@end menu + +@node Invoking grolj4, , grolj4, grolj4 +@subsection Invoking @code{grolj4} +@cindex invoking @code{grolj4} +@cindex @code{grolj4}, invoking + + + +@node grohtml, gxditview, grolj4, Devices +@section @code{grohtml} +@cindex @code{grohtml} + + + +@menu +* Invoking grohtml:: +@end menu + +@node Invoking grohtml, , grohtml, grohtml +@subsection Invoking @code{grohtml} +@cindex invoking @code{grohtml} +@cindex @code{grohtml}, invoking + + + +@node gxditview, , grohtml, Devices +@section @code{gxditview} +@cindex @code{gxditview} + + + +@menu +* Invoking gxditview:: +@end menu + +@node Invoking gxditview, , gxditview, gxditview +@subsection Invoking @code{gxditview} +@cindex invoking @code{gxditview} +@cindex @code{gxditview}, invoking + + + +@node File formats, Installation, Devices, Top +@chapter File formats +@cindex file formats +@cindex formats, file + + + +@menu +* gtroff Output:: +* Font Files:: +@end menu + +@node gtroff Output, Font Files, File formats, File formats +@section @code{gtroff} Output +@cindex @code{gtroff} output +@cindex output, @code{gtroff} + + +This section describes the format output by GNU troff. The output +format used by GNU troff is very similar to that used by @sc{Unix} +device-independent troff. + +The output format is ascii based, as opposed to a binary format (like +@TeX{} dvi). +The output format is 8 bit clean, thus single characters can have the +eighth bit set, as can the names of fonts and special characters. + +The output format consists of single command characters with attached +parameters which are separated from subsequent text by whitespace, or +a newline. + +The names of characters and fonts an be of arbitrary length; drivers +should not assume that they will be only two characters long (as +device-independent troff did). + +When a character is to be printed, that character will always be in the +current font. +Unlike device-independent troff, it is not necessary for +drivers to search special fonts to find a character. + +@table @code +@item H@var{n} +@item V@var{n} +@item h@var{n} +@item v@var{n} +@item c@var{n} +@item C@var{n} +@item @var{nn}@var{c} +@item t@var{xxx} +@var{xxx} is any sequence of characters terminated by a space or a +newline; the first character should be printed at the current +position, the the current horizontal position should be increased by +the width of the first character, and so on for each character. +The width of the character is that given in the font file, +appropriately scaled for the current point size, +and rounded so that it is a multiple of the horizontal resolution. +Special characters cannot be printed using this command. + +This command is only allowed if the @samp{tcommand} line is present +in the @file{DESC} file. +@item u@var{n} @var{xxx} +@pindex DESC +This is same as the @code{t} command except that after printing each +character, the current horizontal position is increased by the sum of +the width of that character and @code{n}. + +This command is only allowed if the @samp{tcommand} line is present +in the @file{DESC} file. +@item n@var{a}@var{b} +@item p@var{n} +@item s@var{n} +The argument to the s command is in scaled points (units of points/n, +where n is the argument to the sizescale command in the DESC file.) +@item f@var{n} +@item x @dots{} \n +Device control. +@item D@var{c} @var{x}@dots{}\n +@end table + +@subsection Device Control + +The @code{x} command is normally followed by a letter or word +indicating the function to perform, followed by white space separated +arguments. + +The first argument can be abreviated to the first letter. + +@table @code +@item x init +@item x T +@item x res @var{n} @var{h} @var{v} +@item x H +The argument to the x Height command is also in scaled points. +@end table + +The first three output commands are guaranteed to be: + +@example +x T device +x res n h v +x init +@end example + +For example, the input @samp{crunchy \fH\s+2frog\s0\fP!?} will produce: + +@example +... sample output here ... +@end example + +@subsection Drawing Functions + +The D drawing command has been extended. These extensions will only be +used by GNU pic if the -x option is given. + +@table @code +... +@item Df n\n +Set the shade of gray to be used for filling solid objects to n; n must +be an integer between 0 and 1000, where 0 corresponds solid white and +1000 to solid black, and values in between correspond to intermediate +shades of gray. This applies only to solid circles, solid ellipses and +solid polygons. By default, a level of 1000 will be used. Whatever +color a solid object has, it should completely obscure everything +beneath it. A value greater than 1000 or less than 0 can also be used: +this means fill with the shade of gray that is currently being used for +lines and text. Normally this will be black, but some drivers may +provide a way of changing this. +@item DC d\n +Draw a solid circle with a diameter of d with the leftmost point at the +current position. +@item DE dx dy\n +Draw a solid ellipse with a horizontal diameter of dx and a vertical +diameter of dy with the leftmost point at the current position. +@item Dp $dx sub 1$ $dy sub 1$ $dx sub 2$ $dy sub 2$ $...$ $dx sub n$ $dy sub +n$\n +Draw a polygon with, for $i = 1 ,..., n+1$, the i-th vertex at the +current position $+ sum from j=1 to i-1 ( dx sub j , dy sub j )$. At +the moment, GNU pic only uses this command to generate triangles and +rectangles. +@item DP $dx sub 1$ $dy sub 1$ $dx sub 2$ $dy sub 2$ $...$ $dx sub n$ $dy sub +n$\n +Like Dp but draw a solid rather than outlined polygon. +@item Dt n\n +Set the current line thickness to n machine units. Traditionally @sc{Unix} +troff drivers use a line thickness proportional to the current point +size; drivers should continue to do this if no Dt command has been +given, or if a Dt command has been given with a negative value of n. A +zero value of n selects the smallest available line thickness. +@end table + +A difficulty arises in how the current position should be changed after +the execution of these commands. This is not of great importance since +the code generated by GNU pic does not depend on this. Given a drawing +command of the form + +\D'c $x sub 1$ $y sub 1$ $x sub 2$ $y sub 2$ $...$ $x sub n$ $y sub n$' + +where c is not one of c, e, l, a or ~, @sc{Unix} troff will treat each of the +$x sub i$ as a horizontal quantity, and each of the $y sub i$ as a +vertical quantity and will assume that the width of the drawn object is +$sum from i=1 to n x sub i$, and that the height is $sum from i=1 to n y +sub i$. (The assumption about the height can be seen by examining the +st and sb registers after using such a D command in a \w escape +sequence.) This rule also holds for all the original drawing commands +with the exception of De. For the sake of compatibility GNU troff also +follows this rule, even though it produces an ugly result in the case of +the Df, Dt, and, to a lesser extent, DE commands. Thus after executing +a D command of the form + +Dc $x sub 1$ $y sub 1$ $x sub 2$ $y sub 2$ $...$ $x sub n$ $y sub n$\n + +the current position should be increased by $( sum from i=1 to n x sub i +, sum from i=1 to n y sub i )$. + +@subsection Line Continuation + +There is a continuation convention which permits the argument to the x X +command to contain newlines: when outputting the argument to the x X +command, GNU troff will follow each newline in the argument with a + +character (as usual, it will terminate the entire argument with a +newline); thus if the line after the line containing the x X command +starts with +, then the newline ending the line containing the x X +command should be treated as part of the argument to the x X command, +the + should be ignored, and the part of the line following the + should +be treated like the part of the line following the x X command. + + + + +@node Font Files, , gtroff Output, File formats +@section Font Files +@cindex font files +@cindex files, font + + +The groff font format is roughly a superset of the ditroff font +format. Unlike the ditroff font format, there is no associated binary +format. The font files for device name are stored in a directory +@file{dev@var{name}}. There are two types of file: a device +description file called @file{DESC} and for each font @samp{F} a font +file called @file{F}. These are text files; there is no associated +binary format. + +@subsection @file{DESC} file format +@pindex DESC + +The @file{DESC} file can contain the following types of line: + +@table @code +@item res @var{n} +There are @var{n} machine units per inch. +@item hor @var{n} +The horizontal resolution is @var{n} machine units. +@item vert @var{n} +The vertical resolution is @var{n} machine units. +@item sizescale @var{n} +The scale factor for pointsizes. By default this has a value of 1. One +scaled point is equal to one point/@var{n}. The arguments to the +@code{unitwidth} and @code{sizes} commands are given in scaled points. +@xref{Fractional Type Sizes}, for more information. +@item unitwidth @var{n} +Quantities in the font files are given in machine units for fonts whose +point size is @var{n} scaled points. +@item tcommand +This means that the postprocessor can handle the @code{t} and +@code{u} output commands. +@item sizes @var{s1} @var{s2}@dots{}@var{sn} 0 +This means that the device has fonts at @var{s1}, @var{s2}, +@dots{}@var{sn} scaled points. The list of sizes must be terminated +by a 0. Each @var{si} can also be a range of +sizes @var{m}-@var{n}. The list can extend over more than one line. +@item styles @var{S1 S2@dots{}Sm} +The first @var{m} font positions will be associated with styles +@var{S1}@dots{}@var{Sm}. +@item fonts @var{n} @var{F1 F2 F3@dots{}Fn} +Fonts @var{F1@dots{}Fn} will be mounted in the font positions +@var{m}+1, @dots{}, @var{m}+@var{n} where @var{m} +is the number of styles. This command may extend over more than one +line. A font name of 0 will cause no font to be mounted on the +corresponding font position. +@item family @var{fam} +The default font family is @var{fam}. +@item charset +This line and everything following in the file are ignored. It is +allowed for the sake of backwards compatibility. +@end table + +The @code{res}, @code{unitwidth}, @code{fonts} and @code{sizes} lines +are compulsory. Other commands are ignored by troff but may be used +by postprocessors to store arbitrary information about the device in +the @file{DESC} file. + + +@subsection Font file format + +A font file has two sections. The first section is a sequence of lines +each containing a sequence of blank delimited words; the first word in +the line is a key, and subsequent words give a value for that key. + +@table @code +@item name @var{F} +The name of the font is @var{F}. +@item spacewidth @var{n} +The normal width of a space is @var{n}. +@item slant @var{n} +The characters of the font have a slant of @var{n} degrees. +(Positive means forward.) +@item ligatures @var{lig1} @var{lig2}@dots{}@var{lign} [0] +Characters @var{lig1}, @var{lig2}, @dots{}, @var{lign} are ligatures; +possible ligatures are ff, fi, fl and ffl. For backwards +compatibiliy, the list of ligatures may be terminated with a 0. The +list of ligatures may not extend over more than one line. +@item special +The font is special; this means that when a character is requested that +is not present in the current font, it will be searched for in any +special fonts that are mounted. +@end table + +Other commands are ignored by troff but may be used by postprocessors to +store arbitrary information about the font in the font file. + +The first section can contain comments which start with the # character +and extend to the end of a line. + +The second section contains one or two subsections. It must contain a +@code{charset} subsection and it may also contain a @code{kernpairs} +subsection. These subsections can appear in any order. Each +subsection starts with a word on a line by itself. + +The word @code{charset} starts the @code{charset} subsection. The +@code{charset} line is followed by a sequence of lines. Each line +gives information for one character. A line comprises a number of +fields separated by blanks or tabs. The format is + +@display +@var{name} @var{metrics} @var{type} @var{code} @var{comment} +@end display + +@var{name} identifies the character: if @var{name} is a single +character @var{c} then it corresponds to the groff input character +@var{c}; if it is of the form @samp{\@var{c}} where @var{c} is a +single character, then it corresponds to the groff input character +@samp{\@var{c}}; otherwise it corresponds to the groff input character +@samp{\[@var{name}]} (if it is exactly two characters @var{xx} it can +be entered as @samp{\(@var{xx}}.) Groff supports eight bit characters; +however some utilities has difficulties with eight bit characters. +For this reason, there is a convention that the @var{name} +@samp{char@var{n}} is equivalent to the single character whose code is +@var{n}. For example, @samp{char163} would be equivalent to the +character with @var{code} 163 which is the pounds sterling sign in ISO +Latin-1 character set. The name @samp{---} is special and indicates +that the character is unnamed; such characters can only be used by +means of the @code{\N} escape sequence in troff. + +The @var{type} field gives the character type: + +@table @code +@item 1 +means the character has an descender, for example, p; +@item 2 +means the character has an ascender, for example, b; +@item 3 +means the character has both an ascender and a descender, for example, +@samp{(}. +@end table + +The @var{code} field gives the code which the postprocessor uses to +print the character. The character can also be input to groff using +this code by means of the @code{\N} escape sequence. The code can be any +integer. If it starts with a 0 it will be interpreted as octal; if it +starts with 0x or 0X it will be intepreted as hexdecimal. + +Anything on the line after the @var{code} field will be ignored. + +The @var{metrics} field has the form: + +@smallexample +@var{width[,height[,depth[,italic_correction[,left_italic_correction[,subscript_correction]]]]]} +@end smallexample + +There must not be any spaces between these subfields. Missing +subfields are assumed to be 0. The subfields are all decimal +integers. Since there is no associated binary format, these values +are not required to fit into a variable of type @samp{char} as they +are in ditroff. The @var{width} subfields gives the width of the +character. The @var{height} subfield gives the height of the +character (upwards is positive); if a character does not extend above +the baseline, it should be given a zero height, rather than a negative +height. The @var{depth} subfield gives the depth of the character, +that is, the distance below the lowest point below the baseline to +which the character extends (downwards is positive); if a character +does not extend below above the baseline, it should be given a zero +depth, rather than a negative depth. The @var{italic_correction} +subfield gives the amount of space that should be added after the +character when it is immediately to be followed by a character from a +roman font. The @var{left_italic_correction} subfield gives the +amount of space that should be added before the character when it is +immediately to be preceded by a character from a roman font. The +@var{subscript_correction} gives the amount of space that should be +added after a character before adding a subscript. This should be less +than the italic correction. + +A line in the @code{charset} section can also have the format + +@example +@var{name} " +@end example + +This indicates that @var{name} is just another name for the character +mentioned in the preceding line. + +The word @code{kernpairs} starts the kernpairs section. This contains a +sequence of lines of the form: + +@display +@var{c1 c2 n} +@end display + +This means that when character @var{c1} appears next to character +@var{c2} the space between them should be increased by @var{n}. Most +entries in kernpairs section will have a negative value for @var{n}. + + + +@node Installation, Request Index, File formats, Top +@chapter Installation +@cindex installation + + + +@node Request Index, Register Index, Installation, Top +@chapter Request Index + +@printindex fn + + +@node Register Index, String Index, Request Index, Top +@chapter Register Index + +@printindex vr + + +@node String Index, Macro Index, Register Index, Top +@chapter String Index + + + +@node Macro Index, Program Index, String Index, Top +@chapter Macro Index + + + +@node Program Index, Concept Index, Macro Index, Top +@chapter Program Index + +@printindex pg + + + +@node Concept Index, , Program Index, Top +@chapter Concept Index + +@printindex cp + + + +@summarycontents +@contents +@bye diff --git a/gnu/usr.bin/groff/grohtml/ChangeLog b/gnu/usr.bin/groff/grohtml/ChangeLog new file mode 100644 index 00000000000..e7c1265769e --- /dev/null +++ b/gnu/usr.bin/groff/grohtml/ChangeLog @@ -0,0 +1,104 @@ +1999-12-21 Werner LEMBERG <wl@gnu.org> + + * grohtml.man: Fixed copyright year. + +1999-12-15 Gaius Mulley <gaius@glam.ac.uk> + + * html.cc: Some other fixes. + +1999-12-13 Gaius Mulley <gaius@glam.ac.uk> + + * html.cc (main): Added new option `-x' to help debugging tables. + +1999-12-11 Gaius Mulley <gaius@glam.ac.uk> + + * html.cc: Fixed image position bugs. However, three major bugs + remain: Firstly, grohtml sometimes miscalculates the end of an + html table resulting in text which appears twice. Secondly, + equation numbers are not handled correctly. Thirdly, equation + macros and pic macros can confuse grohtml; this can be seen by + nested `graphic-start's -- I believe the best method to solve this + is to detect .EQ, .EN, .TS, .TE, .PS, .PE sequences in troff and + add the graphic-start special character at this point. + + * grohtml.man: Minor fixes. + +1999-11-29 Gaius Mulley <gaius@glam.ac.uk> + + * design.ms: More updates; added some basic introductional + information. + + * html.cc: Fixed more bugs mainly in the table handling code. + Making the code terminate a table at the correct position. + Indented .IPs appear to work now. Region ends also correctly + terminate tables. + +1999-11-16 Gaius Mulley <gaius@glam.ac.uk> + + * design.ms, grohtml.man: Updated. + + * html.cc, ordered_list.h: Fixed many bugs in the table handling + code. Reverted the -t switch so that table handling code is used + by default and users must turn it off with -t. + + Manual page generation using `groff -Thtml -man' is much better + due in large part to the table code and minor alterations in + tmac.an. + +1999-10-30 Gaius Mulley <gaius@glam.ac.uk> + + * implemented auto formatting and introduced html table + code. Fixed several text handling bugs and grohtml will + detect centered lines - an offshoot of the html table code. + + * reverted meaning of grohtml's `-a' switch: using -a means that + output will be preformatted. + +1999-10-05 Gaius Mulley <gaius@glam.ac.uk> + + * Introduced command line options -r to determine the resolution + of generated images, -I to determine the format of images + generated. + + * Fixed many bugs to do with superscripts, subscripts, + indentation, font changes, and extraneous spaces. + + * Fixed bug in determining the range of polygons and splines. + + * Updated the manual page to reflect the new options. + + * The default image type is png format, however this will only + work if you have a gs with a png output device. If you don't have + a gs with this ability you can either reconfigure html to generate + gif images by default (alter a #define in html.cc). Or + alternatively you can use the -Igif option. + +1999-09-27 Werner LEMBERG <wl@gnu.org> + + * html.cc (move_horizontal): Fonts have changed one character too + late. + +1999-09-26 Werner LEMBERG <wl@gnu.org> + + * grohtml.man: Minor cosmetic fixes. + +1999-09-25 Gaius Mulley <gaius@glam.ac.uk> + + * grohtml.man, html.cc: Rewrite of the html text component. Basic + font faces supported together with font types. Superscript and + subscript have also been implemented. Temporarily removed the + -P-a switch on grohtml as it is not working (never worked). This + is the next `to do'. Added a simple macro tmac.arkup which + contains simple html features. This macro needs further work. + Arc, spline, polygon fill have all been added and arc max/min xy + limits are calculated, the same needs to be done for spline. Many + bugs have been fixed regarding basic html text. + + * design.ms: New file describing how html.cc works. + +Aug 1999 + + Initial release, very basic html text generated, quite ugly text + is generated according to many reports :-) Equations, tables, + pictures generate gif files via gs and ppmquant, ppmtogif, grops. + diff --git a/gnu/usr.bin/groff/grohtml/Makefile.dep b/gnu/usr.bin/groff/grohtml/Makefile.dep new file mode 100644 index 00000000000..782d72116ee --- /dev/null +++ b/gnu/usr.bin/groff/grohtml/Makefile.dep @@ -0,0 +1,3 @@ +html.o: html.cc ordered_list.h ../include/driver.h ../include/errarg.h \ + ../include/error.h ../include/font.h ../include/printer.h \ + ../include/lib.h diff --git a/gnu/usr.bin/groff/grohtml/Makefile.sub b/gnu/usr.bin/groff/grohtml/Makefile.sub new file mode 100644 index 00000000000..3faa1e30125 --- /dev/null +++ b/gnu/usr.bin/groff/grohtml/Makefile.sub @@ -0,0 +1,6 @@ +PROG=grohtml +MAN1=grohtml.n +XLIBS=$(LIBDRIVER) $(LIBGROFF) +MLIB=$(LIBM) +OBJS=html.o +CCSRCS=html.cc diff --git a/gnu/usr.bin/groff/grohtml/design.ms b/gnu/usr.bin/groff/grohtml/design.ms new file mode 100644 index 00000000000..e62e2233096 --- /dev/null +++ b/gnu/usr.bin/groff/grohtml/design.ms @@ -0,0 +1,156 @@ +.nr PS 12 +.nr VS 14 +.LP +.TL +Design of grohtml +.sp 1i +.SH +What is grohtml +.LP +Grohtml is a back end for groff which generates html. +The aim of grohtml is to produce respectible html given +fairly typical groff input. +.SH +Limitations of grohtml +.LP +Although basic text can be translated +in a straightforward fashion there are some areas where grohtml +has to try and guess text relationship. In particular whenever +grohtml encounters text tables and indented paragraphs or +two column mode it will try and utilize the html table construct +to preserve columns. Grohtml also attempts to work out which +lines should be automatically formatted by the browser. +Ultimately in trying to make reasonable guesses most of the time +it will make mistakes occasionally. +.PP +Tbl, pic, eqn's are also generated using images which may be +considered a limitation. +.SH +Overview of html.cc +.LP +This file briefly provides an overview of how html.cc operates. +The html device driver works as follows: +.IP (i) .5i +firstly it creates a linked list of all words on a page. +.IP (ii) .5i +it runs through the page and finds the left most margin. Later +on when generating the page it removes the margin. +.IP (iii) .5i +scans a page and builds two kinds of regions ascii text and graphical. +The graphical regions consist of tbl's, eqn's, pic's +(basically anything that cannot be textually displayed). +It will scan through a page to find lines (such as footer etc) +and places these into tiny graphical regions. Certain fonts +also are treated as a graphical region - as html has no easy +equivalent. For example Greek math symbols. +.LP +Finally all graphical regions are translated into png files and +all text regions into html text. +.PP +To give grohtml a sporting chance of accuratly deciding which +is a graphical region and which is text, the front end programs +tbl, eqn, pic have all been tweeked to encapsulate pictures, tables +and equations with the following lines: +.sp +.nf +\f[CR]\&.if '\\*(.T'html' \\X(graphic-start(\c + +\&.if '\\*(.T'html' \\X(graphic-end(\c +\fP +.fi +.sp +these appear to grohtml as: +.sp +.nf +\f[CR]\&x X graphic-start + +\&... + +\&x X graphic-end\fP +.fi +.sp +.LP +In addition to graphic-start and graphic-end there are two +other "special characters" which are used. +.sp +\f[CR]\&x X index:N\fP +.sp +where N is a number. The purpose of this sequence is to stop +devhtml from automatically producing links to headings which +have a header level >N. +The line: +.sp +\f[CR]\&x X html:STRING\fR +.sp +.LP +allows a STRING to be passed through to the output file with +no processing whatsoever. Ie it allows users to include html +commands, via macro, such as: +.sp +\f[CR]\&.URL "Latest Emacs" "ftp://somewonderful.gnu.software"\fP +.sp +.LP +Where the URL macro bundles the info into STRING above. +For more info consult: \f[CR]tmac/tmac.arkup\fP. +.PP +While scanning through a page the html device copies headings and titles +into a list of links which are later written to the beginning +of the html document. +.SH +Table handling code +.LP +Provided that the -t option is not present when grohtml is run the grohtml +driver will attempt to find textual tables and generate html tables. +This allows .RS and .RE commands to operate with auto formatting. It also +should grohtml to process .2C correctly. However, the table handling code +has to examine the troff output and \fIguess\fR when a table starts and +finishes. It is well to know the limitations of this approach as it +sometimes makes the wrong decision. +.LP +Here are some of the rules that grohtml uses for terminating a html table: +.LP +.IP "(i)" .5i +A table will be terminated when grohtml finds line which is all in bold +font (it believes that this is a header which is outside of a table). +This might be considered incorrect behaviour especially if you use .2C +which generates a heading on the left column when the corresponding +right row is blank. +.IP "(ii)" .5i +A table is terminated when grohtml sees that the complete line is +has been spanned by words. Ie no gaps exist. +.IP "(nb)" .5i +the documentation about these rules is particularly incomplete and needs finishing +when time prevails. +.SH +To do +.LP +.IP (i) .5i +finish working out the max and min x, y, extents for splines. +.IP (ii) .5i +check and test thoroughly all the character descriptions in devhtml +(originally taken from devX100) +.IP (iii) .5i +improve tmac.arkup +.IP (vi) .5i +also improve documentation. +.IP (v) .5i +fix the bugs which are exposed by Eric Raymonds pic guide, +\fBMaking Pictures With GNU PIC\fR. It appears that grohtml becomes confused +about which sections of the document are text and which sections need +to be rendered as an image. +.IP (vi) .5i +it would be nice to modularise the source. A natural division might be +to extract the table handling code from html.cc into table.cc. +The table.cc could be expanded to recognise output from tbl and try +and generate html tables with lines/rules/boxes. The code as it stands +should cope with very simple plain text tables. But of course at present +it does not get a chance to do this because the output of gtbl is +bracketed by \fCgraphic-start\fR and \fCgraphic-end\fR. +.IP (vii) .5i +introduce anti aliasing for the images as mentioned by Werner. +.SH +Dependencies +.LP +Grohtml is dependent upon grops, gs which are invoked to +generate all png files. Png files are generated whenever a table, picture, +equation or line is encountered. diff --git a/gnu/usr.bin/groff/grohtml/grohtml.man b/gnu/usr.bin/groff/grohtml/grohtml.man new file mode 100644 index 00000000000..63b05edd358 --- /dev/null +++ b/gnu/usr.bin/groff/grohtml/grohtml.man @@ -0,0 +1,173 @@ +.ig \"-*- nroff -*- +Copyright (C) 1999 Free Software Foundation, Inc. + +Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be included in +translations approved by the Free Software Foundation instead of in +the original English. +.. +.\" Like TP, but if specified indent is more than half +.\" the current line-length - indent, use the default indent. +.de Tp +.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP +.el .TP "\\$1" +.. +.TH GROHTML @MAN1EXT@ "@MDATE@" "Groff Version @VERSION@" +.SH NAME +grohtml \- html driver for groff +.SH SYNOPSIS +.B grohtml +[ +.B \-atvdgm? +] [ +.BI \-F dir +] [ +.BI \-I imagetype +] [ +.BI \-r resolution +] [ +.IR files \|.\|.\|. +] +.SH DESCRIPTION +.B grohtml +translates the output of GNU +.B troff +to html. +Normally +.B grohtml +should be invoked by using the groff command with a +.B \-Thtml +option. +If no files are given, +.B grohtml +will read the standard input. +A filename of +.B \- +will also cause +.B grohtml +to read the standard input. +Html output is written to the standard output. +When +.B grohtml +is run by +.B groff +options can be passed to +.B grohtml +using the +.B groff +.B \-P +option. +.SH OPTIONS +.TP +.B \-a +force +.B grohtml +to generate html line breaks in the same position as troff dictates. +Without this option +.B grohtml +generates text in paragraphs which is formatted by the html browser. +.TP +.B \-d +turn on internal debugging. +.TP +.B \-g +tell +.B grohtml +not to try and guess titles and headings. +By using this flag together with the -m and -a flag +.B grohtml +will treat the html browser as a printer, not as a formatter. +.TP +.B \-m +leave margins alone. +.B grohtml +will not remove left margins. +.TP +.B \-t +forbids +.B grohtml +from generating html tables when implementing indentation and tabular text. +.B grohtml +can implement .IP by tables or html indents. +However if .2C is used it can only be sensibly converted to html using a +table structure. +As a few known bugs still exist with the html table code this option is +present to supress execution of this development code. +The default in +.B grohtml +is that html tables are generated when appropriate. +.TP +.BI \-F dir +Search the directory +.IB dir /dev name +for font and device description files; +.I name +is the name of the device, usually +.BR html . +.TP +.BI \-I imagetype +select the type of image generated when grohtml encounters an equation, +table, or picture. +By default this is png256. +Legal image types are: gif and any of the png formats which are supported by +ghostscript gs(1). +.TP +.BI \-r resolution +select the resolution for all images. +By default this is 80 pixels per inch. +Example: -r100 indicates 100 pixels per inch. +.TP +.B \-v +Print the version number. +.TP +.B \-? +Display usage. +.SH USAGE +There are styles called +.BR R , +.BR I , +.BR B , +and +.B BI +mounted at font positions 1 to 4. +It is advisable to invoke groff with the -mhtml macro set, which turns off +headers, footers, and hyphenation; additionally, it will right justify text. +.SH DEPENDENCIES +.B grohtml +is dependent upon grops and gs. +If +.B grohtml +has been configured to generate gif files then it is further dependent upon, +ppmtogif, and ppmquant. +However if it has been configured to generate png files (the default) then +it is dependent upon gs having a png output device. +Images are generated whenever a table, picture, equation or line is +encountered. +.SH BUGS +This is still very alpha. +At least three major bugs remain: +Firstly, +.B grohtml +sometimes miscalculates the end of an html table resulting in text which +appears twice. +Secondly equation numbers are not handled correctly. +Thirdly equation macros and pic macros can confuse +.BR grohtml . +.SH "SEE ALSO" +.BR afmtodit (@MAN1EXT@), +.BR groff (@MAN1EXT@), +.BR @g@troff (@MAN1EXT@), +.BR psbb (@MAN1EXT@), +.BR groff_out (@MAN5EXT@), +.BR groff_font (@MAN5EXT@), +.BR groff_char (@MAN7EXT@) diff --git a/gnu/usr.bin/groff/grohtml/html.cc b/gnu/usr.bin/groff/grohtml/html.cc new file mode 100644 index 00000000000..26b9279da69 --- /dev/null +++ b/gnu/usr.bin/groff/grohtml/html.cc @@ -0,0 +1,5183 @@ +// -*- C++ -*- +/* Copyright (C) 1999 Free Software Foundation, Inc. + * + * Gaius Mulley (gaius@glam.ac.uk) wrote grohtml + * but it owes a huge amount of ideas and raw code from + * James Clark (jjc@jclark.com) grops/ps.cc. + */ + +/* +This file is part of groff. + +groff is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +groff is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License along +with groff; see the file COPYING. If not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "driver.h" +#include "stringclass.h" +#include "cset.h" + +#include "html.h" +#include <time.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include "ordered_list.h" + +#if !defined(TRUE) +# define TRUE (1==1) +#endif +#if !defined(FALSE) +# define FALSE (1==0) +#endif + +#define MAX_TEMP_NAME 1024 +#define MAX_STRING_LENGTH 4096 + +#define Y_FUDGE_MARGIN +0.83 +#define A4_PAGE_LENGTH (11.6944-Y_FUDGE_MARGIN) +#define DEFAULT_IMAGE_RES 80 +#define IMAGE_BOARDER_PIXELS 10 +#define MAX_WORDS_PER_LINE 1000 // only used for table indentation +#define GAP_SPACES 3 // how many spaces needed to guess a gap? +#define GAP_WIDTH_ONE_LINE 2 // 1/GAP_WIDTH_ONE_LINE inches required for one line table +#define CENTER_TOLERANCE 2 // how many pixels off center will we think a line or region is centered +#define MIN_COLUMN 7 // minimum column size pixels + + +/* + * Only uncomment one of the following to determine default image type. + */ + +#define IMAGE_DEFAULT_PNG +/* #define IMAGE_DEFAULT_GIF */ + + +#if defined(IMAGE_DEFAULT_GIF) +static enum { gif, png } image_type = gif; +static char *image_device = "gif"; +#elif defined(IMAGE_DEFAULT_PNG) +static enum { gif, png } image_type = png; +static char *image_device = "png256"; +#else +# error "you must define either IMAGE_DEFAULT_GIF or IMAGE_DEFAULT_PNG" +#endif + +static int debug_on = FALSE; +static int guess_on = TRUE; +static int margin_on = FALSE; +static int auto_on = TRUE; +static int table_on = TRUE; +static int image_res = DEFAULT_IMAGE_RES; +static int debug_table_on = FALSE; + +static int linewidth = -1; + +#define DEFAULT_LINEWIDTH 40 /* in ems/1000 */ +#define MAX_LINE_LENGTH 72 +#define FILL_MAX 1000 + +void stop () {} + + +/* + * start with a few favorites + */ + +static int min (int a, int b) +{ + if (a < b) { + return( a ); + } else { + return( b ); + } +} + +static int max (int a, int b) +{ + if (a > b) { + return( a ); + } else { + return( b ); + } +} + + +/* + * is_subsection - returns TRUE if a1..a2 is within b1..b2 + */ + +static int is_subsection (int a1, int a2, int b1, int b2) +{ + // easier to see whether this is not the case + return( !((a1 < b1) || (a1 > b2) || (a2 < b1) || (a2 > b2)) ); +} + + +/* + * is_intersection - returns TRUE if range a1..a2 intersects with b1..b2 + */ + +static int is_intersection (int a1, int a2, int b1, int b2) +{ + // again easier to prove NOT outside limits + return( ! ((a1 > b2) || (a2 < b1)) ); +} + + +/* + * is_digit - returns TRUE if character, ch, is a digit. + */ + +static int is_digit (char ch) +{ + return( (ch >= '0') && (ch <= '9') ); +} + + +/* + * more_than_line_break - returns TRUE should v1 and v2 differ by more than + * a simple line break. + */ + +static int more_than_line_break (int v1, int v2, int size) +{ + return( abs(v1-v2)>size ); +} + + +/* + * the class and methods for styles + */ + +struct style { + font *f; + int point_size; + int font_no; + int height; + int slant; + style (); + style (font *, int, int, int, int); + int operator == (const style &) const; + int operator != (const style &) const; +}; + +style::style() + : f(0) +{ +} + +style::style(font *p, int sz, int h, int sl, int no) + : f(p), point_size(sz), height(h), slant(sl), font_no(no) +{ +} + +int style::operator==(const style &s) const +{ + return (f == s.f && point_size == s.point_size + && height == s.height && slant == s.slant); +} + +int style::operator!=(const style &s) const +{ + return !(*this == s); +} + + +/* + * the class and methods for retaining ascii text + */ + +struct char_block { + enum { SIZE = 256 }; + char buffer[SIZE]; + int used; + char_block *next; + + char_block(); +}; + +char_block::char_block() +: next(0), used(0) +{ +} + +class char_buffer { +public: + char_buffer(); + ~char_buffer(); + char *add_string(char *, unsigned int); +private: + char_block *head; + char_block *tail; +}; + +char_buffer::char_buffer() +: head(0), tail(0) +{ +} + +char_buffer::~char_buffer() +{ + while (head != 0) { + char_block *temp = head; + head = head->next; + delete temp; + } +} + +char *char_buffer::add_string (char *s, unsigned int length) +{ + int i=0; + unsigned int old_used; + + if (tail == 0) { + tail = new char_block; + head = tail; + } else { + if (tail->used + length+1 > char_block::SIZE) { + tail->next = new char_block; + tail = tail->next; + } + } + // at this point we have a tail which is ready for the string. + if (tail->used + length+1 > char_block::SIZE) { + fatal("need to increase char_block::SIZE"); + } + + old_used = tail->used; + do { + tail->buffer[tail->used] = s[i]; + tail->used++; + i++; + length--; + } while (length>0); + + // add terminating nul character + + tail->buffer[tail->used] = '\0'; + tail->used++; + + // and return start of new string + + return( &tail->buffer[old_used] ); +} + +/* + * the classes and methods for maintaining pages and text positions and graphic regions + */ + +class text_glob { +public: + int is_less (text_glob *a, text_glob *b); + text_glob (style *s, char *string, unsigned int length, + int min_vertical, int min_horizontal, + int max_vertical, int max_horizontal, int is_command, int is_html); + text_glob (void); + ~text_glob (void); + + style text_style; + char *text_string; + unsigned int text_length; + int minv, maxv, minh, maxh; + int is_raw_command; // should the text be sent directly to the device? + int is_html_command; // is the raw command definitely for the html device ie not an eqn? +}; + +text_glob::text_glob (style *s, char *string, unsigned int length, + int min_vertical, int min_horizontal, + int max_vertical, int max_horizontal, int is_command, int is_html) + : text_style(*s), text_string(string), text_length(length), + minv(min_vertical), minh(min_horizontal), maxv(max_vertical), maxh(max_horizontal), + is_raw_command(is_command), is_html_command(is_html) +{ +} + +text_glob::text_glob () + : text_string(0), text_length(0), minv(-1), maxv(-1), minh(-1), maxh(-1), + is_raw_command(FALSE), is_html_command(FALSE) +{ +} + +text_glob::~text_glob () +{ +} + +int text_glob::is_less (text_glob *a, text_glob *b) +{ + if (is_intersection(a->minv, a->maxv, b->minv, b->maxv)) { + return( a->minh < b->minh ); + } else { + return( a->maxv < b->maxv ); + } +} + +struct xycoord { + int x; + int y; +}; + +class graphic_glob { +public: + int is_less (graphic_glob *a, graphic_glob *b); + graphic_glob (int troff_code); + graphic_glob (void); + ~graphic_glob (void); + + int minv, maxv, minh, maxh; + int xc, yc; + int nopoints; // number of points allocated in array below + struct xycoord *point; + int size; + int fill; + int code; +}; + +graphic_glob::graphic_glob () + : minv(-1), maxv(-1), minh(-1), maxh(-1), code(0), size(0), nopoints(0), point(0) +{ +} + +graphic_glob::~graphic_glob () +{ + if (point != 0) { + free(point); + } +} + +graphic_glob::graphic_glob (int troff_code) + : minv(-1), maxv(-1), minh(-1), maxh(-1), code(troff_code), size(0), nopoints(0), point(0) +{ +} + +int graphic_glob::is_less (graphic_glob *a, graphic_glob *b) +{ + return( (a->minv < b->minv) || ((a->minv == b->minv) && (a->minh < b->minh)) ); +} + +class region_glob { +public: + region_glob (void); + ~region_glob (void); + int is_less (region_glob *a, region_glob *b); + + int minv, maxv, minh, maxh; +}; + +int region_glob::is_less (region_glob *a, region_glob *b) +{ + return( (a->minv < b->minv) || ((a->minv == b->minv) && (a->minh < b->minh)) ); +} + +region_glob::region_glob (void) + : minv(-1), maxv(-1), minh(-1), maxh(-1) +{ +} + +region_glob::~region_glob (void) +{ +} + +class page { +public: + page (void); + void add (style *s, char *string, unsigned int length, + int min_vertical, int min_horizontal, + int max_vertical, int max_horizontal); + void add_html_command (style *s, char *string, unsigned int length, + int min_vertical, int min_horizontal, + int max_vertical, int max_horizontal); + void add_special_char (style *s, char *string, unsigned int length, + int min_vertical, int min_horizontal, + int max_vertical, int max_horizontal); + void add_line (int code, int x1, int y1, int x2, int y2, int size, int fill); + void add_arc (int code, int xc, int yc, int *p, double *c, int size, int fill); + void add_polygon (int code, int np, int *p, int oh, int ov, int size, int fill); + void add_spline (int code, int xc, int yc, int np, int *p, int size, int fill); + void calculate_region (void); + int is_in_region (graphic_glob *g); + int can_grow_region (graphic_glob *g); + void make_new_region (graphic_glob *g); + int has_line (region_glob *r); + int has_word (region_glob *r); + int no_raw_commands (int minv, int maxv); + + // and the data + + ordered_list <region_glob> regions; // squares of bitmapped pics,eqn,tbl's + ordered_list <text_glob> words; // position of words on page + ordered_list <graphic_glob> lines; // position of lines on page + char_buffer buffer; // all characters for this page + int is_in_graphic; // should graphics and words go below or above + ordered_list <text_glob> region_words; // temporary accumulation of words in a region + ordered_list <graphic_glob> region_lines; // (as above) and used so that we can determine + // the regions vertical limits +}; + +page::page() + : is_in_graphic(FALSE) +{ +} + +void page::add (style *s, char *string, unsigned int length, + int min_vertical, int min_horizontal, + int max_vertical, int max_horizontal) +{ + if (length > 0) { + text_glob *g=new text_glob(s, buffer.add_string(string, length), length, + min_vertical, min_horizontal, max_vertical, max_horizontal, FALSE, FALSE); + if (is_in_graphic) { + region_words.add(g); + } else { + words.add(g); + } + } +} + +/* + * add_html_command - it only makes sense to add html commands when we are not inside + * a graphical entity. + */ + +void page::add_html_command (style *s, char *string, unsigned int length, + int min_vertical, int min_horizontal, + int max_vertical, int max_horizontal) +{ + if ((length > 0) && (! is_in_graphic)) { + text_glob *g=new text_glob(s, buffer.add_string(string, length), length, + min_vertical, min_horizontal, max_vertical, max_horizontal, TRUE, TRUE); + words.add(g); + } +} + +/* + * add_special_char - it only makes sense to add special characters when we are inside + * a graphical entity. + */ + +void page::add_special_char (style *s, char *string, unsigned int length, + int min_vertical, int min_horizontal, + int max_vertical, int max_horizontal) +{ + if ((length > 0) && (is_in_graphic)) { + text_glob *g=new text_glob(s, buffer.add_string(string, length), length, + min_vertical, min_horizontal, max_vertical, max_horizontal, TRUE, FALSE); + region_words.add(g); + } +} + +void page::add_line (int code, int x1, int y1, int x2, int y2, int size, int fill) +{ + graphic_glob *g = new graphic_glob(code); + + g->minh = min(x1, x2); + g->maxh = max(x1, x2); + g->minv = min(y1, y2); + g->maxv = max(y1, y2); + g->point = (struct xycoord *)malloc(sizeof(xycoord)*2); + g->nopoints = 2; + g->point[0].x = x1 ; + g->point[0].y = y1 ; + g->point[1].x = x2 ; + g->point[1].y = y2 ; + g->xc = 0; + g->yc = 0; + g->size = size; + g->fill = fill; + + if (is_in_graphic) { + region_lines.add(g); + } else { + lines.add(g); + } +} + +/* + * assign_min_max_for_arc - works out the smallest box that will encompass an + * arc defined by: origin: g->xc, g->xc + * and vector (p[0], p[1]) and (p[2], p[3]) + */ + +void assign_min_max_for_arc (graphic_glob *g, int *p, double *c) +{ + int radius = (int) sqrt(c[0]*c[0]+c[1]*c[1]); + int xv1 = p[0]; + int yv1 = p[1]; + int xv2 = p[2]; + int yv2 = p[3]; + int x1 = g->xc+xv1; + int y1 = g->yc+yv1; + int x2 = g->xc+xv1+xv2; + int y2 = g->yc+yv1+yv2; + + // firstly lets use the 'circle' limitation + g->minh = x1-radius; + g->maxh = x1+radius; + g->minv = y1-radius; + g->maxv = y1+radius; + + // incidentally I'm sure there is a better way to do this, but I don't know it + // please can someone let me know or "improve" this function + + // now see which min/max can be reduced and increased for the limits of the arc + // + // + // Q2 | Q1 + // -----+----- + // Q3 | Q4 + // + + + if ((xv1>=0) && (yv1>=0)) { + // first vector in Q3 + if ((xv2>=0) && (yv2>=0)) { + // second in Q1 + g->maxh = x2; + g->minv = y1; + } else if ((xv2<0) && (yv2>=0)) { + // second in Q2 + g->maxh = x2; + g->minv = y1; + } else if ((xv2>=0) && (yv2<0)) { + // second in Q4 + g->minv = min(y1, y2); + } else if ((xv2<0) && (yv2<0)) { + // second in Q3 + if (x1>=x2) { + g->minh = x2; + g->maxh = x1; + g->minv = min(y1, y2); + g->maxv = max(y1, y2); + } else { + // xv2, yv2 could all be zero? + } + } + } else if ((xv1>=0) && (yv1<0)) { + // first vector in Q2 + if ((xv2>=0) && (yv2>=0)) { + // second in Q1 + g->maxh = max(x1, x2); + g->minh = min(x1, x2); + g->minv = y1; + } else if ((xv2<0) && (yv2>=0)) { + // second in Q2 + if (x1<x2) { + g->maxh = x2; + g->minh = x1; + g->minv = min(y1, y2); + g->maxv = max(y1, y2); + } else { + // otherwise almost full circle anyway + } + } else if ((xv2>=0) && (yv2<0)) { + // second in Q4 + g->minv = y2; + g->minh = x1; + } else if ((xv2<0) && (yv2<0)) { + // second in Q3 + g->minh = min(x1, x2); + } + } else if ((xv1<0) && (yv1<0)) { + // first vector in Q1 + if ((xv2>=0) && (yv2>=0)) { + // second in Q1 + if (x1<x2) { + g->minh = x1; + g->maxh = x2; + g->minv = min(y1, y2); + g->maxv = max(y1, y2); + } else { + // nearly full circle + } + } else if ((xv2<0) && (yv2>=0)) { + // second in Q2 + g->maxv = max(y1, y2); + } else if ((xv2>=0) && (yv2<0)) { + // second in Q4 + g->minv = min(y1, y2); + g->maxv = max(y1, y2); + g->minh = min(x1, x2); + } else if ((xv2<0) && (yv2<0)) { + // second in Q3 + g->minh = x2; + g->maxv = y1; + } + } else if ((xv1<0) && (yv1>=0)) { + // first vector in Q4 + if ((xv2>=0) && (yv2>=0)) { + // second in Q1 + g->maxh = max(x1, x2); + } else if ((xv2<0) && (yv2>=0)) { + // second in Q2 + g->maxv = max(y1, y2); + g->maxh = max(x1, x2); + } else if ((xv2>=0) && (yv2<0)) { + // second in Q4 + if (x1>=x2) { + g->minv = min(y1, y2); + g->maxv = max(y1, y2); + g->minh = min(x1, x2); + g->maxh = max(x2, x2); + } else { + // nearly full circle + } + } else if ((xv2<0) && (yv2<0)) { + // second in Q3 + g->maxv = max(y1, y2); + g->minh = min(x1, x2); + g->maxh = max(x1, x2); + } + } + // this should *never* happen but if it does it means a case above is wrong.. + + // this code is only present for safety sake + if (g->maxh < g->minh) { + if (debug_on) { + fprintf(stderr, "assert failed minh > maxh\n"); fflush(stderr); + stop(); + } + g->maxh = g->minh; + } + if (g->maxv < g->minv) { + if (debug_on) { + fprintf(stderr, "assert failed minv > maxv\n"); fflush(stderr); + stop(); + } + g->maxv = g->minv; + } +} + +void page::add_arc (int code, int xc, int yc, int *p, double *c, int size, int fill) +{ + graphic_glob *g = new graphic_glob(code); + + g->point = (struct xycoord *)malloc(sizeof(xycoord)*2); + g->nopoints = 2; + g->point[0].x = p[0] ; + g->point[0].y = p[1] ; + g->point[1].x = p[2] ; + g->point[1].y = p[3] ; + g->xc = xc; + g->yc = yc; + g->size = size; + g->fill = fill; + + assign_min_max_for_arc(g, p, c); + + if (is_in_graphic) { + region_lines.add(g); + } else { + lines.add(g); + } +} + + +void page::add_polygon (int code, int np, int *p, int oh, int ov, int size, int fill) +{ + graphic_glob *g = new graphic_glob(code); + int j = 0; + int i; + + g->point = (struct xycoord *)malloc(sizeof(xycoord)*np/2); + g->nopoints = np/2; + + for (i=0; i<g->nopoints; i++) { + g->point[i].x = p[j]; + j++; + g->point[i].y = p[j]; + j++; + } + // now calculate min/max + g->minh = g->point[0].x; + g->minv = g->point[0].y; + g->maxh = g->point[0].x; + g->maxv = g->point[0].y; + for (i=1; i<g->nopoints; i++) { + g->minh = min(g->minh, g->point[i].x); + g->minv = min(g->minv, g->point[i].y); + g->maxh = max(g->maxh, g->point[i].x); + g->maxv = max(g->maxv, g->point[i].y); + } + g->size = size; + g->xc = oh; + g->yc = ov; + g->fill = fill; + + if (is_in_graphic) { + region_lines.add(g); + } else { + lines.add(g); + } +} + +void page::add_spline (int code, int xc, int yc, int np, int *p, int size, int fill) +{ + graphic_glob *g = new graphic_glob(code); + int j = 0; + int i; + + g->point = (struct xycoord *)malloc(sizeof(xycoord)*np/2); + g->nopoints = np/2; + + for (i=0; i<g->nopoints; i++) { + g->point[i].x = p[j]; + j++; + g->point[i].y = p[j]; + j++; + } + // now calculate min/max + g->minh = min(g->point[0].x, g->point[0].x/2); + g->minv = min(g->point[0].y, g->point[0].y/2); + g->maxh = max(g->point[0].x, g->point[0].x/2); + g->maxv = max(g->point[0].y, g->point[0].y/2); + + /* tnum/tden should be between 0 and 1; the closer it is to 1 + the tighter the curve will be to the guiding lines; 2/3 + is the standard value */ + const int tnum = 2; + const int tden = 3; + + for (i=1; i<g->nopoints-1; i++) { + g->minh = min(g->minh, g->point[i].x*tnum/(2*tden)); + g->minv = min(g->minv, g->point[i].y*tnum/(2*tden)); + g->maxh = max(g->maxh, g->point[i].x*tnum/(2*tden)); + g->maxv = max(g->maxv, g->point[i].y*tnum/(2*tden)); + + g->minh = min(g->minh, g->point[i].x/2+(g->point[i+1].x*(tden-tden))/(2*tden)); + g->minv = min(g->minv, g->point[i].y/2+(g->point[i+1].y*(tden-tden))/(2*tden)); + g->maxh = max(g->maxh, g->point[i].x/2+(g->point[i+1].x*(tden-tden))/(2*tden)); + g->maxv = max(g->maxv, g->point[i].y/2+(g->point[i+1].y*(tden-tden))/(2*tden)); + + g->minh = min(g->minh, (g->point[i].x-g->point[i].x/2) + g->point[i+1].x/2); + g->minv = min(g->minv, (g->point[i].y-g->point[i].y/2) + g->point[i+1].y/2); + g->maxh = max(g->maxh, (g->point[i].x-g->point[i].x/2) + g->point[i+1].x/2); + g->maxv = max(g->maxv, (g->point[i].y-g->point[i].y/2) + g->point[i+1].y/2); + } + i = g->nopoints-1; + + g->minh = min(g->minh, (g->point[i].x-g->point[i].x/2)) + xc; + g->minv = min(g->minv, (g->point[i].y-g->point[i].y/2)) + yc; + g->maxh = max(g->maxh, (g->point[i].x-g->point[i].x/2)) + xc; + g->maxv = max(g->maxv, (g->point[i].y-g->point[i].y/2)) + yc; + + g->size = size; + g->xc = xc; + g->yc = yc; + g->fill = fill; + + if (is_in_graphic) { + region_lines.add(g); + } else { + lines.add(g); + } +} + +/* + * the classes and methods for simple_output manipulation + */ + +simple_output::simple_output(FILE *f, int n) +: fp(f), max_line_length(n), col(0), need_space(0), fixed_point(0) +{ +} + +simple_output &simple_output::set_file(FILE *f) +{ + fp = f; + col = 0; + return *this; +} + +simple_output &simple_output::copy_file(FILE *infp) +{ + int c; + while ((c = getc(infp)) != EOF) + putc(c, fp); + return *this; +} + +simple_output &simple_output::end_line() +{ + if (col != 0) { + putc('\n', fp); + col = 0; + need_space = 0; + } + return *this; +} + +simple_output &simple_output::special(const char *s) +{ + return *this; +} + +simple_output &simple_output::simple_comment(const char *s) +{ + if (col != 0) + putc('\n', fp); + fputs("<!-- ", fp); + fputs(s, fp); + fputs(" -->\n", fp); + col = 0; + need_space = 0; + return *this; +} + +simple_output &simple_output::begin_comment(const char *s) +{ + if (col != 0) + putc('\n', fp); + fputs("<!-- ", fp); + fputs(s, fp); + col = 5 + strlen(s); + return *this; +} + +simple_output &simple_output::end_comment() +{ + if (need_space) { + putc(' ', fp); + } + fputs(" -->\n", fp); + col = 0; + need_space = 0; + return *this; +} + +simple_output &simple_output::comment_arg(const char *s) +{ + int len = strlen(s); + + if (col + len + 1 > max_line_length) { + fputs("\n ", fp); + col = 1; + } + fputs(s, fp); + col += len + 1; + return *this; +} + +simple_output &simple_output::set_fixed_point(int n) +{ + assert(n >= 0 && n <= 10); + fixed_point = n; + return *this; +} + +simple_output &simple_output::put_delimiter(char c) +{ + putc(c, fp); + col++; + need_space = 0; + return *this; +} + +simple_output &simple_output::put_string(const char *s, int n) +{ + int i=0; + + while (i<n) { + fputc(s[i], fp); + i++; + } + col += n; + return *this; +} + +simple_output &simple_output::put_translated_string(const char *s) +{ + int i=0; + + while (s[i] != (char)0) { + if ((s[i] & 0x7f) == s[i]) { + fputc(s[i], fp); + } + i++; + } + col += i; + return *this; +} + +simple_output &simple_output::put_string(const char *s) +{ + int i=0; + + while (s[i] != '\0') { + fputc(s[i], fp); + i++; + } + col += i; + return *this; +} + +struct html_2_postscript { + char *html_char; + char *postscript_char; +}; + +static struct html_2_postscript char_conversions[] = { + "+-", "char177", + "eq", "=", + "mu", "char215", + NULL, NULL, +}; + + +// this is an aweful hack which attempts to translate html characters onto +// postscript characters. Can this be done inside the devhtml files? +// +// or should we read the devps files and find out the translations? +// + +simple_output &simple_output::put_translated_char (const char *s) +{ + int i=0; + + while (char_conversions[i].html_char != NULL) { + if (strcmp(s, char_conversions[i].html_char) == 0) { + put_string(char_conversions[i].postscript_char); + return *this; + } else { + i++; + } + } + put_string(s); + return *this; +} + +simple_output &simple_output::put_number(int n) +{ + char buf[1 + INT_DIGITS + 1]; + sprintf(buf, "%d", n); + int len = strlen(buf); + put_string(buf, len); + need_space = 1; + return *this; +} + +simple_output &simple_output::put_float(double d) +{ + char buf[128]; + + sprintf(buf, "%.4f", d); + int len = strlen(buf); + put_string(buf, len); + need_space = 1; + return *this; +} + + +simple_output &simple_output::put_symbol(const char *s) +{ + int len = strlen(s); + + if (need_space) { + putc(' ', fp); + col++; + } + fputs(s, fp); + col += len; + need_space = 1; + return *this; +} + +class html_font : public font { + html_font(const char *); +public: + int encoding_index; + char *encoding; + char *reencoded_name; + ~html_font(); + void handle_unknown_font_command(const char *command, const char *arg, + const char *filename, int lineno); + static html_font *load_html_font(const char *); +}; + +html_font *html_font::load_html_font(const char *s) +{ + html_font *f = new html_font(s); + if (!f->load()) { + delete f; + return 0; + } + return f; +} + +html_font::html_font(const char *nm) +: font(nm) +{ +} + +html_font::~html_font() +{ +} + +void html_font::handle_unknown_font_command(const char *command, const char *arg, + const char *filename, int lineno) +{ + if (strcmp(command, "encoding") == 0) { + if (arg == 0) + error_with_file_and_line(filename, lineno, + "`encoding' command requires an argument"); + else + encoding = strsave(arg); + } +} + + +/* + * a simple class to contain the header to this document + */ + +class title_desc { +public: + title_desc (); + ~title_desc (); + + int has_been_written; + int has_been_found; + char text[MAX_STRING_LENGTH]; +}; + + +title_desc::title_desc () + : has_been_found(FALSE), has_been_written(FALSE) +{ +} + +title_desc::~title_desc () +{ +} + +class header_desc { +public: + header_desc (); + ~header_desc (); + + int no_of_headings; // how many headings have we found? + char_buffer headings; // all the headings used in the document + ordered_list <text_glob> headers; + int header_level; // current header level + int written_header; // have we written the header yet? + char header_buffer[MAX_STRING_LENGTH]; // current header text + + void write_headings (FILE *f); +}; + +header_desc::header_desc () + : no_of_headings(0), header_level(2), written_header(0) +{ +} + +header_desc::~header_desc () +{ +} + +/* + * paragraph_type - alignment for a new paragraph + */ + +typedef enum { left_alignment, center_alignment } paragraph_type; + +/* + * text_defn - defines the limit of text, initially these are stored in the + * column array as words. Later we examine the white space between + * the words in successive lines to find out whether we can detect + * distinct columns. The columns are generated via html tables. + */ + +struct text_defn { + int left; // the start of a word or text + int right; // the end of the text and beginning of white space + int is_used; // will this this column be used for words or space +}; + + +/* + * note that html_tables are currently only used to provide a better + * indentation mechanism for html text (in particular it allows grohtml + * to render .IP and .2C together with autoformatting). + */ + +class html_table { +public: + html_table (); + ~html_table (); + + int no_of_columns; // how many columns are we using? + struct text_defn *columns; // left and right margins for each column + int vertical_limit; // the limit of the table +}; + +html_table::html_table () + : no_of_columns(0), columns(0), vertical_limit(0) +{ +} + +html_table::~html_table () +{ +} + +class html_printer : public printer { + FILE *tempfp; + simple_output html; + simple_output troff; + int res; + int postscript_res; + int space_char_index; + int no_of_printed_pages; + int paper_length; + enum { SBUF_SIZE = 256 }; + char sbuf[SBUF_SIZE]; + int sbuf_len; + int sbuf_start_hpos; + int sbuf_vpos; + int sbuf_end_hpos; + int sbuf_space_width; + int sbuf_space_count; + int sbuf_space_diff_count; + int sbuf_space_code; + int sbuf_kern; + style sbuf_style; + style output_style; + int output_hpos; + int output_vpos; + int output_draw_point_size; + int line_thickness; + int output_line_thickness; + int fill; + unsigned char output_space_code; + string defs; + char *inside_font_style; + int page_number; + title_desc title; + header_desc header; + page *page_contents; + html_table indentation; + int left_margin_indent; + int right_margin_indent; + int need_one_newline; + int issued_newline; + int in_paragraph; + int need_paragraph; + paragraph_type para_type; + char image_name[MAX_STRING_LENGTH]; + int image_number; + int graphic_level; + + int start_region_vpos; + int start_region_hpos; + int end_region_vpos; + int end_region_hpos; + int cutoff_heading; + + struct graphic_glob *start_graphic; + struct text_glob *start_text; + + + void flush_sbuf (); + void set_style (const style &); + void set_space_code (unsigned char c); + void do_exec (char *, const environment *); + void do_import (char *, const environment *); + void do_def (char *, const environment *); + void do_mdef (char *, const environment *); + void do_file (char *, const environment *); + void set_line_thickness (const environment *); + void change_font (text_glob *g, int is_to_html); + void terminate_current_font (void); + void flush_font (void); + void flush_page (void); + void display_word (text_glob *g, int is_to_html); + void html_display_word (text_glob *g); + void troff_display_word (text_glob *g); + void display_line (graphic_glob *g, int is_to_html); + void display_fill (graphic_glob *g); + void calculate_margin (void); + void traverse_page_regions (void); + void dump_page (void); + int is_within_region (graphic_glob *g); + int is_within_region (text_glob *t); + int is_less (graphic_glob *g, text_glob *t); + void display_globs (int is_to_html); + void move_horizontal (text_glob *g, int left_margin); + void move_vertical (text_glob *g, paragraph_type p); + void write_html_font_face (const char *fontname, const char *left, const char *right); + void write_html_font_type (const char *fontname, const char *left, const char *right); + void html_change_font (text_glob *g, const char *fontname, int size); + char *html_position_text (text_glob *g, int left_margin, int right_margin); + int html_position_region (void); + void troff_change_font (const char *fontname, int size, int font_no); + void troff_position_text (text_glob *g); + int pretend_is_on_same_line (text_glob *g, int left_margin, int right_margin); + int is_on_same_line (text_glob *g, int vpos); + int looks_like_subscript (text_glob *g); + int looks_like_superscript (text_glob *g); + void begin_paragraph (paragraph_type p); + void begin_paragraph_no_height (paragraph_type p); + void force_begin_paragraph (void); + void end_paragraph (void); + void html_newline (void); + void convert_to_image (char *name); + void write_title (int in_head); + void find_title (void); + int is_bold (text_glob *g); + void write_header (void); + void determine_header_level (void); + void build_header (text_glob *g); + void make_html_indent (int indent); + int is_whole_line_bold (text_glob *g); + int is_a_header (text_glob *g); + int processed_header (text_glob *g); + void make_new_image_name (void); + void create_temp_name (char *name, char *extension); + void calculate_region_margins (region_glob *r); + void remove_redundant_regions (void); + void remove_duplicate_regions (void); + void move_region_to_page (void); + void calculate_region_range (graphic_glob *r); + void flush_graphic (void); + void write_string (graphic_glob *g, int is_to_html); + void prologue (void); + int gs_x (int x); + int gs_y (int y); + void display_regions (void); + int check_able_to_use_table (text_glob *g); + int using_table_for_indent (void); + int collect_columns (struct text_defn *line, struct text_defn *last, int max_words); + void include_into_list (struct text_defn *line, struct text_defn *item); + int is_in_column (struct text_defn *line, struct text_defn *item, int max_words); + int is_column_match (struct text_defn *match, struct text_defn *line1, struct text_defn *line2, int max_words); + int count_columns (struct text_defn *line); + void rewind_text_to (text_glob *g); + int found_use_for_table (text_glob *start); + void column_display_word (int vert, int left, int right, int next); + void start_table (void); + void end_table (void); + void foreach_column_include_text (text_glob *start); + void define_cell (int left, int right); + int column_calculate_left_margin (int left, int right); + int column_calculate_right_margin (int left, int right); + void display_columns (const char *word, const char *name, text_defn *line); + void calculate_right (struct text_defn *line, int max_words); + void determine_right_most_column (struct text_defn *line, int max_words); + int remove_white_using_words (struct text_defn *next_guess, struct text_defn *last_guess, struct text_defn *next_line); + int copy_line (struct text_defn *dest, struct text_defn *src); + void combine_line (struct text_defn *dest, struct text_defn *src); + int conflict_with_words (struct text_defn *column_guess, struct text_defn *words); + void remove_entry_in_line (struct text_defn *line, int j); + void remove_redundant_columns (struct text_defn *line); + void add_column_gaps (struct text_defn *line); + int continue_searching_column (text_defn *next_col, text_defn *last_col, text_defn *all_words); + void add_right_full_width (struct text_defn *line, int mingap); + int is_continueous_column (text_defn *last_col, text_defn *next_line); + int is_exact_left (text_defn *last_col, text_defn *next_line); + void emit_space (text_glob *g, int force_space); + int is_in_middle (int left, int right); + int check_able_to_use_center (text_glob *g); + void write_centered_line (text_glob *g); + int single_centered_line (text_defn *first, text_defn *second, text_glob *g); + int determine_row_limit (text_glob *start, int v); + void assign_used_columns (text_glob *start); + int find_column_index (text_glob *t); + int large_enough_gap (text_defn *last_col); + int is_worth_column (int left, int right); + int is_subset_of_columns (text_defn *a, text_defn *b); + void count_hits (text_defn *col); + int calculate_min_gap (text_glob *g); + +public: + html_printer(); + ~html_printer(); + void set_char(int i, font *f, const environment *env, int w, const char *name); + void draw(int code, int *p, int np, const environment *env); + void begin_page(int); + void end_page(int); + void special(char *arg, const environment *env); + font *make_font(const char *); + void end_of_line(); +}; + +html_printer::html_printer() +: no_of_printed_pages(0), + sbuf_len(0), + output_hpos(-1), + output_vpos(-1), + html(0, MAX_LINE_LENGTH), + troff(0, MAX_LINE_LENGTH), + line_thickness(-1), + inside_font_style(0), + fill(FILL_MAX + 1), + page_number(0), + left_margin_indent(0), + right_margin_indent(0), + start_region_vpos(0), + start_region_hpos(0), + end_region_vpos(0), + end_region_hpos(0), + need_one_newline(0), + issued_newline(0), + image_number(0), + graphic_level(0), + cutoff_heading(100), + in_paragraph(0), + need_paragraph(0), + para_type(left_alignment) +{ + tempfp = xtmpfile(); + html.set_file(tempfp); + if (linewidth < 0) + linewidth = DEFAULT_LINEWIDTH; + if (font::hor != 1) + fatal("horizontal resolution must be 1"); + if (font::vert != 1) + fatal("vertical resolution must be 1"); +#if 0 + // should be sorted html.. + if (font::res % (font::sizescale*72) != 0) + fatal("res must be a multiple of 72*sizescale"); +#endif + int r = font::res; + int point = 0; + while (r % 10 == 0) { + r /= 10; + point++; + } + res = r; + html.set_fixed_point(point); + space_char_index = font::name_to_index("space"); + paper_length = font::paperlength; + if (paper_length == 0) + paper_length = 11*font::res; + page_contents = new page; + + postscript_res = 72000; +} + + +void html_printer::set_char(int i, font *f, const environment *env, int w, const char *name) +{ + unsigned char code = f->get_code(i); + + style sty(f, env->size, env->height, env->slant, env->fontno); + if (sty.slant != 0) { + if (sty.slant > 80 || sty.slant < -80) { + error("silly slant `%1' degrees", sty.slant); + sty.slant = 0; + } + } + if ((name != 0) && (page_contents->is_in_graphic)) { + flush_sbuf(); + int r=font::res; // resolution of the device actually + page_contents->add_special_char(&sty, (char *)name, strlen(name), + env->vpos-sty.point_size*r/72, env->hpos, + env->vpos, env->hpos+w); + sbuf_end_hpos = env->hpos + w; + sbuf_start_hpos = env->hpos; + sbuf_vpos = env->vpos; + sbuf_style = sty; + sbuf_kern = 0; + return; + } + + if (sbuf_len > 0) { + if (sbuf_len < SBUF_SIZE + && sty == sbuf_style + && sbuf_vpos == env->vpos) { + if (sbuf_end_hpos == env->hpos) { + sbuf[sbuf_len++] = code; + sbuf_end_hpos += w + sbuf_kern; + return; + } + /* If sbuf_end_hpos - sbuf_kern == env->hpos, we are better off + starting a new string. */ + if (sbuf_len < SBUF_SIZE - 1 && env->hpos >= sbuf_end_hpos + && (sbuf_kern == 0 || sbuf_end_hpos - sbuf_kern != env->hpos)) { + if (sbuf_space_code < 0) { +#if 0 + sbuf_space_code = ' '; + sbuf_space_count++; + sbuf_space_width = env->hpos - sbuf_end_hpos; + sbuf_end_hpos = env->hpos + w + sbuf_kern; + sbuf[sbuf_len++] = ' '; + sbuf[sbuf_len++] = code; + return; +#endif + } else { + int diff = env->hpos - sbuf_end_hpos - sbuf_space_width; + if (diff == 0) { + sbuf_end_hpos = env->hpos + w + sbuf_kern; + sbuf[sbuf_len++] = sbuf_space_code; + sbuf[sbuf_len++] = code; + sbuf_space_count++; + if (diff == 1) + sbuf_space_diff_count++; + else if (diff == -1) + sbuf_space_diff_count--; + return; + } + } + } + } + flush_sbuf(); + } + sbuf_len = 1; + sbuf[0] = code; + sbuf_end_hpos = env->hpos + w; + sbuf_start_hpos = env->hpos; + sbuf_vpos = env->vpos; + sbuf_style = sty; + sbuf_space_code = -1; + sbuf_space_width = 0; + sbuf_space_count = sbuf_space_diff_count = 0; + sbuf_kern = 0; +} + + +/* + * make_new_image_name - creates a new file name ready for a image file. + * it leaves the extension off. + */ + +void html_printer::make_new_image_name (void) +{ + image_number++; + sprintf(image_name, "groff-html-%d-%d", image_number, getpid()); +} + +/* + * write_title - writes the title to this document + */ + +void html_printer::write_title (int in_head) +{ + if (title.has_been_found) { + if (in_head) { + html.put_string("<title>"); + html.put_string(title.text); + html.put_string("</title>\n"); + } else { + title.has_been_written = TRUE; + html.put_string("<h1 align=center>"); + html.put_string(title.text); + html.put_string("</h1>\n"); + } + } +} + + +/* + * find_title - finds a title to this document, if it exists. + */ + +void html_printer::find_title (void) +{ + text_glob *t; + int r=font::res; + int removed_from_head; + + if ((page_number == 1) && (guess_on)) { + if (! page_contents->words.is_empty()) { + + int end_title_hpos = 0; + int start_title_hpos = 0; + int start_title_vpos = 0; + int found_title_start = FALSE; + int height = 0; + int start_region =-1; + + if (! page_contents->regions.is_empty()) { + region_glob *r; + + page_contents->regions.start_from_head(); + r = page_contents->regions.get_data(); + if (r->minv > 0) { + start_region = r->minv; + } + } + + page_contents->words.start_from_head(); + do { + t = page_contents->words.get_data(); + removed_from_head = FALSE; + if ((found_title_start) && (start_region != -1) && (t->maxv >= start_region)) { + /* + * we have just encountered the first graphic region so + * we stop looking for a title. + */ + title.has_been_found = TRUE; + return; + } else if (t->is_raw_command) { + // skip raw commands + } else if ((!found_title_start) && (t->minh > left_margin_indent) && + ((start_region == -1) || (t->maxv < start_region))) { + start_title_vpos = t->minv; + end_title_hpos = t->minh; + strcpy((char *)title.text, (char *)t->text_string); + height = t->text_style.point_size*r/72; + found_title_start = TRUE; + page_contents->words.sub_move_right(); + removed_from_head = ((!page_contents->words.is_empty()) && + (page_contents->words.is_equal_to_head())); + } else if (found_title_start) { + if ((t->minv == start_title_vpos) || + ((!more_than_line_break(start_title_vpos, t->minv, (height*3)/2)) && + (t->minh > left_margin_indent)) || + (is_bold(t) && (t->minh > left_margin_indent))) { + start_title_vpos = min(t->minv, start_title_vpos); + end_title_hpos = max(t->maxh, end_title_hpos); + strcat(title.text, " "); + strcat(title.text, (char *)t->text_string); + page_contents->words.sub_move_right(); + removed_from_head = ((!page_contents->words.is_empty()) && + (page_contents->words.is_equal_to_head())); + } else { + // end of title + title.has_been_found = TRUE; + return; + } + } else if (t->minh == left_margin_indent) { + // no margin exists + return; + } else { + // move onto next word + page_contents->words.move_right(); + } + } while ((! page_contents->words.is_equal_to_head()) || (removed_from_head)); + } + } +} + +/* + * html_newline - generates a newline <br> + */ + +void html_printer::html_newline (void) +{ + int r = font::res; + int height = output_style.point_size*r/72; + + if (in_paragraph) { + // safe to generate a pretty newline + html.put_string("<br>\n"); + } else { + html.put_string("<br>"); + } + output_vpos += height; + issued_newline = TRUE; +} + +/* + * force_begin_paragraph - force the begin_paragraph to be emitted. + */ + +void html_printer::force_begin_paragraph (void) +{ + if (in_paragraph && need_paragraph) { + switch (para_type) { + + case left_alignment: html.put_string("<p>"); + break; + case center_alignment: html.put_string("<p align=center>"); + break; + default: fatal("unknown paragraph alignment type"); + } + need_paragraph = FALSE; + } +} + +/* + * begin_paragraph - starts a new paragraph. It does nothing if a paragraph + * has already been started. + */ + +void html_printer::begin_paragraph (paragraph_type p) +{ + if (! in_paragraph) { + int r = font::res; + int height = output_style.point_size*r/72; + + if (output_vpos >=0) { + // we leave it alone if it is set to the top of page + output_vpos += height; + } + need_paragraph = TRUE; // delay the <p> just in case we don't actually emit text + in_paragraph = TRUE; + issued_newline = TRUE; + para_type = p; + } +} + + +/* + * begin_paragraph_no_height - starts a new paragraph. It does nothing if a paragraph + * has already been started. Note it does not alter output_vpos. + */ + +void html_printer::begin_paragraph_no_height (paragraph_type p) +{ + if (! in_paragraph) { + need_paragraph = TRUE; // delay the <p> just in case we don't actually emit text + in_paragraph = TRUE; + issued_newline = TRUE; + para_type = p; + } +} + +/* + * end_paragraph - end the current paragraph. It does nothing if a paragraph + * has not been started. + */ + +void html_printer::end_paragraph (void) +{ + if (in_paragraph) { + // check whether we have generated any text inbetween the potential paragraph begin end + if (! need_paragraph) { + int r = font::res; + int height = output_style.point_size*r/72; + + output_vpos += height; + html.put_string("</p>\n"); + } + terminate_current_font(); + para_type = left_alignment; + in_paragraph = FALSE; + } +} + +/* + * calculate_margin - runs through the words and graphics globs + * and finds the start of the left most margin. + */ + +void html_printer::calculate_margin (void) +{ + if (! margin_on) { + text_glob *w; + graphic_glob *g; + + // remove margin + + right_margin_indent = 0; + + if (! page_contents->words.is_empty()) { + + // firstly check the words right margin + + page_contents->words.start_from_head(); + do { + w = page_contents->words.get_data(); + if ((w->maxh >= 0) && (w->maxh > right_margin_indent)) { + right_margin_indent = w->maxh; +#if 0 + if (right_margin_indent == 950) stop(); +#endif + } + page_contents->words.move_right(); + } while (! page_contents->words.is_equal_to_head()); + } + + if (! page_contents->lines.is_empty()) { + // now check for diagrams for right margin + page_contents->lines.start_from_head(); + do { + g = page_contents->lines.get_data(); + if ((g->maxh >= 0) && (g->maxh > right_margin_indent)) { + right_margin_indent = g->maxh; +#if 0 + if (right_margin_indent == 950) stop(); +#endif + } + page_contents->lines.move_right(); + } while (! page_contents->lines.is_equal_to_head()); + } + + // now we know the right margin lets do the same to find left margin + + left_margin_indent = right_margin_indent; + + if (! page_contents->words.is_empty()) { + do { + w = page_contents->words.get_data(); + if ((w->minh >= 0) && (w->minh < left_margin_indent)) { + left_margin_indent = w->minh; + } + page_contents->words.move_right(); + } while (! page_contents->words.is_equal_to_head()); + } + + if (! page_contents->lines.is_empty()) { + // now check for diagrams + page_contents->lines.start_from_head(); + do { + g = page_contents->lines.get_data(); + if ((g->minh >= 0) && (g->minh < left_margin_indent)) { + left_margin_indent = g->minh; + } + page_contents->lines.move_right(); + } while (! page_contents->lines.is_equal_to_head()); + } + } +} + + +/* + * calculate_region - runs through the graphics globs and text globs + * and ensures that all graphic routines + * are defined by the region lists. + * This then allows us to easily + * determine the range of vertical and + * horizontal boundaries for pictures, + * tbl's and eqn's. + * + */ + +void page::calculate_region (void) +{ + graphic_glob *g; + + if (! lines.is_empty()) { + lines.start_from_head(); + do { + g = lines.get_data(); + if (! is_in_region(g)) { + if (! can_grow_region(g)) { + make_new_region(g); + } + } + lines.move_right(); + } while (! lines.is_equal_to_head()); + } +} + +/* + * remove_redundant_regions - runs through the regions and ensures that + * all are needed. This is required as + * a picture may be empty, or EQ EN pair + * maybe empty. + */ + +void html_printer::remove_redundant_regions (void) +{ + region_glob *r; + graphic_glob *g; + + // firstly run through the region making sure that all are needed + // ie all contain a line or word + if (! page_contents->regions.is_empty()) { + page_contents->regions.start_from_tail(); + do { + r = page_contents->regions.get_data(); + calculate_region_margins(r); + if (page_contents->has_line(r) || page_contents->has_word(r)) { + page_contents->regions.move_right(); + } else { + page_contents->regions.sub_move_right(); + } + } while ((! page_contents->regions.is_empty()) && + (! page_contents->regions.is_equal_to_tail())); + } +} + +void html_printer::display_regions (void) +{ + if (debug_table_on) { + region_glob *r; + + fprintf(stderr, "==========s t a r t===========\n"); + if (! page_contents->regions.is_empty()) { + page_contents->regions.start_from_head(); + do { + r = page_contents->regions.get_data(); + fprintf(stderr, "region minv %d maxv %d\n", r->minv, r->maxv); + page_contents->regions.move_right(); + } while (! page_contents->regions.is_equal_to_head()); + } + fprintf(stderr, "============e n d=============\n"); + fflush(stderr); + } +} + +/* + * remove_duplicate_regions - runs through the regions and ensures that + * no duplicates exist. + */ + +void html_printer::remove_duplicate_regions (void) +{ + region_glob *r; + region_glob *l=0; + + if (! page_contents->regions.is_empty()) { + page_contents->regions.start_from_head(); + l = page_contents->regions.get_data(); + page_contents->regions.move_right(); + r = page_contents->regions.get_data(); + if (l != r) { + do { + r = page_contents->regions.get_data(); + // we have a legit region so we check for an intersection + if (is_intersection(r->minv, r->minv, l->minv, l->maxv) && + is_intersection(r->minh, r->maxh, l->minh, l->maxh)) { + l->minv = min(r->minv, l->minv); + l->maxv = max(r->maxv, l->maxv); + l->minh = min(r->minh, l->minh); + l->maxh = max(r->maxh, l->maxh); + calculate_region_margins(l); + page_contents->regions.sub_move_right(); + } else { + l = r; + page_contents->regions.move_right(); + } + } while ((! page_contents->regions.is_empty()) && + (! page_contents->regions.is_equal_to_head())); + } + } +} + +int page::has_line (region_glob *r) +{ + graphic_glob *g; + + if (! lines.is_empty()) { + lines.start_from_head(); + do { + g = lines.get_data(); + if (is_subsection(g->minv, g->maxv, r->minv, r->maxv) && + is_subsection(g->minh, g->maxh, r->minh, r->maxh)) { + return( TRUE ); + } + lines.move_right(); + } while (! lines.is_equal_to_head()); + } + return( FALSE ); +} + + +int page::has_word (region_glob *r) +{ + text_glob *g; + + if (! words.is_empty()) { + words.start_from_head(); + do { + g = words.get_data(); + if (is_subsection(g->minv, g->maxv, r->minv, r->maxv) && + is_subsection(g->minh, g->maxh, r->minh, r->maxh)) { + return( TRUE ); + } + words.move_right(); + } while (! words.is_equal_to_head()); + } + return( FALSE ); +} + + +void html_printer::calculate_region_margins (region_glob *r) +{ + text_glob *w; + graphic_glob *g; + + r->minh = right_margin_indent; + r->maxh = left_margin_indent; + + if (! page_contents->lines.is_empty()) { + page_contents->lines.start_from_head(); + do { + g = page_contents->lines.get_data(); + if (is_subsection(g->minv, g->maxv, r->minv, r->maxv)) { + r->minh = min(r->minh, g->minh); + r->maxh = max(r->maxh, g->maxh); + } + page_contents->lines.move_right(); + } while (! page_contents->lines.is_equal_to_head()); + } + if (! page_contents->words.is_empty()) { + page_contents->words.start_from_head(); + do { + w = page_contents->words.get_data(); + if (is_subsection(w->minv, w->maxv, r->minv, r->maxv)) { + r->minh = min(r->minh, w->minh); + r->maxh = max(r->maxh, w->maxh); + } + page_contents->words.move_right(); + } while (! page_contents->words.is_equal_to_head()); + } +} + + +int page::is_in_region (graphic_glob *g) +{ + region_glob *r; + + if (! regions.is_empty()) { + regions.start_from_head(); + do { + r = regions.get_data(); + if (is_subsection(g->minv, g->maxv, r->minv, r->maxv) && + is_subsection(g->minh, g->maxh, r->minh, r->maxh)) { + return( TRUE ); + } + regions.move_right(); + } while (! regions.is_equal_to_head()); + } + return( FALSE ); +} + + +/* + * no_raw_commands - returns TRUE if no html raw commands exist between + * minv and maxv. + */ + +int page::no_raw_commands (int minv, int maxv) +{ + text_glob *g; + + if (! words.is_empty()) { + words.start_from_head(); + do { + g = words.get_data(); + if ((g->is_raw_command) && (g->is_html_command) && + (is_intersection(g->minv, g->maxv, minv, maxv))) { + return( FALSE ); + } + words.move_right(); + } while (! words.is_equal_to_head()); + } + return( TRUE ); +} + +/* + * can_grow_region - returns TRUE if a region exists which can be extended + * to include graphic_glob *g. The region is extended. + */ + +int page::can_grow_region (graphic_glob *g) +{ + region_glob *r; + int quarter_inch=font::res/4; + + if (! regions.is_empty()) { + regions.start_from_head(); + do { + r = regions.get_data(); + // must prevent grohtml from growing a region through a html raw command + if (is_intersection(g->minv, g->maxv, r->minv, r->maxv+quarter_inch) && + (no_raw_commands(r->minv, r->maxv+quarter_inch))) { +#if defined(DEBUGGING) + stop(); + printf("r minh=%d minv=%d maxh=%d maxv=%d\n", + r->minh, r->minv, r->maxh, r->maxv); + printf("g minh=%d minv=%d maxh=%d maxv=%d\n", + g->minh, g->minv, g->maxh, g->maxv); +#endif + r->minv = min(r->minv, g->minv); + r->maxv = max(r->maxv, g->maxv); + r->minh = min(r->minh, g->minh); + r->maxh = max(r->maxh, g->maxh); +#if defined(DEBUGGING) + printf(" r minh=%d minv=%d maxh=%d maxv=%d\n", + r->minh, r->minv, r->maxh, r->maxv); +#endif + return( TRUE ); + } + regions.move_right(); + } while (! regions.is_equal_to_head()); + } + return( FALSE ); +} + + +/* + * make_new_region - creates a new region to contain, g. + */ + +void page::make_new_region (graphic_glob *g) +{ + region_glob *r=new region_glob; + + r->minv = g->minv; + r->maxv = g->maxv; + r->minh = g->minh; + r->maxv = g->maxv; + regions.add(r); +} + + +void html_printer::dump_page(void) +{ + text_glob *g; + + printf("\n\ndebugging start\n"); + page_contents->words.start_from_head(); + do { + g = page_contents->words.get_data(); + printf("%s ", g->text_string); + page_contents->words.move_right(); + } while (! page_contents->words.is_equal_to_head()); + printf("\ndebugging end\n\n"); +} + + +/* + * traverse_page_regions - runs through the regions in current_page + * and generate html for text, and troff output + * for all graphics. + */ + +void html_printer::traverse_page_regions (void) +{ + region_glob *r; + + start_region_vpos = 0; + start_region_hpos = 0; + end_region_vpos = -1; + end_region_hpos = -1; + + if (! page_contents->regions.is_empty()) { + page_contents->regions.start_from_head(); + do { + r = page_contents->regions.get_data(); + if (r->minv > 0) { + end_region_vpos = r->minv-1; + } else { + end_region_vpos = 0; + } + end_region_hpos = -1; + display_globs(TRUE); + calculate_region_margins(r); + start_region_vpos = end_region_vpos; + end_region_vpos = r->maxv; + start_region_hpos = r->minh; + end_region_hpos = r->maxh; + display_globs(FALSE); + start_region_vpos = end_region_vpos+1; + start_region_hpos = 0; + page_contents->regions.move_right(); + } while (! page_contents->regions.is_equal_to_head()); + start_region_vpos = end_region_vpos+1; + start_region_hpos = 0; + end_region_vpos = -1; + end_region_hpos = -1; + } + display_globs(TRUE); +} + +int html_printer::is_within_region (text_glob *t) +{ + int he, ve, hs; + + if (start_region_hpos == -1) { + hs = t->minh; + } else { + hs = start_region_hpos; + } + if (end_region_vpos == -1) { + ve = t->maxv; + } else { + ve = end_region_vpos; + } + if (end_region_hpos == -1) { + he = t->maxh; + } else { + he = end_region_hpos; + } + return( is_subsection(t->minv, t->maxv, start_region_vpos, ve) && + is_subsection(t->minh, t->maxh, hs, he) ); +} + +int html_printer::is_within_region (graphic_glob *g) +{ + int he, ve, hs; + + if (start_region_hpos == -1) { + hs = g->minh; + } else { + hs = start_region_hpos; + } + if (end_region_vpos == -1) { + ve = g->maxv; + } else { + ve = end_region_vpos; + } + if (end_region_hpos == -1) { + he = g->maxh; + } else { + he = end_region_hpos; + } + return( is_subsection(g->minv, g->maxv, start_region_vpos, ve) && + is_subsection(g->minh, g->maxh, hs, he) ); +} + +int html_printer::is_less (graphic_glob *g, text_glob *t) +{ + return( (g->minv < t->minv) || ((g->minv == t->minv) && (g->minh < t->minh)) ); +} + +static FILE *create_file (char *filename) +{ + FILE *f; + + errno = 0; + f = fopen(filename, "w"); + if (f == 0) { + error("can't create `%1'", filename); + return( 0 ); + } else { + return( f ); + } +} + +void html_printer::convert_to_image (char *name) +{ + char buffer[1024]; + + sprintf(buffer, "grops %s > %s.ps\n", name, name); + if (debug_on) { + fprintf(stderr, "%s", buffer); + } + system(buffer); + + if (image_type == gif) { + sprintf(buffer, + "echo showpage | gs -q -dSAFER -sDEVICE=ppmraw -r%d -g%dx%d -sOutputFile=- %s.ps - | ppmquant 256 2> /dev/null | ppmtogif 2> /dev/null > %s.gif \n", + image_res, + (end_region_hpos-start_region_hpos)*image_res/font::res+IMAGE_BOARDER_PIXELS, + (end_region_vpos-start_region_vpos)*image_res/font::res+IMAGE_BOARDER_PIXELS, + name, image_name); + } else { + sprintf(buffer, + "echo showpage | gs -q -dSAFER -sDEVICE=%s -r%d -g%dx%d -sOutputFile=- %s.ps - 2> /dev/null > %s.png \n", + image_device, + image_res, + (end_region_hpos-start_region_hpos)*image_res/font::res+IMAGE_BOARDER_PIXELS, + (end_region_vpos-start_region_vpos)*image_res/font::res+IMAGE_BOARDER_PIXELS, + name, image_name); + } + if (debug_on) { + fprintf(stderr, "%s", buffer); + } + system(buffer); + sprintf(buffer, "/bin/rm -f %s %s.ps\n", name, name); + if (debug_on) { + fprintf(stderr, "%s", buffer); + } else { + system(buffer); + } +} + +void html_printer::prologue (void) +{ + troff.put_string("x T ps\nx res "); + troff.put_number(postscript_res); + troff.put_string(" 1 1\nx init\np1\n"); +} + +void html_printer::create_temp_name (char *name, char *extension) +{ + make_new_image_name(); + sprintf(name, "/tmp/%s.%s", image_name, extension); +} + +void html_printer::display_globs (int is_to_html) +{ + text_glob *t=0; + graphic_glob *g=0; + FILE *f=0; + char name[MAX_TEMP_NAME]; + char buffer[1024]; + int r=font::res; + int something=FALSE; + int is_center=FALSE; + + end_paragraph(); + + if (! is_to_html) { + is_center = html_position_region(); + create_temp_name(name, "troff"); + f = create_file(name); + troff.set_file(f); + prologue(); + output_style.f = 0; + } + if (! page_contents->words.is_empty()) { + page_contents->words.start_from_head(); + t = page_contents->words.get_data(); + } + + if (! page_contents->lines.is_empty()) { + page_contents->lines.start_from_head(); + g = page_contents->lines.get_data(); + } + + do { +#if 0 + if ((t != 0) && (strcmp(t->text_string, "(1.a)") == 0)) { + stop(); + } +#endif + if ((t == 0) && (g != 0)) { + if (is_within_region(g)) { + something = TRUE; + display_line(g, is_to_html); + } + if (page_contents->lines.is_empty() || page_contents->lines.is_equal_to_tail()) { + g = 0; + } else { + g = page_contents->lines.move_right_get_data(); + } + } else if ((g == 0) && (t != 0)) { + if (is_within_region(t)) { + display_word(t, is_to_html); + something = TRUE; + } + if (page_contents->words.is_empty() || page_contents->words.is_equal_to_tail()) { + t = 0; + } else { + t = page_contents->words.move_right_get_data(); + } + } else { + if ((g == 0) || (t == 0)) { + // hmm nothing to print out... + } else if (is_less(g, t)) { + if (is_within_region(g)) { + display_line(g, is_to_html); + something = TRUE; + } + if (page_contents->lines.is_empty() || page_contents->lines.is_equal_to_tail()) { + g = 0; + } else { + g = page_contents->lines.move_right_get_data(); + } + } else { + if (is_within_region(t)) { + display_word(t, is_to_html); + something = TRUE; + } + if (page_contents->words.is_empty() || page_contents->words.is_equal_to_tail()) { + t = 0; + } else { + t = page_contents->words.move_right_get_data(); + } + } + } + } while ((t != 0) || (g != 0)); + + if ((! is_to_html) && (f != 0)) { + fclose(troff.get_file()); + if (something) { + convert_to_image(name); + + if (is_center) { + begin_paragraph(center_alignment); + } else { + begin_paragraph(left_alignment); + } + force_begin_paragraph(); + html.put_string("<img src=\""); + html.put_string(image_name); + if (image_type == gif) { + html.put_string(".gif\""); + } else { + html.put_string(".png\""); + } + if (is_center) { + html.put_string(" align=\"middle\""); + } + html.put_string(">\n"); + html_newline(); + end_paragraph(); + + output_vpos = end_region_vpos; + output_hpos = 0; + need_one_newline = FALSE; + output_style.f = 0; + } + // unlink(name); // remove troff file + } +} + +void html_printer::flush_page (void) +{ + calculate_margin(); + output_vpos = -1; + output_hpos = left_margin_indent; +#if 0 + dump_page(); +#endif + html.begin_comment("left margin: ").comment_arg(itoa(left_margin_indent)).end_comment();; + html.begin_comment("right margin: ").comment_arg(itoa(right_margin_indent)).end_comment();; + remove_redundant_regions(); + page_contents->calculate_region(); + remove_duplicate_regions(); + find_title(); + + traverse_page_regions(); + terminate_current_font(); + if (need_one_newline) { + html_newline(); + } + end_paragraph(); + + // move onto a new page + delete page_contents; + page_contents = new page; +} + +static int convertSizeToHTML (int size) +{ + if (size < 6) { + return( 0 ); + } else if (size < 8) { + return( 1 ); + } else if (size < 10) { + return( 2 ); + } else if (size < 12) { + return( 3 ); + } else if (size < 14) { + return( 4 ); + } else if (size < 16) { + return( 5 ); + } else if (size < 18) { + return( 6 ); + } else { + return( 7 ); + } +} + + +void html_printer::write_html_font_face (const char *fontname, const char *left, const char *right) +{ + switch (fontname[0]) { + + case 'C': html.put_string(left) ; html.put_string("tt"); html.put_string(right); + break; + case 'H': break; + case 'T': break; + default: break; + } +} + + +void html_printer::write_html_font_type (const char *fontname, const char *left, const char *right) +{ + if (strcmp(&fontname[1], "B") == 0) { + html.put_string(left) ; html.put_string("B"); html.put_string(right); + } else if (strcmp(&fontname[1], "I") == 0) { + html.put_string(left) ; html.put_string("I"); html.put_string(right); + } else if (strcmp(&fontname[1], "BI") == 0) { + html.put_string(left) ; html.put_string("EM"); html.put_string(right); + } +} + + +void html_printer::html_change_font (text_glob *g, const char *fontname, int size) +{ + char buffer[1024]; + + if (output_style.f != 0) { + const char *oldfontname = output_style.f->get_name(); + + // firstly terminate the current font face and type + if ((oldfontname != 0) && (oldfontname != fontname)) { + write_html_font_face(oldfontname, "</", ">"); + write_html_font_type(oldfontname, "</", ">"); + } + } + if (fontname != 0) { + // now emit the size if it has changed + if (((output_style.f == 0) || (output_style.point_size != size)) && (size != 0)) { + sprintf(buffer, "<font size=%d>", convertSizeToHTML(size)); + html.put_string(buffer); + output_style.point_size = size; // and remember the size + } + + if (! g->is_raw_command) { + // now emit the new font + write_html_font_face(fontname, "<", ">"); + + // now emit the new font type + write_html_font_type(fontname, "<", ">"); + + output_style = g->text_style; // remember style for next time + } + } else { + output_style.f = 0; // no style at present + } +} + + +void html_printer::change_font (text_glob *g, int is_to_html) +{ + if (is_to_html) { + if (output_style != g->text_style) { + const char *fontname=0; + int size=0; + + if (g->text_style.f != 0) { + fontname = g->text_style.f->get_name(); + size = (font::res/(72*font::sizescale))*g->text_style.point_size; + + html_change_font(g, fontname, size); + } else { + html_change_font(g, fontname, size); + } + } + } else { + // is to troff + if (output_style != g->text_style) { + if (g->text_style.f != 0) { + const char *fontname = g->text_style.f->get_name(); + int size = (font::res/(72*font::sizescale))*g->text_style.point_size; + + if (fontname == 0) { + fatal("no internalname specified for font"); + } + + troff_change_font(fontname, size, g->text_style.font_no); + output_style = g->text_style; // remember style for next time + } + } + } +} + + +/* + * is_bold - returns TRUE if the text inside, g, is using a bold face. + * It returns FALSE is g contains a raw html command, even if this uses + * a bold font. + */ + +int html_printer::is_bold (text_glob *g) +{ + if (g->text_style.f == 0) { + // unknown font + return( FALSE ); + } else if (g->is_raw_command) { + return( FALSE ); + } else { + const char *fontname = g->text_style.f->get_name(); + + if (strlen(fontname) >= 2) { + return( fontname[1] == 'B' ); + } else { + return( FALSE ); + } + } +} + +void html_printer::terminate_current_font (void) +{ + text_glob g; + + // we create a dummy glob just so we can tell html_change_font not to start up + // a new font + g.is_raw_command = TRUE; + html_change_font(&g, 0, 0); +} + +void html_printer::write_header (void) +{ + if (strlen(header.header_buffer) > 0) { + if (header.header_level > 7) { + header.header_level = 7; + } + + if (cutoff_heading+2 > header.header_level) { + // firstly we must terminate any font and type faces + terminate_current_font(); + end_paragraph(); + + // secondly we generate a tag + html.put_string("<a name=\""); + html.put_string(header.header_buffer); + html.put_string("\"></a>"); + // now we save the header so we can issue a list of link + style st; + + header.no_of_headings++; + + text_glob *g=new text_glob(&st, + header.headings.add_string(header.header_buffer, strlen(header.header_buffer)), + strlen(header.header_buffer), + header.no_of_headings, header.header_level, + header.no_of_headings, header.header_level, + FALSE, FALSE); + header.headers.add(g); // and add this header to the header list + } + + end_paragraph(); + // and now we issue the real header + html.put_string("<h"); + html.put_number(header.header_level); + html.put_string(">"); + html.put_string(header.header_buffer); + html.put_string("</h"); + html.put_number(header.header_level); + html.put_string(">"); + need_one_newline = FALSE; + begin_paragraph(left_alignment); + header.written_header = TRUE; + } +} + +/* + * write_headings - emits a list of links for the headings in this document + */ + +void header_desc::write_headings (FILE *f) +{ + text_glob *g; + + if (! headers.is_empty()) { + headers.start_from_head(); + do { + g = headers.get_data(); + fprintf(f, "<a href=\"#%s\">%s</a><br>\n", g->text_string, g->text_string); + headers.move_right(); + } while (! headers.is_equal_to_head()); + } +} + +void html_printer::determine_header_level (void) +{ + int i; + int l=strlen(header.header_buffer); + int stops=0; + + for (i=0; ((i<l) && ((header.header_buffer[i] == '.') || is_digit(header.header_buffer[i]))) ; i++) { + if (header.header_buffer[i] == '.') { + stops++; + } + } + if (stops > 0) { + header.header_level = stops; + } +} + + +void html_printer::build_header (text_glob *g) +{ + int r = font::res; + int height = g->text_style.point_size*r/72; + text_glob *l; + int current_vpos; + + strcpy(header.header_buffer, ""); + do { + l = g; + current_vpos = g->minv; + strcat(header.header_buffer, (char *)g->text_string); + page_contents->words.move_right(); + g = page_contents->words.get_data(); + if (g->minv == current_vpos) { + strcat(header.header_buffer, " "); + } + } while ((! page_contents->words.is_equal_to_head()) && + ((g->minv == current_vpos) || (l->maxh == right_margin_indent))); + + determine_header_level(); + // finally set the output to neutral for after the header + + g = page_contents->words.get_data(); + output_vpos = g->minv; // set output_vpos to the next line since + output_hpos = left_margin_indent; // html header forces a newline anyway + page_contents->words.move_left(); // so that next time we use old g + + need_one_newline = FALSE; +} + + +/* + * is_whole_line_bold - returns TRUE if the whole line is bold. + */ + +int html_printer::is_whole_line_bold (text_glob *g) +{ + text_glob *n=g; + int current_vpos=g->minv; + + do { + if (is_bold(n)) { + page_contents->words.move_right(); + n = page_contents->words.get_data(); + } else { + while (page_contents->words.get_data() != g) { + page_contents->words.move_left(); + } + return( FALSE ); + } + } while ((! page_contents->words.is_equal_to_head()) && (is_on_same_line(n, current_vpos))); + // was (n->minv == current_vpos) + while (page_contents->words.get_data() != g) { + page_contents->words.move_left(); + } + return( TRUE ); +} + + +/* + * is_a_header - returns TRUE if the whole sequence of contineous lines are bold. + * It checks to see whether a line is likely to be contineous and + * then checks that all words are bold. + */ + +int html_printer::is_a_header (text_glob *g) +{ + text_glob *l; + text_glob *n=g; + int current_vpos; + + do { + l = n; + current_vpos = n->minv; + if (is_bold(n)) { + page_contents->words.move_right(); + n = page_contents->words.get_data(); + } else { + while (page_contents->words.get_data() != g) { + page_contents->words.move_left(); + } + return( FALSE ); + } + } while ((! page_contents->words.is_equal_to_head()) && + ((n->minv == current_vpos) || (l->maxh == right_margin_indent))); + while (page_contents->words.get_data() != g) { + page_contents->words.move_left(); + } + return( TRUE ); +} + + +int html_printer::processed_header (text_glob *g) +{ + if ((guess_on) && (g->minh == left_margin_indent) && (! using_table_for_indent()) && + (is_a_header(g))) { + build_header(g); + write_header(); + return( TRUE ); + } else { + return( FALSE ); + } +} + +int is_punctuation (char *s, int length) +{ + return( (length == 1) && + ((s[0] == '(') || (s[0] == ')') || (s[0] == '!') || (s[0] == '.') || (s[0] == '[') || + (s[0] == ']') || (s[0] == '?') || (s[0] == ',') || (s[0] == ';') || (s[0] == ':') || + (s[0] == '@') || (s[0] == '#') || (s[0] == '$') || (s[0] == '%') || (s[0] == '^') || + (s[0] == '&') || (s[0] == '*') || (s[0] == '+') || (s[0] == '-') || (s[0] == '=') || + (s[0] == '{') || (s[0] == '}') || (s[0] == '|') || (s[0] == '\"') || (s[0] == '\'')) + ); +} + +/* + * move_horizontal - moves right into the position, g->minh. + */ + +void html_printer::move_horizontal (text_glob *g, int left_margin) +{ + if (g->text_style.f != 0) { + int w = g->text_style.f->get_space_width(g->text_style.point_size); + + if (w == 0) { + fatal("space width is zero"); + } + if ((output_hpos == left_margin) && (g->minh > output_hpos)) { + make_html_indent(g->minh-output_hpos); + } else { + emit_space(g, FALSE); + } + output_hpos = g->maxh; + output_vpos = g->minv; + + change_font(g, TRUE); + } +} + +int html_printer::looks_like_subscript (text_glob *g) +{ + return(((output_vpos < g->minv) && (output_style.point_size != 0) && + (output_style.point_size > g->text_style.point_size))); +} + + +int html_printer::looks_like_superscript (text_glob *g) +{ + return(((output_vpos > g->minv) && (output_style.point_size != 0) && + (output_style.point_size > g->text_style.point_size))); +} + +/* + * pretend_is_on_same_line - returns TRUE if we think, g, is on the same line as the previous glob. + * Note that it believes a single word spanning the left..right as being + * on a different line. + */ + +int html_printer::pretend_is_on_same_line (text_glob *g, int left_margin, int right_margin) +{ + return( auto_on && (right_margin == output_hpos) && (left_margin == g->minh) && + (right_margin != g->maxh) && ((! is_whole_line_bold(g)) || (g->text_style.f == output_style.f)) ); +} + +int html_printer::is_on_same_line (text_glob *g, int vpos) +{ + return( + (vpos >= 0) && + is_intersection(vpos, vpos+g->text_style.point_size*font::res/72-1, g->minv, g->maxv) + ); +} + + +/* + * make_html_indent - creates a relative indentation. + */ + +void html_printer::make_html_indent (int indent) +{ + int r=font::res; + + html.put_string("<span style=\" text-indent: "); + html.put_float(((double)(indent)/((double)r))); + html.put_string("in;\"></span>"); +} + +/* + * using_table_for_indent - returns TRUE if we currently using a table for indentation + * purposes. + */ + +int html_printer::using_table_for_indent (void) +{ + return( indentation.no_of_columns != 0 ); +} + +/* + * calculate_min_gap - returns the minimum gap by which we deduce columns. + * This is a rough heuristic. + */ + +int html_printer::calculate_min_gap (text_glob *g) +{ + return( g->text_style.f->get_space_width(g->text_style.point_size)*GAP_SPACES ); +} + +/* + * collect_columns - place html text in a column and return the vertical limit reached. + */ + +int html_printer::collect_columns (struct text_defn *line, struct text_defn *last, int max_words) +{ + text_glob *start = page_contents->words.get_data(); + text_glob *t = start; + int upper_limit = 0; + + line[0].left = 0; + line[0].right = 0; + if (start != 0) { + int graphic_limit = end_region_vpos; + + if (is_whole_line_bold(t) && (t->minh == left_margin_indent)) { + // found header therefore terminate indentation table + upper_limit = -t->minv; // so we know a header has stopped the column + } else { + int i =0; + int j =0; + int prevh =0; + int mingap =calculate_min_gap(start); + + while ((t != 0) && (is_on_same_line(t, start->minv) && (i<max_words)) && + ((graphic_limit == -1) || (graphic_limit > t->minv))) { + while ((last != 0) && (j<max_words) && (last[j].left != 0) && (last[j].left < t->minh)) { + j++; + } + // t->minh might equal t->maxh when we are passing a special device character via \X + // we currently ignore these when considering tables + if (((t->minh - prevh >= mingap) || ((last != 0) && (last[j].left != 0) && (t->minh == last[j].left))) && + (t->minh != t->maxh)) { + line[i].left = t->minh; + line[i].right = t->maxh; + i++; + } else if (i>0) { + line[i-1].right = t->maxh; + } + + // and record the vertical upper limit + upper_limit = max(t->minv, upper_limit); + + prevh = t->maxh; + page_contents->words.move_right(); + t = page_contents->words.get_data(); + if (page_contents->words.is_equal_to_head()) { + t = 0; + } + } + + if (i<max_words) { + line[i].left = 0; + line[i].right = 0; + } + } + } + return( upper_limit ); +} + +/* + * conflict_with_words - returns TRUE if a word sequence crosses a column. + */ + +int html_printer::conflict_with_words (struct text_defn *column_guess, struct text_defn *words) +{ + int i=0; + int j; + + while ((column_guess[i].left != 0) && (i<MAX_WORDS_PER_LINE)) { + j=0; + while ((words[j].left != 0) && (j<MAX_WORDS_PER_LINE)) { + if ((words[j].left <= column_guess[i].right) && (i+1<MAX_WORDS_PER_LINE) && + (column_guess[i+1].left != 0) && (words[j].right >= column_guess[i+1].left)) { + if (debug_table_on) { + fprintf(stderr, "is a conflict with words\n"); + fflush(stderr); + } + return( TRUE ); + } + j++; + } + i++; + } + if (debug_table_on) { + fprintf(stderr, "is NOT a conflict with words\n"); + fflush(stderr); + } + return( FALSE ); +} + +/* + * combine_line - combines dest and src. + */ + +void html_printer::combine_line (struct text_defn *dest, struct text_defn *src) +{ + int i; + + for (i=0; (i<MAX_WORDS_PER_LINE) && (src[i].left != 0); i++) { + include_into_list(dest, &src[i]); + } + remove_redundant_columns(dest); +} + +/* + * remove_entry_in_line - removes an entry, j, in, line. + */ + +void html_printer::remove_entry_in_line (struct text_defn *line, int j) +{ + while (line[j].left != 0) { + line[j].left = line[j+1].left; + line[j].right = line[j+1].right; + j++; + } +} + +/* + * remove_redundant_columns - searches through the array columns and removes any redundant entries. + */ + +void html_printer::remove_redundant_columns (struct text_defn *line) +{ + int i=0; + int j=0; + + while (line[i].left != 0) { + if ((i<MAX_WORDS_PER_LINE) && (line[i+1].left != 0)) { + j = 0; + while ((j<MAX_WORDS_PER_LINE) && (line[j].left != 0)) { + if ((j != i) && (is_intersection(line[i].left, line[i].right, line[j].left, line[j].right))) { + line[i].left = min(line[i].left , line[j].left); + line[i].right = max(line[i].right, line[j].right); + remove_entry_in_line(line, j); + } else { + j++; + } + } + } + i++; + } +} + +/* + * include_into_list - performs an order set inclusion + */ + +void html_printer::include_into_list (struct text_defn *line, struct text_defn *item) +{ + int i=0; + + while ((i<MAX_WORDS_PER_LINE) && (line[i].left != 0) && (line[i].left<item->left)) { + i++; + } + + if (line[i].left == 0) { + // add to the end + if (i<MAX_WORDS_PER_LINE) { + if ((i>0) && (line[i-1].left > item->left)) { + fatal("insertion error"); + } + line[i].left = item->left; + line[i].right = item->right; + i++; + line[i].left = 0; + line[i].right = 0; + } + } else { + if (line[i].left == item->left) { + line[i].right = max(item->right, line[i].right); + } else { + // insert + int left = item->left; + int right = item->right; + int l = line[i].left; + int r = line[i].right; + + while ((i+1<MAX_WORDS_PER_LINE) && (line[i].left != 0)) { + line[i].left = left; + line[i].right = right; + i++; + left = l; + right = r; + l = line[i].left; + r = line[i].right; + } + if (i+1<MAX_WORDS_PER_LINE) { + line[i].left = left; + line[i].right = right; + line[i+1].left = 0; + line[i+1].right = 0; + } + } + } +} + +/* + * is_in_column - return TRUE if value is present in line. + */ + +int html_printer::is_in_column (struct text_defn *line, struct text_defn *item, int max_words) +{ + int i=0; + + while ((i<max_words) && (line[i].left != 0)) { + if (line[i].left == item->left) { + return( TRUE ); + } else { + i++; + } + } + return( FALSE ); +} + +/* + * calculate_right - calculate the right most margin for each column in line. + */ + +void html_printer::calculate_right (struct text_defn *line, int max_words) +{ + int i=0; + + while ((i<max_words) && (line[i].left != 0)) { + if (i>0) { + line[i-1].right = line[i].left; + } + i++; + } +} + +/* + * add_right_full_width - adds an extra column to the right to bring the table up to + * full width. + */ + +void html_printer::add_right_full_width (struct text_defn *line, int mingap) +{ + int i=0; + + while ((i<MAX_WORDS_PER_LINE) && (line[i].left != 0)) { + i++; + } + + if ((i>0) && (line[i-1].right != right_margin_indent) && (i+1<MAX_WORDS_PER_LINE)) { + line[i].left = min(line[i-1].right+mingap, right_margin_indent); + line[i].right = right_margin_indent; + i++; + if (i<MAX_WORDS_PER_LINE) { + line[i].left = 0; + line[i].right = 0; + } + } +} + +/* + * determine_right_most_column - works out the right most limit of the right most column. + * Required as we might be performing a .2C and only + * have enough text to fill the left column. + */ + +void html_printer::determine_right_most_column (struct text_defn *line, int max_words) +{ + int i=0; + + while ((i<max_words) && (line[i].left != 0)) { + i++; + } + if (i>0) { + // remember right_margin_indent is the right most position for this page + line[i-1].right = column_calculate_right_margin(line[i-1].left, right_margin_indent); + } +} + +/* + * is_column_match - returns TRUE if a word is aligned in the same horizontal alignment + * between two lines, line1 and line2. If so then this horizontal + * position is saved in match. + */ + +int html_printer::is_column_match (struct text_defn *match, + struct text_defn *line1, struct text_defn *line2, int max_words) +{ + int i=0; + int j=0; + int found=FALSE; + int first=(match[0].left==0); + + if (first) { + struct text_defn t; + + t.left = left_margin_indent; + t.right = 0; + + include_into_list(match, &t); + } + while ((line1[i].left != 0) && (line2[i].left != 0)) { + if (line1[i].left == line2[j].left) { + // same horizontal alignment found + include_into_list(match, &line1[i]); + i++; + j++; + found = TRUE; + } else if (line1[i].left < line2[j].left) { + i++; + } else { + j++; + } + } + calculate_right(match, max_words); + return( found ); +} + + +/* + * remove_white_using_words - remove white space in, last_guess, by examining, next_line + * placing results into next_guess. + * It returns TRUE if the same columns exist in next_guess and last_guess + * we do allow columns to shrink but if a column disappears then we return FALSE. + */ + +int html_printer::remove_white_using_words (struct text_defn *next_guess, + struct text_defn *last_guess, struct text_defn *next_line) +{ + int i=0; + int j=0; + int k=0; + int removed=FALSE; + + while ((last_guess[j].left != 0) && (next_line[k].left != 0)) { + if (last_guess[j].left == next_line[k].left) { + // same horizontal alignment found + next_guess[i].left = last_guess[j].left; + next_guess[i].right = max(last_guess[j].right, next_line[k].right); + i++; + j++; + k++; + if ((next_guess[i-1].right > last_guess[j].left) && (last_guess[j].left != 0)) { + removed = TRUE; + } + } else if (last_guess[j].right < next_line[k].left) { + next_guess[i].left = last_guess[j].left; + next_guess[i].right = last_guess[j].right; + i++; + j++; + } else if (last_guess[j].left > next_line[k].right) { + // insert a word sequence from next_line[k] + next_guess[i].left = next_line[k].left; + next_guess[i].right = next_line[k].right; + i++; + k++; + } else if (is_intersection(last_guess[j].left, last_guess[j].right, next_line[k].left, next_line[k].right)) { + // potential for a column disappearing + next_guess[i].left = min(last_guess[j].left , next_line[k].left); + next_guess[i].right = max(last_guess[j].right, next_line[k].right); + i++; + j++; + k++; + if ((next_guess[i-1].right > last_guess[j].left) && (last_guess[j].left != 0)) { + removed = TRUE; + } + } + } + if (i<MAX_WORDS_PER_LINE) { + next_guess[i].left = 0; + next_guess[i].right = 0; + } + if (debug_table_on) { + if (removed) { + fprintf(stderr, "have removed column\n"); + } else { + fprintf(stderr, "have NOT removed column\n"); + } + fflush(stderr); + } + remove_redundant_columns(next_guess); + return( removed ); +} + +/* + * count_columns - returns the number of elements inside, line. + */ + +int html_printer::count_columns (struct text_defn *line) +{ + int i=0; + + while (line[i].left != 0) { + i++; + } + return( i ); +} + +/* + * rewind_text_to - moves backwards until page_contents is looking at, g. + */ + +void html_printer::rewind_text_to (text_glob *g) +{ + while (page_contents->words.get_data() != g) { + if (page_contents->words.is_equal_to_head()) { + page_contents->words.start_from_tail(); + } else { + page_contents->words.move_left(); + } + } +} + +/* + * display_columns - a long overdue debugging function, as this column code is causing me grief :-( + */ + +void html_printer::display_columns (const char *word, const char *name, text_defn *line) +{ + int i=0; + + fprintf(stderr, "[%s:%s]", name, word); + while (line[i].left != 0) { + fprintf(stderr, " <left=%d right=%d> ", line[i].left, line[i].right); + i++; + } + fprintf(stderr, "\n"); + fflush(stderr); +} + +/* + * copy_line - dest = src + */ + +int html_printer::copy_line (struct text_defn *dest, struct text_defn *src) +{ + int k; + + for (k=0; ((src[k].left != 0) && (k<MAX_WORDS_PER_LINE)); k++) { + dest[k].left = src[k].left; + dest[k].right = src[k].right; + } + if (k<MAX_WORDS_PER_LINE) { + dest[k].left = 0; + dest[k].right = 0; + } +} + +/* + * add_column_gaps - adds empty columns between columns which don't exactly align + */ + +void html_printer::add_column_gaps (struct text_defn *line) +{ + int i=0; + struct text_defn t; + + // firstly lets see whether we need an initial column on the left hand side + if ((line[0].left != left_margin_indent) && (line[0].left != 0) && + (left_margin_indent < line[0].left) && (is_worth_column(left_margin_indent, line[0].left))) { + t.left = left_margin_indent; + t.right = line[0].left; + include_into_list(line, &t); + } + + while ((i<MAX_WORDS_PER_LINE) && (line[i].left != 0)) { + if ((i+1<MAX_WORDS_PER_LINE) && (line[i+1].left != 0) && (line[i].right != line[i+1].left) && + (is_worth_column(line[i].right, line[i+1].left))) { + t.left = line[i].right; + t.right = line[i+1].left; + include_into_list(line, &t); + i=0; + } else { + i++; + } + } + // lastly lets see whether we need a final column on the right hand side + if ((i>0) && (line[i-1].right != right_margin_indent) && + (is_worth_column(line[i-1].right, right_margin_indent))) { + t.left = line[i-1].right; + t.right = right_margin_indent; + include_into_list(line, &t); + } +} + +/* + * is_continueous_column - returns TRUE if a line has a word on one + * of the last_col right most boundaries. + */ + +int html_printer::is_continueous_column (text_defn *last_col, text_defn *next_line) +{ + int w = count_columns(next_line); + int c = count_columns(last_col); + int i, j; + + for (i=0; i<c; i++) { + for (j=0; j<w; j++) { + if (last_col[i].right == next_line[j].right) { + return( TRUE ); + } + } + } + return( FALSE ); +} + +/* + * is_exact_left - returns TRUE if a line has a word on one + * of the last_col left most boundaries. + */ + +int html_printer::is_exact_left (text_defn *last_col, text_defn *next_line) +{ + int w = count_columns(next_line); + int c = count_columns(last_col); + int i, j; + + for (i=0; i<c; i++) { + for (j=0; j<w; j++) { + if ((last_col[i].left == next_line[j].left) || + (last_col[i].left != left_margin_indent)) { + return( TRUE ); + } + } + } + return( FALSE ); +} + +/* + * continue_searching_column - decides whether we should carry on searching text for a column. + */ + +int html_printer::continue_searching_column (text_defn *next_col, + text_defn *last_col, + text_defn *all_words) +{ + int count = count_columns(next_col); + int words = count_columns(all_words); + + if ((words == 0) || ((words == 1) && + (all_words[0].left == left_margin_indent) && + (all_words[0].right == right_margin_indent))) { + // no point as we have now seen a full line of contineous text + return( FALSE ); + } + return( (count == count_columns(last_col)) && + (last_col[0].left != left_margin_indent) || (last_col[0].right != right_margin_indent) ); +} + +/* + * is_worth_column - returns TRUE if the size of this column is worth defining. + */ + +int html_printer::is_worth_column (int left, int right) +{ +#if 0 + return( abs(right-left) >= MIN_COLUMN ); +#endif + return( TRUE ); +} + +/* + * large_enough_gap - returns TRUE if a large enough gap for one line was seen. + * We need to make sure that a single line definitely warrents + * a table. + * It also removes other smaller gaps. + */ + +int html_printer::large_enough_gap (text_defn *last_col) +{ + int i=0; + int found=FALSE; + int r=font::res; + int gap=r/GAP_WIDTH_ONE_LINE; + + if (abs(last_col[i].left - left_margin_indent) >= gap) { + found = TRUE; + } + while ((last_col[i].left != 0) && (last_col[i+1].left != 0)) { + if (abs(last_col[i+1].left-last_col[i].right) >= gap) { + found = TRUE; + i++; + } else { + // not good enough for a single line, remove it + if (i>0) { + last_col[i-1].right = last_col[i].right; + } + remove_entry_in_line(last_col, i); + } + } + return( found ); +} + +/* + * is_subset_of_columns - returns TRUE if line, a, is a subset of line, b. + */ + +int html_printer::is_subset_of_columns (text_defn *a, text_defn *b) +{ + int i; + int j; + + i=0; + while ((i<MAX_WORDS_PER_LINE) && (a[i].left != 0)) { + j=0; + while ((j<MAX_WORDS_PER_LINE) && (b[j].left != 0) && + ((b[j].left != a[i].left) || (b[j].right != a[i].right))) { + j++; + } + if ((j==MAX_WORDS_PER_LINE) || (b[j].left == 0)) { + // found a different column - not a subset + return( FALSE ); + } + i++; + } + return( TRUE ); +} + +/* + * count_hits - counts the number of hits per column. A hit is when the + * left hand position of a glob hits the left hand column. + */ + +void html_printer::count_hits (text_defn *col) +{ + int i; + text_glob *start = page_contents->words.get_data(); + text_glob *g = start; + int r = font::res; + int gap = r/GAP_WIDTH_ONE_LINE; + int n = count_columns(col); + int left; + + // firstly reset the used field + for (i=0; i<n; i++) { + col[i].is_used = 0; + } + // now calculate the left hand hits + while ((g != 0) && (g->minv <= indentation.vertical_limit)) { + i=0; + while ((col[i].left < g->minh) && (col[i].left != 0)) { + i++; + } + if ((col[i].left == g->minh) && (col[i].left != 0)) { + col[i].is_used++; + } + page_contents->words.move_right(); + if (page_contents->words.is_equal_to_head()) { + g = 0; + page_contents->words.start_from_tail(); + } else { + g=page_contents->words.get_data(); + } + } + // now remove any column which is less than the + // minimal gap for one hit. + // column 0 is excempt + + left = col[0].left; + i=1; + while (i<count_columns(col)) { + if (col[i].is_used == 1) { + if (col[i].left - left < gap) { + col[i-1].right = col[i].right; + remove_entry_in_line(col, i); + left = col[i].left; + } else { + left = col[i].left; + i++; + } + } else { + left = col[i].left; + i++; + } + } +} + +/* + * found_use_for_table - checks whether the some words on one line directly match + * the horizontal alignment of the line below. + */ + +int html_printer::found_use_for_table (text_glob *start) +{ + text_glob *t; + struct text_defn all_words [MAX_WORDS_PER_LINE]; + struct text_defn last_raw [MAX_WORDS_PER_LINE]; + struct text_defn next_line [MAX_WORDS_PER_LINE]; + struct text_defn prev_guess[MAX_WORDS_PER_LINE]; + struct text_defn last_guess[MAX_WORDS_PER_LINE]; + struct text_defn next_guess[MAX_WORDS_PER_LINE]; + int i =0; + int lines =0; + int mingap=calculate_min_gap(start); + int limit; + +#if 0 + if (strcmp(start->text_string, "man") == 0) { + stop(); + } +#endif + + // get first set of potential columns into line1 + limit = collect_columns(last_guess, 0, MAX_WORDS_PER_LINE); + copy_line(last_raw, last_guess); + // add_right_full_width(last_guess, mingap); // adds extra right column to bring table to full width + + copy_line(all_words, last_guess); + indentation.vertical_limit = limit; + + if (page_contents->words.is_equal_to_head() || (limit == 0)) { + next_line[0].left = 0; + next_line[0].right = 0; + } else { + // and get the next line for finding columns + limit = collect_columns(next_line, last_guess, MAX_WORDS_PER_LINE); + lines++; + } + + // now check to see whether the first line looks like a single centered line + + if (single_centered_line(last_raw, next_line, start)) { + rewind_text_to(start); + write_centered_line(start); + indentation.no_of_columns = 0; // center instead + return( TRUE ); + } else if (! table_on) { + rewind_text_to(start); + return( FALSE ); + } + + combine_line(all_words, next_line); + if (debug_table_on) { + display_columns(start->text_string, "[b] all_words", all_words); + } + + if ((! remove_white_using_words(next_guess, last_guess, next_line))) { + } + + if ((! conflict_with_words(next_guess, all_words)) && + (continue_searching_column(next_guess, next_guess, all_words)) && + (! page_contents->words.is_equal_to_head()) && + ((end_region_vpos < 0) || (limit < end_region_vpos)) && + (limit > 0)) { + + combine_line(last_guess, next_line); + // subtract any columns which are bridged by a sequence of words + do { + copy_line(prev_guess, next_guess); + combine_line(last_guess, next_guess); + + if (debug_table_on) { + t = page_contents->words.get_data(); + display_columns(t->text_string, "[l] last_guess", last_guess); + } + indentation.vertical_limit = limit; + + copy_line(last_raw, next_line); + if (page_contents->words.is_equal_to_head()) { + next_line[0].left = 0; + next_line[0].right = 0; + } else { + limit = collect_columns(next_line, last_guess, MAX_WORDS_PER_LINE); + lines++; + } + + combine_line(all_words, next_line); + if (debug_table_on) { + display_columns(t->text_string, "[l] all_words", all_words); + display_columns(t->text_string, "[l] last_raw ", last_raw); + } + + if (debug_table_on) { + display_columns(t->text_string, "[l] next_line", next_line); + } + t = page_contents->words.get_data(); +#if 0 + if (strcmp(t->text_string, "market,") == 0) { + stop(); + } +#endif + + } while ((! remove_white_using_words(next_guess, last_guess, next_line)) && + (! conflict_with_words(next_guess, all_words)) && + (continue_searching_column(next_guess, last_guess, all_words)) && + ((is_continueous_column(prev_guess, last_raw)) || (is_exact_left(last_guess, next_line))) && + (! page_contents->words.is_equal_to_head()) && + ((end_region_vpos <= 0) || (t->minv < end_region_vpos)) && + (limit >= 0)); + } + lines--; + + if (limit < 0) { + indentation.vertical_limit = limit; + } + + if (page_contents->words.is_equal_to_head()) { + // end of page check whether we should include everything + if ((! conflict_with_words(next_guess, all_words)) && + (continue_searching_column(next_guess, last_guess, all_words)) && + ((is_continueous_column(prev_guess, last_raw)) || (is_exact_left(last_guess, next_line)))) { + // end of page reached - therefore include everything + page_contents->words.start_from_tail(); + t = page_contents->words.get_data(); + indentation.vertical_limit = t->minv; + } + } else { + t = page_contents->words.get_data(); + if ((end_region_vpos > 0) && (t->minv > end_region_vpos)) { + indentation.vertical_limit = min(indentation.vertical_limit, end_region_vpos+1); + } else if (indentation.vertical_limit < 0) { + // -1 as we don't want to include section heading itself + indentation.vertical_limit = -indentation.vertical_limit-1; + } + } + + if (debug_table_on) { + display_columns(start->text_string, "[x] last_guess", last_guess); + } + rewind_text_to(start); + + i = count_columns(last_guess); + if (((lines > 2) && ((i>1) || (continue_searching_column(last_guess, last_guess, all_words)))) || + ((lines == 1) && (large_enough_gap(last_guess)))) { + // copy match into permenant html_table + + if (indentation.columns != 0) { + free(indentation.columns); + } + if (debug_table_on) { + display_columns(start->text_string, "[x] last_guess", last_guess); + } + add_column_gaps(last_guess); + if (debug_table_on) { + display_columns(start->text_string, "[g] last_guess", last_guess); + } + + indentation.no_of_columns = count_columns(last_guess); + indentation.columns = (struct text_defn *)malloc(indentation.no_of_columns*sizeof(struct text_defn)); + + i=0; + while (i<indentation.no_of_columns) { + indentation.columns[i].left = last_guess[i].left; + indentation.columns[i].right = last_guess[i].right; + i++; + } + return( TRUE ); + } else { + return( FALSE ); + } +} + +void html_printer::define_cell (int left, int right) +{ + float f=((float)(right-left))/((float)(right_margin_indent-left_margin_indent))*100.0; + + html.put_string("<td valign=\"top\" align=\"left\" width=\""); + if (f > 1.0) { + html.put_float(f); + } else { + html.put_float(1.0); + } + html.put_string("%\">\n"); +} + +/* + * column_display_word - given a left, right pair and the indentation.vertical_limit + * write out html text within this region. + */ + +void html_printer::column_display_word (int vert, int left, int right, int next) +{ + text_glob *g=page_contents->words.get_data(); + + if (left != next) { + define_cell(left, next); + begin_paragraph_no_height(left_alignment); + while ((g != 0) && (g->minv <= vert)) { + if ((left <= g->minh) && (g->minh<right)) { + char *postword=html_position_text(g, left, right); + + if (header.written_header) { + fatal("should never generate a header inside a table"); + } else { + if (g->is_raw_command) { + html.put_string((char *)g->text_string); + } else { + html.html_write_string((char *)g->text_string); + } + if (postword != 0) { + html.put_string(postword); + } + issued_newline = FALSE; + } + } + if (page_contents->words.is_equal_to_tail()) { + g = 0; + } else { + page_contents->words.move_right(); + g=page_contents->words.get_data(); + } +#if 0 + if (page_contents->words.is_equal_to_head()) { + g = 0; + page_contents->words.start_from_tail(); + } else { + + } +#endif + } + end_paragraph(); + html.put_string("</td>\n"); + if (g != 0) { + page_contents->words.move_left(); + // and correct output_vpos + g=page_contents->words.get_data(); + output_vpos = g->minv; + } + } +} + +/* + * start_table - creates a table according with parameters contained within class html_table. + */ + +void html_printer::start_table (void) +{ + int i; + + end_paragraph(); + html.put_string("\n<table width=\"100%\" rules=\"none\" frame=\"none\" cols=\""); + html.put_number(indentation.no_of_columns); + html.put_string("\">\n"); +} + +/* + * end_table - finishes off a table. + */ + +void html_printer::end_table (void) +{ + html.put_string("</table>\n"); + indentation.no_of_columns = 0; +} + +/* + * column_calculate_right_margin - scan through the column and find the right most margin + */ + +int html_printer::column_calculate_right_margin (int left, int right) +{ + if (left == right) { + return( right ); + } else { + int rightmost =-1; + int count = 0; + text_glob *start = page_contents->words.get_data(); + text_glob *g = start; + + while ((g != 0) && (g->minv <= indentation.vertical_limit)) { + if ((left <= g->minh) && (g->minh<right)) { + if (debug_on) { + fprintf(stderr, "right word = %s %d\n", g->text_string, g->maxh); fflush(stderr); + } + if (g->maxh == rightmost) { + count++; + } else if (g->maxh > rightmost) { + count = 1; + rightmost = g->maxh; + } + if (g->maxh > right) { + if (debug_on) { + fprintf(stderr, "problem as right word = %s %d [%d..%d]\n", + g->text_string, right, g->minh, g->maxh); fflush(stderr); + stop(); + } + } + } + page_contents->words.move_right(); + if (page_contents->words.is_equal_to_head()) { + g = 0; + page_contents->words.start_from_tail(); + } else { + g=page_contents->words.get_data(); + } + } + rewind_text_to(start); + if (rightmost == -1) { + return( right ); // no words in this column + } else { + if (count == 1) { + return( rightmost+1 ); + } else { + return( rightmost ); + } + } + } +} + +/* + * column_calculate_left_margin - scan through the column and find the left most margin + */ + +int html_printer::column_calculate_left_margin (int left, int right) +{ + if (left == right) { + return( left ); + } else { + int leftmost=right; + text_glob *start = page_contents->words.get_data(); + text_glob *g = start; + + while ((g != 0) && (g->minv <= indentation.vertical_limit)) { + if ((left <= g->minh) && (g->minh<right)) { + leftmost = min(g->minh, leftmost); + } + page_contents->words.move_right(); + if (page_contents->words.is_equal_to_head()) { + g = 0; + page_contents->words.start_from_tail(); + } else { + g=page_contents->words.get_data(); + } + } + rewind_text_to(start); + if (leftmost == right) { + return( left ); // no words in this column + } else { + return( leftmost ); + } + } +} + +/* + * find_column_index - returns the index to the column in which glob, t, exists. + */ + +int html_printer::find_column_index (text_glob *t) +{ + int i=0; + + while ((i<indentation.no_of_columns) && + (! ((indentation.columns[i].left<=t->minh) && + (indentation.columns[i].right>t->minh)))) { + i++; + } + return( i ); +} + +/* + * determine_row_limit - checks each row to see if there is a gap in a cell. + * We return the vertical position after the empty cell + * at the start of the next line. + */ + +int html_printer::determine_row_limit (text_glob *start, int v) +{ + text_glob *t; + int i; + int vpos, prev, last; + int is_gap[MAX_WORDS_PER_LINE]; + + if (v >= indentation.vertical_limit) { + return( v+1 ); + } else { + // initially we start with all gaps in our table + // after a gap we start a new row + // here we set the gap array to the previous line + + if (v>=0) { + t = page_contents->words.get_data(); + if (t->minv < v) { + do { + page_contents->words.move_right(); + t = page_contents->words.get_data(); + } while ((! page_contents->words.is_equal_to_head()) && + (t->minv <= v)); + } + } + if (! page_contents->words.is_equal_to_head()) { + page_contents->words.move_left(); + } + t = page_contents->words.get_data(); + prev = t->minv; + for (i=0; i<indentation.no_of_columns; i++) { + is_gap[i] = prev; + } + + if (! page_contents->words.is_equal_to_tail()) { + page_contents->words.move_right(); + } + t = page_contents->words.get_data(); + vpos = t->minv; + + // now check each row for a gap + do { + last = vpos; + vpos = t->minv; + i = find_column_index(t); + if (! is_on_same_line(t, last)) { + prev = last; + } + + if ((is_gap[i] != vpos) && (is_gap[i] != prev) && + (indentation.columns[i].is_used)) { + // no word on previous line - must be a gap - force alignment of row + rewind_text_to(start); + return( last ); + } + is_gap[i] = vpos; + page_contents->words.move_right(); + t = page_contents->words.get_data(); + } while ((! page_contents->words.is_equal_to_head()) && + (vpos < indentation.vertical_limit) && (vpos >= last)); + page_contents->words.move_left(); + t = page_contents->words.get_data(); + rewind_text_to(start); + return( indentation.vertical_limit ); + } +} + +/* + * assign_used_columns - sets the is_used field of the column array of records. + */ + +void html_printer::assign_used_columns (text_glob *start) +{ + text_glob *t = start; + int i; + + for (i=0; i<indentation.no_of_columns; i++) { + indentation.columns[i].is_used = FALSE; + } + + rewind_text_to(start); + if (! page_contents->words.is_empty()) { + do { + i = find_column_index(t); + if (indentation.columns[i].left != 0) { + if (debug_table_on) { + fprintf(stderr, "[%s] in column %d at %d..%d limit %d\n", t->text_string, + i, t->minv, t->maxv, indentation.vertical_limit); fflush(stderr); + } + indentation.columns[i].is_used = TRUE; + } + page_contents->words.move_right(); + t = page_contents->words.get_data(); + } while ((t->minv<indentation.vertical_limit) && + (! page_contents->words.is_equal_to_head())); + } + if (debug_table_on) { + for (i=0; i<indentation.no_of_columns; i++) { + fprintf(stderr, " <left=%d right=%d is_used=%d> ", + indentation.columns[i].left, + indentation.columns[i].right, + indentation.columns[i].is_used); + } + fprintf(stderr, "\n"); + fflush(stderr); + } +} + +/* + * foreach_column_include_text - foreach column in a table place the + * appropriate html text. + */ + +void html_printer::foreach_column_include_text (text_glob *start) +{ + if (indentation.no_of_columns>0) { + int i; + int left, right; + int limit=-1; + + assign_used_columns(start); + start_table(); + rewind_text_to(start); + + do { + limit = determine_row_limit(start, limit); // find the bottom of the next row + html.put_string("<tr valign=\"top\" align=\"left\">\n"); + i=0; + start = page_contents->words.get_data(); + while (i<indentation.no_of_columns) { + // reset the output position to the start of column + rewind_text_to(start); + output_vpos = start->minv; + output_hpos = indentation.columns[i].left; + // and display each column until limit + right = column_calculate_right_margin(indentation.columns[i].left, + indentation.columns[i].right); + left = column_calculate_left_margin(indentation.columns[i].left, + indentation.columns[i].right); + + if (right>indentation.columns[i].right) { + if (debug_on) { + fprintf(stderr, "assert calculated right column edge is greater than column\n"); fflush(stderr); + stop(); + } + } + + if (left<indentation.columns[i].left) { + if (debug_on) { + fprintf(stderr, "assert calculated left column edge is less than column\n"); fflush(stderr); + stop(); + } + } + + column_display_word(limit, left, right, indentation.columns[i].right); + i++; + } + + if (page_contents->words.is_equal_to_tail()) { + start = 0; + } else { + page_contents->words.sub_move_right(); + if (page_contents->words.is_empty()) { + start = 0; + } else { + start = page_contents->words.get_data(); + } + } + + html.put_string("</tr>\n"); + } while ((limit < indentation.vertical_limit) && (start != 0) && + (! page_contents->words.is_empty())); + end_table(); + + if (start == 0) { + // finished page remove all words + page_contents->words.start_from_head(); + while (! page_contents->words.is_empty()) { + page_contents->words.sub_move_right(); + } + } else if (! page_contents->words.is_empty()) { + page_contents->words.move_left(); + } + } +} + +/* + * write_centered_line - generates a line of centered text. + */ + +void html_printer::write_centered_line (text_glob *g) +{ + int current_vpos=g->minv; + + move_vertical(g, center_alignment); + + header.written_header = FALSE; + output_vpos = g->minv; + output_hpos = g->minh; + do { + char *postword=html_position_text(g, left_margin_indent, right_margin_indent); + + if (! header.written_header) { + if (g->is_raw_command) { + html.put_string((char *)g->text_string); + } else { + html.html_write_string((char *)g->text_string); + } + if (postword != 0) { + html.put_string(postword); + } + need_one_newline = TRUE; + issued_newline = FALSE; + } + page_contents->words.move_right(); + g = page_contents->words.get_data(); + } while ((! page_contents->words.is_equal_to_head()) && (g->minv == current_vpos)); + page_contents->words.move_left(); // so when we move right we land on the word following this centered line + need_one_newline = TRUE; +} + +/* + * is_in_middle - returns TRUE if the text defn, t, is in the middle of the page. + */ + +int html_printer::is_in_middle (int left, int right) +{ + return( abs(abs(left-left_margin_indent) - abs(right_margin_indent-right)) <= CENTER_TOLERANCE ); +} + +/* + * single_centered_line - returns TRUE if first is a centered line with a different + * margin to second. + */ + +int html_printer::single_centered_line (text_defn *first, text_defn *second, text_glob *g) +{ + return( + ((count_columns(first) == 1) && (first[0].left != left_margin_indent) && + (first[0].left != second[0].left) && is_in_middle(first->left, first->right)) + ); +} + +/* + * check_able_to_use_center - returns TRUE if we can see a centered line. + */ + +int html_printer::check_able_to_use_center (text_glob *g) +{ + if (auto_on && table_on && ((! is_on_same_line(g, output_vpos)) || issued_newline) && (! using_table_for_indent())) { + // we are allowed to check for centered line + // first check to see whether we might be looking at a set of columns + struct text_defn last_guess[MAX_WORDS_PER_LINE]; + int limit = collect_columns(last_guess, 0, MAX_WORDS_PER_LINE); + + rewind_text_to(g); + if ((count_columns(last_guess) == 1) && (is_in_middle(last_guess[0].left, last_guess[0].right))) { + write_centered_line(g); + return( TRUE ); + } + } + return( FALSE ); +} + +/* + * check_able_to_use_table - examines forthcoming text to see whether we can + * better format it by using an html transparent table. + */ + +int html_printer::check_able_to_use_table (text_glob *g) +{ + if (auto_on && ((! is_on_same_line(g, output_vpos)) || issued_newline) && (! using_table_for_indent())) { + // we are allowed to check for table + + if ((output_hpos != right_margin_indent) && (found_use_for_table(g))) { + foreach_column_include_text(g); + return( TRUE ); + } + } + return( FALSE ); +} + +/* + * move_vertical - if we are using html auto formatting then decide whether to + * break the line via a <br> or a </p><p> sequence. + */ + +void html_printer::move_vertical (text_glob *g, paragraph_type p) +{ + int r =font::res; + int height = (g->text_style.point_size+2)*r/72; // --fixme-- we always assume VS is PS+2 (could do better) + int temp_vpos; + + if (auto_on) { + if ((more_than_line_break(output_vpos, g->minv, height)) || (p != para_type)) { + end_paragraph(); + begin_paragraph(p); + } else { + html_newline(); + } + } else { + if (output_vpos == -1) { + temp_vpos = g->minv; + } else { + temp_vpos = output_vpos; + } + + force_begin_paragraph(); + if (need_one_newline) { + html_newline(); + temp_vpos += height; + } else { + need_one_newline = TRUE; + } + + while ((temp_vpos < g->minv) && (more_than_line_break(temp_vpos, g->minv, height))) { + html_newline(); + temp_vpos += height; + } + } +} + +/* + * emit_space - emits a space within html, it checks for the font type and + * will change font depending upon, g. Courier spaces are larger + * than roman so we need consistancy when changing between them. + */ + +void html_printer::emit_space (text_glob *g, int force_space) +{ + if (! need_paragraph) { + // only generate a space if we have written a word - as html will ignore it otherwise + if ((output_style != g->text_style) && (g->text_style.f != 0)) { + terminate_current_font(); + } + if (force_space || (g->minh > output_hpos)) { + html.put_string(" "); + } + change_font(g, TRUE); + } +} + +/* + * html_position_text - determine whether the text is subscript/superscript/normal + * or a header. + */ + +char *html_printer::html_position_text (text_glob *g, int left_margin, int right_margin) +{ + char *postword=0; + +#if 0 + if (strcmp(g->text_string, "increased.") == 0) { + stop(); + } +#endif + begin_paragraph(left_alignment); + + if ((! header.written_header) && + (is_on_same_line(g, output_vpos) || + pretend_is_on_same_line(g, left_margin, right_margin))) { + // check whether the font was reset after generating an image + + header.written_header = FALSE; + force_begin_paragraph(); + + // check whether we need to insert white space between words on 'same' line + if (pretend_is_on_same_line(g, left_margin, right_margin)) { + emit_space(g, TRUE); + } + + if (output_style.f == 0) { + change_font(g, TRUE); + } + + if (looks_like_subscript(g)) { + + g->text_style.point_size = output_style.point_size; + g->minv = output_vpos; // this ensures that output_vpos doesn't alter + // which allows multiple subscripted words + move_horizontal(g, left_margin); + html.put_string("<sub>"); + postword = "</sub>"; + } else if (looks_like_superscript(g)) { + + g->text_style.point_size = output_style.point_size; + g->minv = output_vpos; + + move_horizontal(g, left_margin); + html.put_string("<sup>"); + postword = "</sup>"; + } else { + move_horizontal(g, left_margin); + } + } else { + // we have found a new line + if (! header.written_header) { + move_vertical(g, left_alignment); + } + header.written_header = FALSE; + + if (processed_header(g)) { + // we must not alter output_vpos as we have peeped at the next word + // and set vpos to this - to ensure we do not generate a <br> after + // a heading. (The html heading automatically generates a line break) + output_hpos = left_margin; + return( postword ); + } else { + force_begin_paragraph(); + if (g->minh-left_margin != 0) { + make_html_indent(g->minh-left_margin); + } + change_font(g, TRUE); + } + } + output_vpos = g->minv; + output_hpos = g->maxh; + return( postword ); +} + + +int html_printer::html_position_region (void) +{ + int r = font::res; + int height = output_style.point_size*r/72; + int temp_vpos; + int is_center = FALSE; + + if (output_style.point_size != 0) { + if (output_vpos != start_region_vpos) { + + // graphic starts on a different line + if (output_vpos == -1) { + temp_vpos = start_region_vpos; + } else { + temp_vpos = output_vpos; + } + +#if 1 + if (need_one_newline) { + html_newline(); + temp_vpos += height; + } else { + need_one_newline = TRUE; + } +#else + html_newline(); + temp_vpos += height; +#endif + + while ((temp_vpos < start_region_vpos) && + (more_than_line_break(temp_vpos, start_region_vpos, height))) { + html_newline(); + temp_vpos += height; + } + } + } + if (auto_on && (is_in_middle(start_region_hpos, end_region_hpos))) { + is_center = TRUE; + } else { + if (start_region_hpos > left_margin_indent) { + html.put_string("<span style=\" text-indent: "); + html.put_float(((double)(start_region_hpos-left_margin_indent)/((double)r))); + html.put_string("in;\"></span>"); + } + } +#if 0 + } else { + // on the same line + if (start_region_hpos > output_hpos) { + html.put_string("<span style=\" text-indent: "); + html.put_float(((double)(start_region_hpos-output_hpos)/((double)r))); + html.put_string("in;\"></span>"); + } + } + } +#endif + output_vpos = start_region_vpos; + output_hpos = start_region_hpos; + return( is_center ); +} + + +/* + * gs_x - translate and scale the x axis + */ + +int html_printer::gs_x (int x) +{ + x += IMAGE_BOARDER_PIXELS/2; + return((x-start_region_hpos)*postscript_res/font::res); +} + + +/* + * gs_y - translate and scale the y axis + */ + +int html_printer::gs_y (int y) +{ + int yoffset=((int)(A4_PAGE_LENGTH*(double)font::res))-end_region_vpos; + + y += IMAGE_BOARDER_PIXELS/2; + return( (y+yoffset)*postscript_res/font::res ); +} + + +void html_printer::troff_position_text (text_glob *g) +{ + change_font(g, FALSE); + + troff.put_string("V"); + troff.put_number(gs_y(g->maxv)); + troff.put_string("\n"); + + troff.put_string("H"); + troff.put_number(gs_x(g->minh)); + troff.put_string("\n"); +} + +void html_printer::troff_change_font (const char *fontname, int size, int font_no) +{ + troff.put_string("x font "); + troff.put_number(font_no); + troff.put_string(" "); + troff.put_string(fontname); + troff.put_string("\nf"); + troff.put_number(font_no); + troff.put_string("\ns"); + troff.put_number(size*1000); + troff.put_string("\n"); +} + + +void html_printer::set_style(const style &sty) +{ +#if 0 + const char *fontname = sty.f->get_name(); + if (fontname == 0) + fatal("no internalname specified for font"); + + change_font(fontname, (font::res/(72*font::sizescale))*sty.point_size); +#endif +} + +void html_printer::end_of_line() +{ + flush_sbuf(); + output_hpos = -1; +} + +void html_printer::html_display_word (text_glob *g) +{ +#if 0 + if (strcmp(g->text_string, "increased.") == 0) { + stop(); + } +#endif + if (! check_able_to_use_table(g)) { + char *postword=html_position_text(g, left_margin_indent, right_margin_indent); + + if (! header.written_header) { + if (g->is_raw_command) { + html.put_string((char *)g->text_string); + } else { + html.html_write_string((char *)g->text_string); + } + if (postword != 0) { + html.put_string(postword); + } + need_one_newline = TRUE; + issued_newline = FALSE; + } + } +} + +void html_printer::troff_display_word (text_glob *g) +{ + troff_position_text(g); + if (g->is_raw_command) { + int l=strlen((char *)g->text_string); + if (l == 1) { + troff.put_string("c"); + troff.put_string((char *)g->text_string); + troff.put_string("\n"); + } else if (l > 1) { + troff.put_string("C"); + troff.put_translated_char((char *)g->text_string); + troff.put_string("\n"); + } + } else { + troff_position_text(g); + troff.put_string("t"); + troff.put_translated_string((const char *)g->text_string); + troff.put_string("\n"); + } +} + +void html_printer::display_word (text_glob *g, int is_to_html) +{ + if (is_to_html) { + html_display_word(g); + } else if ((g->is_raw_command) && (g->is_html_command)) { + // found a raw html command inside a graphic glob. + // We should emit the command to the html device, but of course we + // cannot place it correctly as we are dealing with troff words. + // Remember output_vpos will refer to troff and not html. + html.put_string((char *)g->text_string); + } else { + troff_display_word(g); + } +} + + +/* + * this information may be better placed inside some of the font files + * in devhtml - however one must bare in mind that we need the ability + * to write out to TWO devices (image and html) and image + * invokes ghostscript. + */ + +simple_output &simple_output::html_write_string (const char *s) +{ + int i=0; + + while (s[i] != (char)0) { + if (s[i] == '<') { + put_string("<"); + } else if (s[i] == '>') { + put_string(">"); + } else { + fputc(s[i], fp); + col++; + } + i++; + } + return *this; +} + +/* + * display_fill - generates a troff format fill command + */ + +void html_printer::display_fill (graphic_glob *g) +{ + troff.put_string("Df ") ; + troff.put_number(g->fill); + troff.put_string(" 0\n"); +} + +/* + * display_line - displays a line using troff format + */ + +void html_printer::display_line (graphic_glob *g, int is_to_html) +{ + if (is_to_html) { + fatal("cannot emit lines in html"); + } + if (g->code == 'l') { + // straight line + + troff.put_string("V"); + troff.put_number(gs_y(g->point[0].y)); + troff.put_string("\n"); + + troff.put_string("H"); + troff.put_number(gs_x(g->point[0].x)); + troff.put_string("\n"); + + display_fill(g); + + troff.put_string("Dl "); + troff.put_number((g->point[1].x-g->point[0].x)*postscript_res/font::res); + troff.put_string(" "); + troff.put_number((g->point[1].y-g->point[0].y)*postscript_res/font::res); + troff.put_string("\n"); + // printf("line %c %d %d %d %d size %d\n", (char)g->code, g->point[0].x, g->point[0].y, + // g->point[1].x, g->point[1].y, g->size); + } else if ((g->code == 'c') || (g->code == 'C')) { + // circle + + int xradius = (g->maxh - g->minh) / 2; + int yradius = (g->maxv - g->minv) / 2; + // center of circle or elipse + + troff.put_string("V"); + troff.put_number(gs_y(g->minv+yradius)); + troff.put_string("\n"); + + troff.put_string("H"); + troff.put_number(gs_x(g->minh)); + troff.put_string("\n"); + + display_fill(g); + + if (g->code == 'c') { + troff.put_string("Dc "); + } else { + troff.put_string("DC "); + } + + troff.put_number(xradius*2*postscript_res/font::res); + troff.put_string("\n"); + + } else if ((g->code == 'e') || (g->code == 'E')) { + // ellipse + + int xradius = (g->maxh - g->minh) / 2; + int yradius = (g->maxv - g->minv) / 2; + // center of elipse - this is untested + + troff.put_string("V"); + troff.put_number(gs_y(g->minv+yradius)); + troff.put_string("\n"); + + troff.put_string("H"); + troff.put_number(gs_x(g->minh)); + troff.put_string("\n"); + + display_fill(g); + + if (g->code == 'e') { + troff.put_string("De "); + } else { + troff.put_string("DE "); + } + + troff.put_number(xradius*2*postscript_res/font::res); + troff.put_string(" "); + troff.put_number(yradius*2*postscript_res/font::res); + troff.put_string("\n"); + } else if ((g->code == 'p') || (g->code == 'P')) { + // polygon + troff.put_string("V"); + troff.put_number(gs_y(g->yc)); + troff.put_string("\n"); + + troff.put_string("H"); + troff.put_number(gs_x(g->xc)); + troff.put_string("\n"); + + display_fill(g); + + if (g->code == 'p') { + troff.put_string("Dp"); + } else { + troff.put_string("DP"); + } + + int i; + int xc=g->xc; + int yc=g->yc; + for (i=0; i<g->nopoints; i++) { + troff.put_string(" "); + troff.put_number((g->point[i].x-xc)*postscript_res/font::res); + troff.put_string(" "); + troff.put_number((g->point[i].y-yc)*postscript_res/font::res); + xc = g->point[i].x; + yc = g->point[i].y; + } + troff.put_string("\n"); + } else if (g->code == 'a') { + // arc + troff.put_string("V"); + troff.put_number(gs_y(g->yc)); + troff.put_string("\n"); + + troff.put_string("H"); + troff.put_number(gs_x(g->xc)); + troff.put_string("\n"); + + display_fill(g); + + troff.put_string("Da"); + + int i; + + for (i=0; i<g->nopoints; i++) { + troff.put_string(" "); + troff.put_number(g->point[i].x*postscript_res/font::res); + troff.put_string(" "); + troff.put_number(g->point[i].y*postscript_res/font::res); + } + troff.put_string("\n"); + } else if (g->code == '~') { + // spline + troff.put_string("V"); + troff.put_number(gs_y(g->yc)); + troff.put_string("\n"); + + troff.put_string("H"); + troff.put_number(gs_x(g->xc)); + troff.put_string("\n"); + + display_fill(g); + + troff.put_string("D~"); + + int i; + int xc=g->xc; + int yc=g->yc; + for (i=0; i<g->nopoints; i++) { + troff.put_string(" "); + troff.put_number((g->point[i].x-xc)*postscript_res/font::res); + troff.put_string(" "); + troff.put_number((g->point[i].y-yc)*postscript_res/font::res); + xc = g->point[i].x; + yc = g->point[i].y; + } + troff.put_string("\n"); + } +} + + +void html_printer::flush_sbuf() +{ + if (sbuf_len > 0) { + int r=font::res; // resolution of the device actually + set_style(sbuf_style); + + page_contents->add(&sbuf_style, sbuf, sbuf_len, + sbuf_vpos-sbuf_style.point_size*r/72, sbuf_start_hpos, + sbuf_vpos, sbuf_end_hpos); + + output_hpos = sbuf_end_hpos; + output_vpos = sbuf_vpos; + sbuf_len = 0; + } + +#if 0 + enum { + NONE, + RELATIVE_H, + RELATIVE_V, + RELATIVE_HV, + ABSOLUTE + } motion = NONE; + int space_flag = 0; + if (sbuf_len == 0) + return; + + if (output_style != sbuf_style) { + set_style(sbuf_style); + output_style = sbuf_style; + } + + int extra_space = 0; + if (output_hpos < 0 || output_vpos < 0) + motion = ABSOLUTE; + else { + if (output_hpos != sbuf_start_hpos) + motion = RELATIVE_H; + if (output_vpos != sbuf_vpos) { + if (motion != NONE) + motion = RELATIVE_HV; + else + motion = RELATIVE_V; + } + } + if (sbuf_space_code >= 0) { + int w = sbuf_style.f->get_width(space_char_index, sbuf_style.point_size); + if (w + sbuf_kern != sbuf_space_width) { + if (sbuf_space_code != output_space_code) { + output_space_code = sbuf_space_code; + } + space_flag = 1; + extra_space = sbuf_space_width - w - sbuf_kern; + if (sbuf_space_diff_count > sbuf_space_count/2) + extra_space++; + else if (sbuf_space_diff_count < -(sbuf_space_count/2)) + extra_space--; + } + } + + if (space_flag) + html.put_number(extra_space); + if (sbuf_kern != 0) + html.put_number(sbuf_kern); + + html.put_string(sbuf, sbuf_len); + + char sym[2]; + sym[0] = 'A' + motion*4 + space_flag + 2*(sbuf_kern != 0); + sym[1] = '\0'; + switch (motion) { + case NONE: + break; + case ABSOLUTE: + html.put_number(sbuf_start_hpos) + .put_number(sbuf_vpos); + break; + case RELATIVE_H: + html.put_number(sbuf_start_hpos - output_hpos); + break; + case RELATIVE_V: + html.put_number(sbuf_vpos - output_vpos); + break; + case RELATIVE_HV: + html.put_number(sbuf_start_hpos - output_hpos) + .put_number(sbuf_vpos - output_vpos); + break; + default: + assert(0); + } + + output_hpos = sbuf_end_hpos; + output_vpos = sbuf_vpos; + sbuf_len = 0; +#endif +} + + +void html_printer::set_line_thickness(const environment *env) +{ + line_thickness = env->size; + printf("line thickness = %d\n", line_thickness); +} + +void html_printer::draw(int code, int *p, int np, const environment *env) +{ + switch (code) { + + case 'l': + if (np == 2) { + page_contents->add_line(code, + env->hpos, env->vpos, env->hpos+p[0], env->vpos+p[1], + env->size, fill); + } else { + error("2 arguments required for line"); + } + break; + case 't': + { + if (np == 0) { + line_thickness = -1; + } else { + // troff gratuitously adds an extra 0 + if (np != 1 && np != 2) { + error("0 or 1 argument required for thickness"); + break; + } + line_thickness = p[0]; + } + break; + } + + case 'P': + // fall through + case 'p': + { + if (np & 1) { + error("even number of arguments required for polygon"); + break; + } + if (np == 0) { + error("no arguments for polygon"); + break; + } + // firstly lets add our current position to polygon + int oh=env->hpos; + int ov=env->vpos; + int i=0; + + while (i<np) { + p[i+0] += oh; + p[i+1] += ov; + oh = p[i+0]; + ov = p[i+1]; + i += 2; + } + // now store polygon in page + page_contents->add_polygon(code, np, p, env->hpos, env->vpos, env->size, fill); + } + break; + case 'E': + // fall through + case 'e': + if (np != 2) { + error("2 arguments required for ellipse"); + break; + } + page_contents->add_line(code, + env->hpos, env->vpos-p[1]/2, env->hpos+p[0], env->vpos+p[1]/2, + env->size, fill); + + break; + case 'C': + // fill circle + + case 'c': + { + // troff adds an extra argument to C + if (np != 1 && !(code == 'C' && np == 2)) { + error("1 argument required for circle"); + break; + } + page_contents->add_line(code, + env->hpos, env->vpos-p[0]/2, env->hpos+p[0], env->vpos+p[0]/2, + env->size, fill); + } + break; + case 'a': + { + if (np == 4) { + double c[2]; + + if (adjust_arc_center(p, c)) { + page_contents->add_arc('a', env->hpos, env->vpos, p, c, env->size, fill); + } else { + // a straignt line + page_contents->add_line('l', env->hpos, env->vpos, p[0]+p[2], p[1]+p[3], env->size, fill); + } + } else { + error("4 arguments required for arc"); + } + } + break; + case '~': + { + if (np & 1) { + error("even number of arguments required for spline"); + break; + } + if (np == 0) { + error("no arguments for spline"); + break; + } + // firstly lets add our current position to spline + int oh=env->hpos; + int ov=env->vpos; + int i=0; + + while (i<np) { + p[i+0] += oh; + p[i+1] += ov; + oh = p[i+0]; + ov = p[i+1]; + i += 2; + } + page_contents->add_spline('~', env->hpos, env->vpos, np, p, env->size, fill); + } + break; + case 'f': + { + if (np != 1 && np != 2) { + error("1 argument required for fill"); + break; + } + fill = p[0]; + if (fill < 0 || fill > FILL_MAX) { + // This means fill with the current color. + fill = FILL_MAX + 1; + } + break; + } + + default: + error("unrecognised drawing command `%1'", char(code)); + break; + } +} + + +void html_printer::begin_page(int n) +{ + page_number = n; + html.begin_comment("Page: ").comment_arg(itoa(page_number)).end_comment();; + no_of_printed_pages++; + + output_style.f = 0; + output_space_code = 32; + output_draw_point_size = -1; + output_line_thickness = -1; + output_hpos = -1; + output_vpos = -1; +} + +void testing (text_glob *g) {} + +void html_printer::flush_graphic (void) +{ + graphic_glob g; + + graphic_level = 0; + page_contents->is_in_graphic = FALSE; + + g.minv = -1; + g.maxv = -1; + calculate_region_range(&g); + if (g.minv != -1) { + page_contents->make_new_region(&g); + } + move_region_to_page(); +} + +void html_printer::end_page(int) +{ + flush_sbuf(); + flush_graphic(); + flush_page(); +} + +font *html_printer::make_font(const char *nm) +{ + return html_font::load_html_font(nm); +} + +html_printer::~html_printer() +{ + if (fseek(tempfp, 0L, 0) < 0) + fatal("fseek on temporary file failed"); + html.set_file(stdout); + fputs("<html>\n", stdout); + fputs("<head>\n", stdout); + fputs("<meta name=\"Content-Style\" content=\"text/css\">\n", stdout); + write_title(TRUE); + fputs("</head>\n", stdout); + fputs("<body>\n", stdout); + write_title(FALSE); + header.write_headings(stdout); + { + extern const char *version_string; + html.begin_comment("Creator : ") + .comment_arg("groff ") + .comment_arg("version ") + .comment_arg(version_string) + .end_comment(); + } + { +#ifdef LONG_FOR_TIME_T + long +#else + time_t +#endif + t = time(0); + html.begin_comment("CreationDate: ") + .comment_arg(ctime(&t)) + .end_comment(); + } + for (font_pointer_list *f = font_list; f; f = f->next) { + html_font *psf = (html_font *)(f->p); + } + html.begin_comment("Total number of pages: ").comment_arg(itoa(no_of_printed_pages)).end_comment(); + html.end_line(); + html.copy_file(tempfp); + fputs("</body>\n", stdout); + fputs("</html>\n", stdout); + fclose(tempfp); +} + + +/* + * calculate_region_range - calculates the vertical range for words and lines + * within the region lists. + */ + +void html_printer::calculate_region_range (graphic_glob *r) +{ + text_glob *w; + graphic_glob *g; + + if (! page_contents->region_lines.is_empty()) { + page_contents->region_lines.start_from_head(); + do { + g = page_contents->region_lines.get_data(); + if ((r->minv == -1) || (g->minv < r->minv)) { + r->minv = g->minv; + } + if ((r->maxv == -1) || (g->maxv > r->maxv)) { + r->maxv = g->maxv; + } + page_contents->region_lines.move_right(); + } while (! page_contents->region_lines.is_equal_to_head()); + } + if (! page_contents->region_words.is_empty()) { + page_contents->region_words.start_from_head(); + do { + w = page_contents->region_words.get_data(); + + if ((r->minv == -1) || (w->minv < r->minv)) { + r->minv = w->minv; + } + if ((r->maxv == -1) || (w->maxv > r->maxv)) { + r->maxv = w->maxv; + } + page_contents->region_words.move_right(); + } while (! page_contents->region_words.is_equal_to_head()); + } +} + + +/* + * move_region_to_page - moves lines and words held in the temporary region + * list to the page list. + */ + +void html_printer::move_region_to_page (void) +{ + text_glob *w; + graphic_glob *g; + + page_contents->region_lines.start_from_head(); + while (! page_contents->region_lines.is_empty()) { + g = page_contents->region_lines.get_data(); // remove from our temporary region list + page_contents->lines.add(g); // and add to the page list + page_contents->region_lines.sub_move_right(); + } + page_contents->region_words.start_from_head(); + while (! page_contents->region_words.is_empty()) { + w = page_contents->region_words.get_data(); // remove from our temporary region list + page_contents->words.add(w); // and add to the page list + page_contents->region_words.sub_move_right(); + } +} + + +void html_printer::special(char *s, const environment *env) +{ + if (s != 0) { + if (strcmp(s, "graphic-start") == 0) { + graphic_level++; + if (graphic_level == 1) { + page_contents->is_in_graphic = TRUE; // add words and lines to temporary region lists + } + } else if ((strcmp(s, "graphic-end") == 0) && (graphic_level > 0)) { + graphic_level--; + if (graphic_level == 0) { + flush_graphic(); + } + } else if (strncmp(s, "html:", 5) == 0) { + int r=font::res; // resolution of the device actually + + page_contents->add_html_command(&sbuf_style, &s[5], strlen(s)-5, + + // need to pass rest of string through to html output during flush + + env->vpos-env->size*r/72, env->hpos, + env->vpos , env->hpos); + // assume that the html command has no width, if it does then we hopefully troff + // will have fudged this in a macro and requested that the formatting move right by + // the appropriate width + } else if (strncmp(s, "index:", 6) == 0) { + cutoff_heading = atoi(&s[6]); + } + } +} + +void set_image_type (char *type) +{ + if (strcmp(type, "gif") == 0) { + image_type = gif; + } else if (strcmp(type, "png") == 0) { + image_type = png; + image_device = "png256"; + } else if (strncmp(type, "png", 3) == 0) { + image_type = png; + image_device = type; + } +} + +// A conforming PostScript document must not have lines longer +// than 255 characters (excluding line termination characters). + +static int check_line_lengths(const char *p) +{ + for (;;) { + const char *end = strchr(p, '\n'); + if (end == 0) + end = strchr(p, '\0'); + if (end - p > 255) + return 0; + if (*end == '\0') + break; + p = end + 1; + } + return 1; +} + +printer *make_printer() +{ + return new html_printer; +} + +static void usage(); + +int main(int argc, char **argv) +{ + program_name = argv[0]; + static char stderr_buf[BUFSIZ]; + setbuf(stderr, stderr_buf); + int c; + while ((c = getopt(argc, argv, "F:atvdgmx?I:r:")) != EOF) + switch(c) { + case 'v': + { + extern const char *version_string; + fprintf(stderr, "grohtml version %s\n", version_string); + fflush(stderr); + break; + } + case 'a': + auto_on = FALSE; + break; + case 't': + table_on = FALSE; + break; + case 'F': + font::command_line_font_dir(optarg); + break; + case 'I': + // user specifying the type of images we should generate + set_image_type(optarg); + break; + case 'r': + // resolution (dots per inch for an image) + image_res = atoi(optarg); + break; + case 'd': + // debugging on + debug_on = TRUE; + break; + case 'x': + debug_table_on = TRUE; + break; + case 'g': + // do not guess title and headings + guess_on = FALSE; + break; + case 'm': + // leave margins alone + margin_on = TRUE; + break; + case '?': + usage(); + break; + default: + assert(0); + } + if (optind >= argc) { + do_file("-"); + } else { + for (int i = optind; i < argc; i++) + do_file(argv[i]); + } + delete pr; + return 0; +} + +static void usage() +{ + fprintf(stderr, "usage: %s [-avdgmt?] [-r resolution] [-F dir] [-I imagetype] [files ...]\n", + program_name); + exit(1); +} diff --git a/gnu/usr.bin/groff/grohtml/html.h b/gnu/usr.bin/groff/grohtml/html.h new file mode 100644 index 00000000000..d61a391a1de --- /dev/null +++ b/gnu/usr.bin/groff/grohtml/html.h @@ -0,0 +1,57 @@ +// -*- C++ -*- +/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file is part of groff. + +groff is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +groff is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License along +with groff; see the file COPYING. If not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +class simple_output { +public: + simple_output(FILE *, int max_line_length); + simple_output &put_string(const char *, int); + simple_output &put_string(const char *s); + simple_output &html_write_string(const char *s); + simple_output &put_translated_char (const char *s); + simple_output &put_translated_string(const char *s); + simple_output &put_number(int); + simple_output &put_float(double); + simple_output &put_symbol(const char *); + simple_output &put_literal_symbol(const char *); + simple_output &set_fixed_point(int); + simple_output &simple_comment(const char *); + simple_output &begin_comment(const char *); + simple_output &comment_arg(const char *); + simple_output &end_comment(); + simple_output &set_file(FILE *); + simple_output &include_file(FILE *); + simple_output ©_file(FILE *); + simple_output &end_line(); + simple_output &put_delimiter(char); + simple_output &special(const char *); + FILE *get_file(); +private: + FILE *fp; + int col; + int max_line_length; // not including newline + int need_space; + int fixed_point; +}; + +inline FILE *simple_output::get_file() +{ + return fp; +} + diff --git a/gnu/usr.bin/groff/grohtml/ordered_list.h b/gnu/usr.bin/groff/grohtml/ordered_list.h new file mode 100644 index 00000000000..52fe1c9e605 --- /dev/null +++ b/gnu/usr.bin/groff/grohtml/ordered_list.h @@ -0,0 +1,193 @@ +/* + * Copyright (C) 1999 Free Software Foundation, Inc. + * + * Ordered list, a template module for simple ordered list manipulation. + * + * Gaius Mulley (gaius@glam.ac.uk) + */ + +template <class T> class list_element +{ + public: + list_element *right; + list_element *left; + + list_element (T *in); + T *data; +}; + +template <class T> class ordered_list +{ + private: + list_element<T> *head; + list_element<T> *tail; + list_element<T> *ptr; + public: + ordered_list (void); + ~ ordered_list (void); + void add (T* in); + void sub_move_right (void); + void move_right (void); + void move_left (void); + int is_empty (void); + int is_equal_to_tail (void); + int is_equal_to_head (void); + void start_from_head (void); + void start_from_tail (void); + T *move_right_get_data (void); + T *move_left_get_data (void); + T *get_data (void); +}; + + +template <class T> ordered_list<T>::ordered_list() + : head(0), tail(0), ptr(0) +{ +} + +template <class T> ordered_list<T>::~ordered_list() +{ + list_element<T> *temp=head; + + do { + temp = head; + if (temp != 0) { + head = head->right; + delete temp; + } + } while ((head != 0) && (head != tail)); +} + +template <class T> list_element<T>::list_element(T *in) + : right(0), left(0) +{ + data = in; +} + +template <class T> void ordered_list<T>::add(T *in) +{ + list_element<T> *t = new list_element<T>(in); // create a new list element with data field initialized + list_element<T> *last; + + if (in == 0) { + fatal("cannot add NULL to ordered list"); + } + + if (head == 0) { + head = t; + tail = t; + t->left = t; + t->right = t; + } else { + last = tail; + + while ((last != head) && (in->is_less(in, last->data))) { + last = last->left; + } + + if (in->is_less(in, last->data)) { + t->right = last; + last->left->right = t; + t->left = last->left; + last->left = t; + // now check for a new head + if (last == head) { + head = t; + } + } else { + // add t onto beyond last + t->right = last->right; + t->left = last; + last->right->left = t; + last->right = t; + // now check for a new tail + if (last == tail) { + tail = t; + } + } + } +} + +template <class T> void ordered_list<T>::sub_move_right (void) +{ + list_element<T> *t=ptr->right; + + if (head == tail) { + head = 0; + if (tail != 0) { + delete tail; + } + tail = 0; + ptr = 0; + } else { + if (head == ptr) { + head = head->right; + } + if (tail == ptr) { + tail = tail->left; + } + ptr->left->right = ptr->right; + ptr->right->left = ptr->left; + ptr=t; + } +} + +template <class T> void ordered_list<T>::start_from_head (void) +{ + ptr = head; +} + +template <class T> void ordered_list<T>::start_from_tail (void) +{ + ptr = tail; +} + +template <class T> int ordered_list<T>::is_empty (void) +{ + return( head == 0 ); +} + +template <class T> int ordered_list<T>::is_equal_to_tail (void) +{ + return( ptr == tail ); +} + +template <class T> int ordered_list<T>::is_equal_to_head (void) +{ + return( ptr == head ); +} + +template <class T> void ordered_list<T>::move_left (void) +{ + ptr = ptr->left; +} + +template <class T> void ordered_list<T>::move_right (void) +{ + ptr = ptr->right; +} + +template <class T> T* ordered_list<T>::get_data (void) +{ + return( ptr->data ); +} + +template <class T> T* ordered_list<T>::move_right_get_data (void) +{ + ptr = ptr->right; + if (ptr == head) { + return( 0 ); + } else { + return( ptr->data ); + } +} + +template <class T> T* ordered_list<T>::move_left_get_data (void) +{ + ptr = ptr->left; + if (ptr == tail) { + return( 0 ); + } else { + return( ptr->data ); + } +} diff --git a/gnu/usr.bin/groff/tmac/groff_man.man b/gnu/usr.bin/groff/tmac/groff_man.man new file mode 100644 index 00000000000..57eb9ec4555 --- /dev/null +++ b/gnu/usr.bin/groff/tmac/groff_man.man @@ -0,0 +1,171 @@ +.TH GROFF_MAN @MAN7EXT@ "@MDATE@" "Groff Version @VERSION@" +. +.SH NAME +. +groff_man \- groff `an' macros to support generation of man pages +.SH SYNOPSIS +.B groff +.B \-m@TMAC_AN_PREFIX@an +[ +.IR options .\|.\|. +] +[ +.IR files .\|.\|. +] +. +.SH DESCRIPTION +. +The +.B tmac.an +macros used to generate man pages with +.I groff +were written by James Clark. +This document provides a brief summary of the use of each macro in that +package. +.TP +.BI .TP " title section " [ extra1 "] [" extra2 "] [" extra3 ] +Sets the title of the man page to +.I title +and the section to +.IR section , +which must take on a value between 1 and\ 8. +The value +.I section +may also have a string appended, e.g. `.pm', to indicate a specific +subsection of the man pages. +.TP +.BI .SH " text for a heading" +Sets up an unindented and unnumbered section heading. +Prints out all the text following `.SH' up to the end of the line in bold +face, with a size slightly smaller than that for indented section headings. +.TP +.BI .SS " text for a heading" +Sets up an indented section heading. +Prints out all the text following `.SS' up to the end of the line in bold +face, with a size slightly larger than that for unindented section headings. +.TP +.BI ".TP [" nnn ] +Sets up an indented paragraph. +The indentation is set to +.I nnn +if that argument is supplied. +The first line of text following this macro is interpreted as a string to be +printed flush-left, as it is appropriate for a label. +It is not interpreted as part of a paragraph, so there is no attempt to fill +the first line with text from the following input lines. +Nevertheless, if the label is not as wide as the indentation, then the +paragraph starts at the same line (but indented), continuing on the +following lines. +If the label is wider than the indentation, then the descriptive part of the +paragraph begins on the line following the label, entirely indented. +The `.TP' macro is the macro used for the explanations you are just reading. +.TP +.BR ".LP " or " .PP " or " .P" +These macros are mutual aliases. +Any of them causes a line break at the current position, followed by a +vertical space downwards by the amount that is set in the `PD' counter. +.TP +.BI ".IP [" designator "] [" nnn ] +Sets up an indented paragraph, using +.I designator +as a tag to mark its beginning. +The indentation is permanently set to +.I nnn +if that argument is supplied. +To set the indentation back to the previous level, one must call some other +macro that uses indented paragraphs, and explicitly provide it with the +value of the previous indentation. +.IP +For example, the following paragraphs were all set up with bullets as the +designator, using `.IP \\(bu 4': +.IP \(bu 4 +`IP' is one of the three macros used in +.B tmac.an +to format lists. +.IP \(bu 4 +`HP' is another. +This macro produces a paragraph with a left hanging indentation. +.IP \(bu 4 +`TP' is another. +This macro produces an unindented label (given by the text on the first line +following `TP'), followed by an indented paragraph with appropriately +descriptive text. +.TP +.BI ".HP [" nnn ] +Sets up paragraphs with hanging left indentation. +The indentation is set to +.I nnn +if that argument is supplied. +The following pargraph illustrates the effect of this macro with the hanging +indentation set to\ 2: +.HP 2 +This is a pagraph following an invocation of the `.HP' macro. +As you can see, it produces a paragraph where all lines but the first are +flushed right and are shorter than the preceding lines. +. +.SH "MACROS TO SET FONTS" +. +.TP +.BI .SM +Causes the text on the same line or the text on the next line to appear in a +font that is one point size smaller than the default font. +.TP +.BI .SB +Causes the text on the same line or the text on the next line to appear in +small boldface font. +.TP +.BI ".BI " text +Causes text on the same line to appear alternately in bold face and italic. +The text must be on the same line as the macro call. +Thus `.BI this word and that' would cause `this' and `and' to appear in bold +face, while `word' and `that' appear in italics. +.TP +.BI ".IB " text +Causes text to appear alternately in italic and bold face. +The text must be on the same line as the macro call. +.TP +.BI ".BR " text +Causes text on the same line to appear alternately in bold face and roman. +The text must be on the same line as the macro call. +.TP +.BI ".RB " text +Causes text on the same line to appear alternately in roman and bold face. +The text must be on the same line as the macro call. +.TP +.BI ".R " text +Causes text to appear in roman font. +If no text is present on the line where the macro is called, then the text +of the next line appears in roman. +This is the default font to which text is returned at the end of processing +of the other macros. +.TP +.BI ".B " text +Causes text to appear in bold face. +If no text is present on the line where the macro is called, then the text +of the next line appears in bold face. +.TP +.BI ".I " text +Causes text to appear in italic. +If no text is present on the line where the macro is called, then the text +of the next line appears in italic. +. +.SH "SEE ALSO" +. +Since the +.B tmac.an +macros consist of groups of +.I groff +requests, one can, in principle, supplement the functionality of the +.B tmac.an +macros with individual +.I groff +requests where necessary. +A complete list of these requests is available on the WWW at +.ce 1 +http://www.cs.pdx.edu/~trent/gnu/groff/groff_toc.html +. +.SH AUTHOR +. +This manual page was originally written for the Debian GNU/Linux system by +Susan G. Kleinmann <sgk@debian.org>, corrected by Werner Lemberg +<wl@gnu.org>, and is now part of the GNU troff distribution. diff --git a/gnu/usr.bin/groff/tmac/groff_mdoc.man b/gnu/usr.bin/groff/tmac/groff_mdoc.man new file mode 100644 index 00000000000..2112eba4eba --- /dev/null +++ b/gnu/usr.bin/groff/tmac/groff_mdoc.man @@ -0,0 +1,422 @@ +.\" $NetBSD: mdoc.7,v 1.14 1999/08/30 00:41:28 ross Exp $ +.\" +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)mdoc.7 8.2 (Berkeley) 12/30/93 +.\" +.Dd November 24, 1997 +.Os +.Dt MDOC 7 +.Sh NAME +.Nm mdoc +.Nd quick reference guide for the +.Nm \-mdoc +macro package +.Sh SYNOPSIS +.Nm groff +.Fl m Ns Ar doc +.Ar files ... +.Sh DESCRIPTION +The +.Nm \-mdoc +package is a set of content-based and domain-based macros +used to format the +.Bx +man pages. +The macro names and their meanings are +listed below for quick reference; for +a detailed explanation on using the package, +see the tutorial sampler +.Xr mdoc.samples 7 . +.Pp +The macros are described in two groups, the first +includes the structural and physical page layout macros. +The second contains the manual and general text domain +macros which differentiate the +.Nm -\mdoc +package from other +.Xr troff +formatting packages. +.Sh PAGE STRUCTURE DOMAIN +.Ss Title Macros +To create a valid manual page, these three macros, in this order, +are required: +.Bl -tag -width "xxxx.Os OPERATINGxSYSTEM [version/release]" -compact +.It Li "\&.Dd " Ar "Month day, year" +Document date. +.It Li "\&.Dt " Ar "DOCUMENT_TITLE [section] [volume]" +Title, in upper case. +.It Li "\&.Os " Ar "OPERATING_SYSTEM [version/release]" +Operating system +.Pq Tn BSD . +.El +.Ss Page Layout Macros +Section headers, paragraph breaks, lists and displays. +.Bl -tag -width flag -compact +.It Li \&.Sh +Section Headers. +Valid headers, in the order of presentation: +.Bl -tag -width "RETURN VALUES" -compact +.It Ar NAME +Name section, should include the +.Ql \&.Nm +or +.Ql \&.Fn +and the +.Ql \&.Nd +macros. +.It Ar SYNOPSIS +Usage. +.It Ar DESCRIPTION +General description, should include +options and parameters. +.It Ar RETURN VALUES +Sections two and three function calls. +.It Ar ENVIRONMENT +Describe environment variables. +.It Ar FILES +Files associated with the subject. +.It Ar EXAMPLES +Examples and suggestions. +.It Ar DIAGNOSTICS +Normally used for section four device interface diagnostics. +.It Ar ERRORS +Sections two and three error and signal +handling. +.It Ar SEE ALSO +Cross references and citations. +.It Ar STANDARDS +Conformance to standards if applicable. +.It Ar HISTORY +If a standard is not applicable, the history +of the subject should be given. +.It Ar BUGS +Gotchas and caveats. +.It Ar SECURITY CONSIDERATIONS +Security issues to be aware of. +.It Ar other +Customized headers may be added at +the authors discretion. +.El +.It Li \&.Ss +Subsection Headers. +.It Li \&.Pp +Paragraph Break. +Vertical space (one line). +.It Li \&.D1 +(D-one) Display-one +Indent and display one text line. +.It Li \&.Dl +(D-ell) Display-one literal. +Indent and display one line of literal text. +.It Li \&.Bd +Begin-display block. +Display options: +.Bl -tag -width "xoffset string " -compact +.It Fl ragged +Unjustified (ragged edges). +.It Fl filled +Filled, and if +.Xr troff 1 , +also justified. +.It Fl unfilled +Unfilled, unjustified. +.It Fl literal +Literal text or code. +.It Fl file Ar name +Read in named +.Ar file +and display. +.It Fl offset Ar string +Offset display. +Acceptable +.Ar string +values: +.Bl -tag -width indent-two -compact +.It Ar left +Align block on left (default). +.It Ar center +Approximate center margin. +.It Ar indent +Six constant width spaces (a tab). +.It Ar indent-two +Two tabs. +.It Ar right +Left aligns block 2 inches from +right. +.It Ar xx Ns Cm n +Where +.Ar xx +is a number from +.No \&4 Ns Cm n +to +.No \&9\&9 Ns Cm n . +.It Ar Aa +Where +.Ar Aa +is a callable macro name. +.It Ar string +The width of +.Ar string +is used. +.El +.El +.It Li \&.Ed +End-display (matches \&.Bd). +.It Li \&.Bl +Begin-list. +Create lists or columns. Options: +.Bl -tag -width flag -compact +.It Em List-types +.Bl -column "xbullet " -compact +.It Fl bullet Ta "Bullet Item List" +.It Fl dash Ta "Dash Item List" +.It Fl hyphen Ta "(as per" Fl dash ")" +.It Fl item Ta "Unlabeled List" +.It Fl enum Ta "Enumerated List" +.It Fl tag Ta "Tag Labeled List" +.It Fl diag Ta "Diagnostic List" +.It Fl hang Ta "Hanging Labeled List" +.It Fl ohang Ta "Overhanging Labeled List" +.It Fl inset Ta "Inset or Run-on Labeled List" +.It Fl column Ta "Multiple Columns" +.El +.It Em List-parameters +.Bl -tag -width "xcompact " -compact +.It Fl offset +(All lists.) See +.Ql \&.Bd +begin-display above. +.It Fl width +.Pf ( Fl tag +and +.Fl hang +lists only.) +See +.Ql \&.Bd . +This parameter is effectively required for +.Fl tag +lists. +.It Fl compact +(All lists.) +Suppresses blank lines. +.El +.El +.It Li \&.El +End-list. +.It Li \&.It +List item. +.El +.Sh MANUAL AND GENERAL TEXT DOMAIN MACROS +The manual and general text domain macros are special in that +most of them are parsed for callable macros +for example: +.Bl -tag -width ".Op Fl s Ar filex" -offset indent +.It Li "\&.Op Fl s Ar file" +Produces +.Op Fl s Ar file +.El +.Pp +In this example, the option enclosure macro +.Ql \&.Op +is parsed, and calls the callable content macro +.Ql \&Fl +which operates on the argument +.Ql s +and then calls the callable content macro +.Ql \&Ar +which operates on the argument +.Ql file . +Some macros may be callable, but are not parsed and vice versa. +These macros are indicated in the +.Em parsed +and +.Em callable +columns below. +.Pp +Unless stated, manual domain macros share a common syntax: +.Pp +.Dl \&.Va argument [\ .\ ,\ ;\ :\ (\ )\ [\ ]\ argument \...\ ] +.Pp +.Sy Note : +Opening and closing +punctuation characters are only recognized as such if they are presented +one at a time. +The string +.Ql ")," +is not recognized as punctuation and will be output with a leading white +space and in what ever font the calling macro uses. +The +argument list +.Ql "] ) ," +is recognized as three sequential closing punctuation characters +and a leading white space is not output between the characters +and the previous argument (if any). +The special meaning of a punctuation character may be escaped +with the string +.Ql \e& . +For example the following string, +.Bl -tag -width "&.Ar file1\ , file2\ , file3\ )\ ." -offset indent +.It Li "\&.Ar file1\ , file2\ , file3\ )\ ." +Produces +.Ar file1 , file2 , file3 ) . +.El +.ne 1i +.Ss Manual Domain Macros +.Bl -column "Name" "Parsed" "Callable" -compact +.It Em Name Parsed Callable Description +.It Li \&Ad Ta Yes Ta Yes Ta Address. "(This macro may be deprecated.)" +.It Li \&Ar Ta Yes Ta Yes Ta "Command line argument." +.It Li \&Cd Ta \&No Ta \&No Ta "Configuration declaration (section four only)." +.It Li \&Cm Ta Yes Ta Yes Ta "Command line argument modifier." +.It Li \&Dv Ta Yes Ta Yes Ta "Defined variable (source code)." +.It Li \&Er Ta Yes Ta Yes Ta "Error number (source code)." +.It Li \&Ev Ta Yes Ta Yes Ta "Environment variable." +.It Li \&Fa Ta Yes Ta Yes Ta "Function argument." +.It Li \&Fd Ta \&No Ta \&No Ta "Function declaration." +.It Li \&Fl Ta Yes Ta Yes Ta "Command line flag." +.It Li \&Fn Ta Yes Ta Yes Ta "Function call (also .Fo and .Fc)." +.It Li \&Ic Ta Yes Ta Yes Ta "Interactive command." +.It Li \&Li Ta Yes Ta Yes Ta "Literal text." +.It Li \&Nm Ta Yes Ta Yes Ta "Command name." +.It Li \&Op Ta Yes Ta Yes Ta "Option (also .Oo and .Oc)." +.It Li \&Ot Ta Yes Ta Yes Ta "Old style function type (Fortran only)." +.It Li \&Pa Ta Yes Ta Yes Ta "Pathname or file name." +.It Li \&St Ta Yes Ta Yes Ta "Standards (-p1003.2, -p1003.1 or -ansiC)" +.It Li \&Va Ta Yes Ta Yes Ta "Variable name." +.It Li \&Vt Ta Yes Ta Yes Ta "Variable type (Fortran only)." +.It Li \&Xr Ta Yes Ta Yes Ta "Manual Page Cross Reference." +.El +.Ss General Text Domain Macros +.Bl -column "Name" "Parsed" "Callable" -compact +.It Em "Name Parsed Callable Description" +.It Li \&%A Ta Yes Ta \&No Ta "Reference author." +.It Li \&%B Ta Yes Ta Yes Ta "Reference book title." +.It Li \&%\&C Ta \&No Ta \&No Ta "Reference place of publishing (city)." +.It Li \&%\&D Ta \&No Ta \&No Ta "Reference date." +.It Li \&%J Ta Yes Ta Yes Ta "Reference journal title." +.It Li \&%N Ta \&No Ta \&No Ta "Reference issue number." +.It Li \&%\&O Ta \&No Ta \&No Ta "Reference optional information." +.It Li \&%P Ta \&No Ta \&No Ta "Reference page number(s)." +.It Li \&%R Ta \&No Ta \&No Ta "Reference report Name." +.It Li \&%T Ta Yes Ta Yes Ta "Reference article title." +.It Li \&%V Ta \&No Ta \&No Ta "Reference volume." +.It Li \&Ac Ta Yes Ta Yes Ta "Angle close quote." +.It Li \&Ao Ta Yes Ta Yes Ta "Angle open quote." +.It Li \&Ap Ta Yes Ta Yes Ta "Insert apostrophe; switch to .No mode " +.It Li \&Aq Ta Yes Ta Yes Ta "Angle quote." +.It Li \&At Ta \&No Ta \&No Ta Tn "AT&T UNIX." +.It Li \&Bc Ta Yes Ta Yes Ta "Bracket close quote." +.It Li \&Bf Ta \&No Ta \&No Ta "Begin font mode." +.It Li \&Bo Ta Yes Ta Yes Ta "Bracket open quote." +.It Li \&Bq Ta Yes Ta Yes Ta "Bracket quote." +.It Li \&Bx Ta Yes Ta Yes Ta "BSD" . +.It Li \&Db Ta \&No Ta \&No Ta "Debug (default is \\*qoff\\*q)." +.It Li \&Dc Ta Yes Ta Yes Ta "Double close quote." +.It Li \&Do Ta Yes Ta Yes Ta "Double open quote." +.It Li \&Dq Ta Yes Ta Yes Ta "Double quote." +.It Li \&Ec Ta Yes Ta Yes Ta "Enclose string close quote." +.It Li \&Ef Ta \&No Ta \&No Ta "End font mode." +.It Li \&Em Ta Yes Ta Yes Ta "Emphasis (traditional English)." +.It Li \&Eo Ta Yes Ta Yes Ta "Enclose string open quote." +.It Li \&Fx Ta \&No Ta \&No Ta "FreeBSD." +.It Li \&No Ta Yes Ta Yes Ta "Normal text (no-op)." +.It Li \&Ns Ta Yes Ta Yes Ta "No space." +.It Li \&Nx Ta \&No Ta \&No Ta "NetBSD." +.It Li \&Pc Ta Yes Ta Yes Ta "Parenthesis close quote." +.It Li \&Pf Ta Yes Ta \&No Ta "Prefix string." +.It Li \&Po Ta Yes Ta Yes Ta "Parenthesis open quote." +.It Li \&Pq Ta Yes Ta Yes Ta "Parentheses quote." +.It Li \&Qc Ta Yes Ta Yes Ta "Strait Double close quote." +.It Li \&Ql Ta Yes Ta Yes Ta "Quoted literal." +.It Li \&Qo Ta Yes Ta Yes Ta "Strait Double open quote." +.It Li \&Qq Ta Yes Ta Yes Ta "Strait Double quote." +.It Li \&Re Ta \&No Ta \&No Ta "Reference end." +.It Li \&Rs Ta \&No Ta \&No Ta "Reference start." +.It Li \&Sc Ta Yes Ta Yes Ta "Single close quote." +.It Li \&So Ta Yes Ta Yes Ta "Single open quote." +.It Li \&Sq Ta Yes Ta Yes Ta "Single quote." +.It Li \&Sm Ta \&No Ta \&No Ta "Space mode (default is \\*qon\\*q)." +.It Li \&Sx Ta Yes Ta Yes Ta "Section Cross Reference." +.It Li \&Sy Ta Yes Ta Yes Ta "Symbolic (traditional English)." +.It Li \&Tn Ta Yes Ta Yes Ta "Trade or type name (small Caps)." +.It Li \&Ux Ta Yes Ta Yes Ta "UNIX." +.It Li \&Xc Ta Yes Ta Yes Ta "Extend argument list close." +.It Li \&Xo Ta Yes Ta Yes Ta "Extend argument list open." +.El +.\" .It Sy \&Hf Ta \&No Ta \&No Ta "Include file with header" +.Pp +Macro names ending in +.Ql q +quote remaining items on the argument list. +Macro names ending in +.Ql o +begin a quote which may span more than one line of input and +are close quoted with the matching macro name ending in +.Ql c . +Enclosure macros may be nested and are limited to +eight arguments. +.Pp +Note: the extended argument list macros +.Pf ( Ql \&.Xo , +.Ql \&.Xc ) +and the function enclosure macros +.Pf ( Ql \&.Fo , +.Ql \&.Fc ) +are irregular. +The extended list macros are used when the number of macro arguments +would exceed the +.Xr troff +limitation of nine arguments. +.Sh CONFIGURATION +For site specific configuration of the macro package, +see the file +.Pa /usr/src/share/tmac/README . +.Sh FILES +.Bl -tag -width "tmac.doc-ditroff" -compact +.It Pa tmac.doc +Manual and general text domain macros. +.It Pa tmac.doc-common +Common structural macros and definitions. +.It Pa tmac.doc-nroff +Site dependent +.Xr nroff +style file. +.It Pa tmac.doc-ditroff +Site dependent +.Xr troff +style file. +.It Pa tmac.doc-syms +Special defines (such as the standards macro). +.El +.Sh SEE ALSO +.Xr mdoc.samples 7 diff --git a/gnu/usr.bin/groff/tmac/groff_mdoc.samples.man b/gnu/usr.bin/groff/tmac/groff_mdoc.samples.man new file mode 100644 index 00000000000..cdbbc21c4f6 --- /dev/null +++ b/gnu/usr.bin/groff/tmac/groff_mdoc.samples.man @@ -0,0 +1,2925 @@ +.\" $NetBSD: mdoc.samples.7,v 1.21 1999/08/23 21:54:20 ross Exp $ +.\" +.\" Copyright (c) 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)mdoc.samples.7 8.2 (Berkeley) 12/30/93 +.\" +.\" This tutorial sampler invokes every macro in the package several +.\" times and is guaranteed to give a worst case performance +.\" for an already extremely slow package. +.\" +.Dd November 24, 1997 +.Os +.Dt MDOC.SAMPLES 7 +.Sh NAME +.Nm mdoc.samples +.Nd tutorial sampler for writing +.Bx +manuals with +.Nm \-mdoc +.Sh SYNOPSIS +.Nm man mdoc.samples +.Sh DESCRIPTION +A tutorial sampler for writing +.Bx +manual pages with the +.Nm \-mdoc +macro package, a +.Em content Ns \-based +and +.Em domain Ns \-based +formatting +package for +.Xr troff 1 . +Its predecessor, the +.Xr \-man 7 +package, +addressed page layout leaving the +manipulation of fonts and other +typesetting details to the individual author. +In +.Nm \-mdoc , +page layout macros +make up the +.Em "page structure domain" +which consists of macros for titles, section headers, displays +and lists. Essentially items which affect the physical position +of text on a formatted page. +In addition to the page structure domain, there are two more domains, +the manual domain and the general text domain. +The general text domain is defined as macros which +perform tasks such as quoting or emphasizing pieces of text. +The manual domain is defined as macros that are a subset of the +day to day informal language used to describe commands, routines +and related +.Bx +files. +Macros in the manual domain handle +command names, command line arguments and options, function names, +function parameters, pathnames, variables, cross +references to other manual pages, and so on. +These domain +items have value +for both the author and the future user of the manual page. +It is hoped the consistency gained +across the manual set will provide easier +translation to future documentation tools. +.Pp +Throughout the +.Ux +manual pages, a manual entry +is simply referred +to as a man page, regardless of actual length and without +sexist intention. +.Sh GETTING STARTED +Since a tutorial document is normally read when a person +desires to use the material immediately, the assumption has +been made that the user of this document may be impatient. +The material presented in the remained of this document is +outlined as follows: +.Bl -enum -offset indent +.It +.Tn "TROFF IDIOSYNCRASIES" +.Bl -tag -width flag -compact -offset indent +.It "Macro Usage" . +.It "Passing Space Characters in an Argument" . +.It "Trailing Blank Space Characters (a warning)" . +.It "Escaping Special Characters" . +.El +.It +.Tn "THE ANATOMY OF A MAN PAGE" +.Bl -tag -width flag -compact -offset indent +.It "A manual page template" . +.El +.It +.Tn "INTRODUCTION OF TITLE MACROS" . +.It +.Tn "INTRODUCTION OF MANUAL AND GENERAL TEXT DOMAINS" . +.Bl -tag -width flag -compact -offset indent +.It "What's in a name..." . +.It "General Syntax" . +.El +.It +.Tn "MANUAL DOMAIN" +.Bl -tag -width flag -compact -offset indent +.It "Addresses" . +.It "Arguments" . +.It "Configuration Declarations (section four only)" . +.It "Command Modifier" . +.It "Defined Variables" . +.It "Errno's (Section two only)" . +.It "Environment Variables" . +.It "Function Argument" . +.It "Function Declaration" . +.It "Flags" . +.It "Functions (library routines)" . +.It "Function Types" . +.\" .It "Header File (including source code)" . +.It "Interactive Commands" . +.It "Literals" . +.It "Names" . +.It "Options" . +.It "Pathnames" . +.It "Variables" . +.It "Cross References" . +.El +.It +.Tn "GENERAL TEXT DOMAIN" +.Bl -tag -width flag -compact -offset indent +.It "AT&T Macro" . +.It "BSD Macro" . +.It "UNIX Macro" . +.It "Emphasis Macro" . +.It "Enclosure/Quoting Macros" +.Bl -tag -width flag -compact -offset indent +.It "Angle Bracket Quote/Enclosure" . +.It "Bracket Quotes/Enclosure" . +.It "Double Quote macro/Enclosure" . +.It "Parenthesis Quote/Enclosure" . +.It "Single Quotes/Enclosure" . +.It "Prefix Macro" . +.El +.It "Extended Arguments" . +.It "No\-Op or Normal Text Macro" . +.It "No Space Macro" . +.It "Section Cross References" . +.It "Symbolic Macro" . +.It "References and Citations" . +.It "Trade Names (Acronyms and Type Names)" . +.El +.It +.Tn "PAGE STRUCTURE DOMAIN" +.Bl -tag -width flag -compact -offset indent +.It "Section Headers" . +.It "Paragraphs and Line Spacing" . +.It "Keeps" . +.It "Displays" . +.It "Lists and Columns" . +.El +.It +.Tn "PREDEFINED STRINGS" +.It +.Tn "DIAGNOSTICS" +.It +.Tn "FORMATTING WITH GROFF, TROFF AND NROFF" +.It +.Tn "BUGS" +.El +.ne 7 +.Sh TROFF IDIOSYNCRASIES +The +.Nm \-mdoc +package attempts to simplify the process of writing a man page. +Theoretically, one should not have to learn the dirty details of +.Xr troff 1 +to use +.Nm \-mdoc ; +however, there are a few +limitations which are unavoidable and best gotten out +of the way. +And, too, be forewarned, this package is +.Em not +fast. +.Ss Macro Usage +As in +.Xr troff 1 , +a macro is called by placing a +.Ql \&\. +(dot character) +at the beginning of +a line followed by the two character name for the macro. +Arguments may follow the macro separated by spaces. +It is the dot character at the beginning of the line which causes +.Xr troff 1 +to interpret the next two characters as a macro name. +To place a +.Ql \&\. +(dot character) +at the beginning of a line in some context other than +a macro invocation, precede the +.Ql \&\. +(dot) with the +.Ql \e& +escape sequence. +The +.Ql \e& +translates literally to a zero width space, and is never displayed in the +output. +.Pp +In general, +.Xr troff 1 +macros accept up to nine arguments, any +extra arguments are ignored. +Most macros in +.Nm \-mdoc +accept nine arguments and, +in limited cases, arguments may be continued or extended +on the +next line (See +.Sx Extended Arguments ) . +A few macros handle quoted arguments (see +.Sx Passing Space Characters in an Argument +below). +.Pp +Most of the +.Nm \-mdoc +general text domain and manual domain macros are special +in that their argument lists are +.Em parsed +for callable macro names. +This means an argument on the argument list which matches +a general text or manual domain macro name and is determined +to be callable will be executed +or called when it is processed. +In this case +the argument, although the name of a macro, +is not preceded by a +.Ql \&\. +(dot). +It is in this manner that many macros are nested; for +example +the option macro, +.Ql \&.Op , +may +.Em call +the flag and argument macros, +.Ql \&Fl +and +.Ql \&Ar , +to specify an optional flag with an argument: +.Bl -tag -width "\&.Op \&Fl s \&Ar bytes" -offset indent +.It Op Fl s Ar bytes +is produced by +.Li \&.Op \&Fl s \&Ar bytes +.El +.Pp +To prevent a two character +string from being interpreted as a macro name, precede +the string with the +escape sequence +.Ql \e& : +.Bl -tag -width "\&.Op \&Fl s \&Ar bytes" -offset indent +.It Op \&Fl s \&Ar bytes +is produced by +.Li \&.Op \e&Fl s \e&Ar bytes +.El +.Pp +Here the strings +.Ql \&Fl +and +.Ql \&Ar +are not interpreted as macros. +Macros whose argument lists are parsed for callable arguments +are referred to +as parsed and macros which may be called from an argument +list are referred to as callable +throughout this document and in the companion quick reference +manual +.Xr mdoc 7 . +This is a technical +.Em faux pas +as almost all of the macros in +.Nm \-mdoc +are parsed, but as it was cumbersome to constantly refer to macros +as being callable and being able to call other macros, +the term parsed has been used. +.Ss Passing Space Characters in an Argument +Sometimes it is desirable to give as one argument a string +containing one or more blank space characters. +This may be necessary +to defeat the nine argument limit or to specify arguments to macros +which expect particular arrangement of items in the argument list. +For example, +the function macro +.Ql \&.Fn +expects the first argument to be the name of a function and any +remaining arguments to be function parameters. +As +.Tn "ANSI C" +stipulates the declaration of function parameters in the +parenthesized parameter list, each parameter is guaranteed +to be at minimum a two word string. +For example, +.Fa int foo . +.Pp +There are two possible ways to pass an argument which contains +an embedded space. +.Em Implementation note : +Unfortunately, the most convenient way +of passing spaces in between quotes by reassigning individual +arguments before parsing was fairly expensive speed wise +and space wise to implement in all the macros for +.Tn AT&T +.Xr troff . +It is not expensive for +.Xr groff +but for the sake of portability, has been limited +to the following macros which need +it the most: +.Pp +.Bl -tag -width 4n -offset indent -compact +.It Li \&Cd +Configuration declaration (section 4 +.Sx SYNOPSIS ) +.It Li \&Bl +Begin list (for the width specifier). +.It Li \&Em +Emphasized text. +.It Li \&Fn +Functions (sections two and four). +.It Li \&It +List items. +.It Li \&Li +Literal text. +.It Li \&Sy +Symbolic text. +.It Li \&%B +Book titles. +.It Li \&%J +Journal names. +.It Li \&%O +Optional notes for a reference. +.It Li \&%R +Report title (in a reference). +.It Li \&%T +Title of article in a book or journal. +.El +.Pp +One way of passing a string +containing blank spaces is to use the hard or unpaddable space character +.Ql \e\ , +that is, a blank space preceded by the escape character +.Ql \e . +This method may be used with any macro but has the side effect +of interfering with the adjustment of text +over the length of a line. +.Xr Troff +sees the hard space as if it were any other printable character and +cannot split the string into blank or newline separated pieces as one +would expect. +The method is useful for strings which are not expected +to overlap a line boundary. +For example: +.Bl -tag -width "fetch(char *str)" -offset indent +.It Fn fetch char\ *str +is created by +.Ql \&.Fn fetch char\e *str +.It Fn fetch "char *str" +can also be created by +.Ql \&.Fn fetch "\\*q*char *str\\*q" +.El +.Pp +If the +.Ql \e +or quotes +were omitted, +.Ql \&.Fn +would see three arguments and +the result would be: +.Pp +.Dl Fn fetch char *str +.Pp +For an example of what happens when the parameter list overlaps +a newline boundary, see the +.Sx BUGS +section. +.Ss Trailing Blank Space Characters +.Xr Troff +can be confused by blank space characters at the end of a line. +It +is a wise preventive measure to globally remove all blank spaces +from <blank-space><end-of-line> character sequences. +Should the need +arise to force a blank character at the end of a line, +it may be forced with an unpaddable space and the +.Ql \e& +escape character. +For example, +.Ql string\e\ \e& . +.Ss Escaping Special Characters +Special characters +like the newline character +.Ql \en , +are handled by replacing the +.Ql \e +with +.Ql \ee +(e.g. +.Ql \een ) +to preserve +the backslash. +.Sh THE ANATOMY OF A MAN PAGE +The body of a man page is easily constructed from a basic +template found in the file: +.Bd -literal -offset indent +\&.\e" /usr/share/misc/mdoc.template: +\&.\e" The following six lines are required. +\&.Dd Month day, year +\&.Os OPERATING_SYSTEM [version/release] +\&.Dt DOCUMENT_TITLE [section number] [volume] +\&.Sh NAME +\&.Sh SYNOPSIS +\&.Sh DESCRIPTION +\&.\e" The following requests should be uncommented and +\&.\e" used where appropriate. This next request is +\&.\e" for sections 2 and 3 function return values only. +\&.\e" .Sh RETURN VALUES +\&.\e" This next request is for sections 1, 6, 7 & 8 only +\&.\e" .Sh ENVIRONMENT +\&.\e" .Sh FILES +\&.\e" .Sh EXAMPLES +\&.\e" This next request is for sections 1, 6, 7 & 8 only +\&.\e" (command return values (to shell) and +\&.\e" fprintf/stderr type diagnostics) +\&.\e" .Sh DIAGNOSTICS +\&.\e" The next request is for sections 2 and 3 error +\&.\e" and signal handling only. +\&.\e" .Sh ERRORS +\&.\e" .Sh SEE ALSO +\&.\e" .Sh STANDARDS +\&.\e" .Sh HISTORY +\&.\e" .Sh AUTHORS +\&.\e" .Sh BUGS +.Ed +.Pp +The first items in the template are the macros +.Pq Li \&.Dd , \&.Os , \&.Dt ; +the document date, +the operating system the man page or subject source is developed +or modified for, +and the man page title +.Pq Em in upper case +along with the section of the manual the page +belongs in. +These macros identify the page, +and are discussed below in +.Sx TITLE MACROS . +.Pp +The remaining items in the template are section headers +.Pq Li \&.Sh ; +of which +.Sx NAME , +.Sx SYNOPSIS +and +.Sx DESCRIPTION +are mandatory. +The +headers are +discussed in +.Sx PAGE STRUCTURE DOMAIN , +after +presentation of +.Sx MANUAL DOMAIN . +Several content macros are used to demonstrate page layout macros; +reading about content macros before page layout macros is +recommended. +.Sh TITLE MACROS +The title macros are the first portion of the page structure +domain, but are presented first and separate for someone who +wishes to start writing a man page yesterday. +Three header macros designate the document title or manual page title, +the operating system, +and the date of authorship. +These macros are one called once at the very beginning of the document +and are used to construct the headers and footers only. +.Bl -tag -width 6n +.It Li \&.Dt DOCUMENT_TITLE section# [volume] +The document title is the +subject of the man page and must be in +.Tn CAPITALS +due to troff +limitations. +The section number may be 1,\ ...,\ 9, +and if it is specified, +the volume title may be omitted. +A volume title may be arbitrary or one of the following: +.\" .Cl +.\" USD UNIX User's Supplementary Documents +.\" .Cl +.\" PS1 UNIX Programmer's Supplementary Documents +.Pp +.Bl -column SMM -offset indent -compact +.It Li AMD NetBSD Ancestral Manual Documents +.It Li SMM NetBSD System Manager's Manual +.It Li URM NetBSD Reference Manual +.It Li PRM NetBSD Programmer's Manual +.It Li KM NetBSD Kernel Manual +.El +.Pp +The default volume labeling is +.Li URM +for sections 1, 6, and 7; +.Li SMM +for section 8; +.Li PRM +for sections 2, 3, 4, and 5; +.Li KM +for section 9. +.\" .Cl +.\" MMI UNIX Manual Master Index +.\" .Cl +.\" CON UNIX Contributed Software Manual +.\" .Cl +.\" LOC UNIX Local Manual +.It Li \&.Os operating_system release# +The name of the operating system +should be the common acronym, e.g. +.Tn BSD +or +.Tn ATT . +The release should be the standard release +nomenclature for the system specified, e.g. 4.3, 4.3+Tahoe, V.3, +V.4. +Unrecognized arguments are displayed as given in the page footer. +For instance, a typical footer might be: +.Pp +.Dl \&.Os BSD 4.3 +.Pp +or for a locally produced set +.Pp +.Dl \&.Os CS Department +.Pp +The Berkeley default, +.Ql \&.Os +without an argument, has been defined as +.Nx 1.4 +in the site specific file +.Pa /usr/share/tmac/tmac.doc-common . +Note, if the +.Ql \&.Os +macro is not present, the bottom left corner of the page +will be ugly. +.It Li \&.Dd month day, year +The date should be written formally: +.Pp +.ne 5 +.Dl January 25, 1989 +.sp +Note that the date must not be placed in quotes! +.El +.Sh MANUAL DOMAIN +.Ss What's in a name... +The manual domain macro names are derived from the day to day +informal language used to describe commands, subroutines and related +files. +Slightly +different variations of this language are used to describe +the three different aspects of writing a man page. +First, there is the description of +.Nm \-mdoc +macro request usage. +Second is the description of a +.Ux +command +.Em with +.Nm \-mdoc +macros and third, +the +description of a command to a user in the verbal sense; +that is, discussion of a command in the text of a man page. +.Pp +In the first case, +.Xr troff 1 +macros are themselves a type of command; +the general syntax for a troff command is: +.Bd -filled -offset indent +\&.Va argument1 argument2 ... argument9 +.Ed +.Pp +The +.Ql \&.Va +is a macro command or request, and anything following it is an argument to +be processed. +In the second case, +the description of a +.Ux +command using the content macros is a +bit more involved; +a typical +.Sx SYNOPSIS +command line might be displayed as: +.Bd -filled -offset indent +.Nm filter +.Op Fl flag +.Ar infile outfile +.Ed +.Pp +Here, +.Nm filter +is the command name and the +bracketed string +.Fl flag +is a +.Em flag +argument designated as optional by the option brackets. +In +.Nm \-mdoc +terms, +.Ar infile +and +.Ar outfile +are +called +.Em arguments . +The macros which formatted the above example: +.Bd -literal -offset indent +\&.Nm filter +\&.Op \&Fl flag +\&.Ar infile outfile +.Ed +.Pp +In the third case, discussion of commands and command syntax +includes both examples above, but may add more detail. +The +arguments +.Ar infile +and +.Ar outfile +from the example above might be referred to as +.Em operands +or +.Em file arguments . +Some command line argument lists are quite long: +.Bl -tag -width make -offset indent +.It Nm make +.Op Fl eiknqrstv +.Op Fl D Ar variable +.Op Fl d Ar flags +.Op Fl f Ar makefile +.Bk -words +.Op Fl I Ar directory +.Ek +.Op Fl j Ar max_jobs +.Op Ar variable=value +.Bk -words +.Op Ar target ... +.Ek +.El +.Pp +Here one might talk about the command +.Nm make +and qualify the argument +.Ar makefile , +as an argument to the flag, +.Fl f , +or discuss the optional +file +operand +.Ar target . +In the verbal context, such detail can prevent confusion, +however the +.Nm \-mdoc +package +does not have a macro for an argument +.Em to +a flag. +Instead the +.Ql \&Ar +argument macro is used for an operand or file argument like +.Ar target +as well as an argument to a flag like +.Ar variable . +The make command line was produced from: +.Bd -literal -offset indent +\&.Nm make +\&.Op Fl eiknqrstv +\&.Op Fl D Ar variable +\&.Op Fl d Ar flags +\&.Op Fl f Ar makefile +\&.Op Fl I Ar directory +\&.Op Fl j Ar max_jobs +\&.Op Ar variable=value +\&.Bk -words +\&.Op Ar target ... +\&.Ek +.Ed +.Pp +The +.Ql \&.Bk +and +.Ql \&.Ek +macros are explained in +.Sx Keeps . +.Ss General Syntax +The manual domain and general text domain macros share a similar +syntax with a few minor deviations: +.Ql \&.Ar , +.Ql \&.Fl , +.Ql \&.Nm , +and +.Ql \&.Pa +differ only when called without arguments; +.Ql \&.Fn +and +.Ql \&.Xr +impose an order on their argument lists +and the +.Ql \&.Op +and +.Ql \&.Fn +macros +have nesting limitations. +All content macros +are capable of recognizing and properly handling punctuation, +provided each punctuation character is separated by a leading space. +If an request is given: +.Pp +.Dl \&.Li sptr, ptr), +.Pp +The result is: +.Pp +.Dl Li sptr, ptr), +.Pp +The punctuation is not recognized and all is output in the +literal font. If the punctuation is separated by a leading +white space: +.Pp +.Dl \&.Li "sptr , ptr ) ," +.Pp +The result is: +.Pp +.Dl Li sptr , ptr ) , +.Pp +The punctuation is now recognized and is output in the +default font distinguishing it from the strings in literal font. +.Pp +To remove the special meaning from a punctuation character +escape it with +.Ql \e& . +.Xr Troff +is limited as a macro language, and has difficulty +when presented with a string containing +a member of the mathematical, logical or +quotation set: +.Bd -literal -offset indent-two +\&{+,\-,/,*,\&%,<,>,<=,>=,=,==,&,`,',"} +.Ed +.Pp +The problem is that +.Xr troff +may assume it is supposed to actually perform the operation +or evaluation suggested by the characters. To prevent +the accidental evaluation of these characters, +escape them with +.Ql \e& . +Typical syntax is shown in the first content macro displayed +below, +.Ql \&.Ad . +.Ss Address Macro +The address macro identifies an address construct +of the form addr1[,addr2[,addr3]]. +.Pp +.Dl Usage: .Ad address ... \*(Pu +.Bl -tag -width ".Ad f1 , f2 , f3 :" -compact -offset 14n +.It Li \&.Ad addr1 +.Ad addr1 +.It Li \&.Ad addr1\ . +.Ad addr1 . +.It Li \&.Ad addr1\ , file2 +.Ad addr1 , file2 +.It Li \&.Ad f1\ , f2\ , f3\ : +.Ad f1 , f2 , f3 : +.It Li \&.Ad addr\ )\ )\ , +.Ad addr ) ) , +.El +.Pp +It is an error to call +.Li \&.Ad +without arguments. +.Li \&.Ad +is callable by other macros and is parsed. +.Ss Argument Macro +The +.Li \&.Ar +argument macro may be used whenever +a command line argument is referenced. +.Pp +.Dl Usage: .Ar argument ... \*(Pu +.Bl -tag -width ".Ar file1 file2" -compact -offset 15n +.It Li \&.Ar +.Ar +.It Li \&.Ar file1 +.Ar file1 +.It Li \&.Ar file1\ . +.Ar file1 . +.It Li \&.Ar file1 file2 +.Ar file1 file2 +.It Li \&.Ar f1 f2 f3\ : +.Ar f1 f2 f3 : +.It Li \&.Ar file\ )\ )\ , +.Ar file ) ) , +.El +.Pp +If +.Li \&.Ar +is called without arguments +.Ql Ar +is assumed. +The +.Li \&.Ar +macro is parsed and is callable. +.Ss Configuration Declaration (section four only) +The +.Ql \&.Cd +macro is used to demonstrate a +.Xr config 8 +declaration for a device interface in a section four manual. +This macro accepts quoted arguments (double quotes only). +.Pp +.Bl -tag -width "device le0 at scode?" -offset indent +.It Cd "device le0 at scode?" +produced by: +.Ql ".Cd device le0 at scode?" . +.El +.Ss Command Modifier +The command modifier is identical to the +.Ql \&.Fl +(flag) command with the exception +the +.Ql \&.Cm +macro does not assert a dash +in front of every argument. +Traditionally flags are marked by the +preceding dash, some commands or subsets of commands do not use them. +Command modifiers may also be specified in conjunction with interactive +commands such as editor commands. +See +.Sx Flags . +.Ss Defined Variables +A variable which is defined in an include file is specified +by the macro +.Ql \&.Dv . +.Pp +.Dl Usage: .Dv defined_variable ... \*(Pu +.Bl -tag -width ".Dv MAXHOSTNAMELEN" -compact -offset 14n +.It Li ".Dv MAXHOSTNAMELEN" +.Dv MAXHOSTNAMELEN +.It Li ".Dv TIOCGPGRP )" +.Dv TIOCGPGRP ) +.El +.Pp +It is an error to call +.Ql \&.Dv +without arguments. +.Ql \&.Dv +is parsed and is callable. +.Ss Errno's (Section two only) +The +.Ql \&.Er +errno macro specifies the error return value +for section two library routines. +The second example +below shows +.Ql \&.Er +used with the +.Ql \&.Bq +general text domain macro, as it would be used in +a section two manual page. +.Pp +.Dl Usage: .Er ERRNOTYPE ... \*(Pu +.Bl -tag -width ".Bq Er ENOTDIR" -compact -offset 14n +.It Li \&.Er ENOENT +.Er ENOENT +.It Li \&.Er ENOENT\ )\ ; +.Er ENOENT ) ; +.It Li \&.Bq \&Er ENOTDIR +.Bq Er ENOTDIR +.El +.Pp +It is an error to call +.Ql \&.Er +without arguments. +The +.Ql \&.Er +macro is parsed and is callable. +.Ss Environment Variables +The +.Ql \&.Ev +macro specifies an environment variable. +.Pp +.Dl Usage: .Ev argument ... \*(Pu +.Bl -tag -width ".Ev PRINTER ) ) ," -compact -offset 14n +.It Li \&.Ev DISPLAY +.Ev DISPLAY +.It Li \&.Ev PATH\ . +.Ev PATH . +.It Li \&.Ev PRINTER\ )\ )\ , +.Ev PRINTER ) ) , +.El +.Pp +It is an error to call +.Ql \&.Ev +without arguments. +The +.Ql \&.Ev +macro is parsed and is callable. +.Ss Function Argument +The +.Ql \&.Fa +macro is used to refer to function arguments (parameters) +outside of the +.Sx SYNOPSIS +section of the manual or inside +the +.Sx SYNOPSIS +section should a parameter list be too +long for the +.Ql \&.Fn +macro and the enclosure macros +.Ql \&.Fo +and +.Ql \&.Fc +must be used. +.Ql \&.Fa +may also be used to refer to structure members. +.Pp +.Dl Usage: .Fa function_argument ... \*(Pu +.Bl -tag -width ".Fa d_namlen\ )\ )\ ," -compact -offset 14n +.It Li \&.Fa d_namlen\ )\ )\ , +.Fa d_namlen ) ) , +.It Li \&.Fa iov_len +.Fa iov_len +.El +.Pp +It is an error to call +.Ql \&.Fa +without arguments. +.Ql \&.Fa +is parsed and is callable. +.Ss Function Declaration +The +.Ql \&.Fd +macro is used in the +.Sx SYNOPSIS +section with section two or three +functions. +The +.Ql \&.Fd +macro does not call other macros and is not callable by other +macros. +.Pp +.Dl Usage: .Fd include_file (or defined variable) +.Pp +In the +.Sx SYNOPSIS +section a +.Ql \&.Fd +request causes a line break if a function has already been presented +and a break has not occurred. +This leaves a nice vertical space +in between the previous function call and the declaration for the +next function. +.Ss Flags +The +.Ql \&.Fl +macro handles command line flags. +It prepends +a dash, +.Ql \- , +to the flag. +For interactive command flags, which +are not prepended with a dash, the +.Ql \&.Cm +(command modifier) +macro is identical, but without the dash. +.Pp +.Dl Usage: .Fl argument ... \*(Pu +.Bl -tag -width ".Fl \-s \-t \-v" -compact -offset 14n +.It Li \&.Fl +.Fl +.It Li \&.Fl cfv +.Fl cfv +.It Li \&.Fl cfv\ . +.Fl cfv . +.It Li \&.Fl s v t +.Fl s v t +.It Li \&.Fl -\ , +.Fl - , +.It Li \&.Fl xyz\ )\ , +.Fl xyz ) , +.El +.Pp +The +.Ql \&.Fl +macro without any arguments results +in a dash representing stdin/stdout. +Note that giving +.Ql \&.Fl +a single dash, will result in two dashes. +The +.Ql \&.Fl +macro is parsed and is callable. +.Ss Functions (library routines) +The .Fn macro is modeled on ANSI C conventions. +.Bd -literal +Usage: .Fn [type] function [[type] parameters ... \*(Pu] +.Ed +.Bl -tag -width ".Fn .int align. .const * char *sptrsxx" -compact +.It Li "\&.Fn getchar" +.Fn getchar +.It Li "\&.Fn strlen ) ," +.Fn strlen ) , +.It Li \&.Fn "\\*qint align\\*q" "\\*qconst * char *sptrs\\*q" , +.Fn "int align" "const * char *sptrs" , +.El +.Pp +It is an error to call +.Ql \&.Fn +without any arguments. +The +.Ql \&.Fn +macro +is parsed and is callable, +note that any call to another macro signals the end of +the +.Ql \&.Fn +call (it will close-parenthesis at that point). +.Pp +For functions that have more than eight parameters (and this +is rare), the +macros +.Ql \&.Fo +(function open) +and +.Ql \&.Fc +(function close) +may be used with +.Ql \&.Fa +(function argument) +to get around the limitation. For example: +.Bd -literal -offset indent +\&.Fo "int res_mkquery" +\&.Fa "int op" +\&.Fa "char *dname" +\&.Fa "int class" +\&.Fa "int type" +\&.Fa "char *data" +\&.Fa "int datalen" +\&.Fa "struct rrec *newrr" +\&.Fa "char *buf" +\&.Fa "int buflen" +\&.Fc +.Ed +.Pp +Produces: +.Bd -filled -offset indent +.Fo "int res_mkquery" +.Fa "int op" +.Fa "char *dname" +.Fa "int class" +.Fa "int type" +.Fa "char *data" +.Fa "int datalen" +.Fa "struct rrec *newrr" +.Fa "char *buf" +.Fa "int buflen" +.Fc +.Ed +.Pp +The +.Ql \&.Fo +and +.Ql \&.Fc +macros are parsed and are callable. +In the +.Sx SYNOPSIS +section, the function will always begin at +the beginning of line. +If there is more than one function +presented in the +.Sx SYNOPSIS +section and a function type has not been +given, a line break will occur, leaving a nice vertical space +between the current function name and the one prior. +At the moment, +.Ql \&.Fn +does not check its word boundaries +against troff line lengths and may split across a newline +ungracefully. +This will be fixed in the near future. +.Ss Function Type +This macro is intended for the +.Sx SYNOPSIS +section. +It may be used +anywhere else in the man page without problems, but its main purpose +is to present the function type in kernel normal form for the +.Sx SYNOPSIS +of sections two and three +(it causes a page break allowing the function name to appear +on the next line). +.Pp +.Dl Usage: .Ft type ... \*(Pu +.Bl -tag -width "\&.Ft struct stat" -offset 14n -compact +.It Li \&.Ft struct stat +.Ft struct stat +.El +.Pp +The +.Ql \&.Ft +request is not callable by other macros. +.Ss Interactive Commands +The +.Ql \&.Ic +macro designates an interactive or internal command. +.Pp +.Dl Usage: .Li argument ... \*(Pu +.Bl -tag -width ".Ic setenv , unsetenvxx" -compact -offset 14n +.It Li \&.Ic :wq +.Ic :wq +.It Li \&.Ic do while {...} +.Ic do while {...} +.It Li \&.Ic setenv\ , unsetenv +.Ic setenv , unsetenv +.El +.Pp +It is an error to call +.Ql \&.Ic +without arguments. +The +.Ql \&.Ic +macro is parsed and is callable. +.Ss Literals +The +.Ql \&.Li +literal macro may be used for special characters, +variable constants, anything which should be displayed as it +would be typed. +.Pp +.Dl Usage: .Li argument ... \*(Pu +.Bl -tag -width ".Li cntrl-D ) ," -compact -offset 14n +.It Li \&.Li \een +.Li \en +.It Li \&.Li M1 M2 M3\ ; +.Li M1 M2 M3 ; +.It Li \&.Li cntrl-D\ )\ , +.Li cntrl-D ) , +.It Li \&.Li 1024\ ... +.Li 1024 ... +.El +.Pp +The +.Ql \&.Li +macro is parsed and is callable. +.Ss Name Macro +The +.Ql \&.Nm +macro is used for the document title or subject name. +It has the peculiarity of remembering the first +argument it was called with, which should +always be the subject name of the page. +When called without +arguments, +.Ql \&.Nm +regurgitates this initial name for the sole purpose +of making less work for the author. +If trailing punctuation is required with this feature, +use +.Qq +as a first argument to +.Ql \&.Nm . +Note: +a section two +or three document function name is addressed with the +.Ql \&.Nm +in the +.Sx NAME +section, and with +.Ql \&.Fn +in the +.Sx SYNOPSIS +and remaining sections. +For interactive commands, such as the +.Ql while +command keyword in +.Xr csh 1 , +the +.Ql \&.Ic +macro should be used. +While the +.Ql \&.Ic +is nearly identical +to +.Ql \&.Nm , +it can not recall the first argument it was invoked with. +.Pp +.Dl Usage: .Nm argument ... \*(Pu +.Bl -tag -width ".Nm mdoc.samples" -compact -offset 14n +.It Li \&.Nm mdoc.samples +.Nm mdoc.samples +.It Li \&.Nm \e-mdoc +.Nm \-mdoc +.It Li \&.Nm foo\ )\ )\ , +.Nm foo ) ) , +.It Li \&.Nm +.Nm +.It Li \&.Nm \&"\&"\ : +.Nm "" : +.El +.Pp +The +.Ql \&.Nm +macro is parsed and is callable. +.Ss Options +The +.Ql \&.Op +macro +places option brackets around the any remaining arguments on the command +line, and places any +trailing punctuation outside the brackets. +The macros +.Ql \&.Oc +and +.Ql \&.Oo +may be used across one or more lines. +.Pp +.Dl Usage: .Op options ... \*(Pu +.Bl -tag -width ".Op Fl c Ar objfil Op Ar corfil ," -compact -offset indent +.It Li \&.Op +.Op +.It Li ".Op Fl k" +.Op Fl k +.It Li ".Op Fl k ) ." +.Op Fl k ) . +.It Li ".Op Fl k Ar kookfile" +.Op Fl k Ar kookfile +.It Li ".Op Fl k Ar kookfile ," +.Op Fl k Ar kookfile , +.It Li ".Op Ar objfil Op Ar corfil" +.Op Ar objfil Op Ar corfil +.It Li ".Op Fl c Ar objfil Op Ar corfil ," +.Op Fl c Ar objfil Op Ar corfil , +.It Li \&.Op word1 word2 +.Op word1 word2 +.El +.Pp +The +.Ql \&.Oc +and +.Ql \&.Oo +macros: +.Bd -literal -offset indent +\&.Oo +\&.Op \&Fl k \&Ar kilobytes +\&.Op \&Fl i \&Ar interval +\&.Op \&Fl c \&Ar count +\&.Oc +.Ed +.Pp +Produce: +.Oo +.Op Fl k Ar kilobytes +.Op Fl i Ar interval +.Op Fl c Ar count +.Oc +.Pp +The macros +.Ql \&.Op , +.Ql \&.Oc +and +.Ql \&.Oo +are parsed and are callable. +.Ss Pathnames +The +.Ql \&.Pa +macro formats path or file names. +.Pp +.Dl Usage: .Pa pathname \*(Pu +.Bl -tag -width ".Pa /tmp/fooXXXXX ) ." -compact -offset 14n +.It Li \&.Pa /usr/share +.Pa /usr/share +.It Li \&.Pa /tmp/fooXXXXX\ )\ . +.Pa /tmp/fooXXXXX ) . +.El +.Pp +The +.Ql \&.Pa +macro is parsed and is callable. +.Ss Variables +Generic variable reference: +.Pp +.Dl Usage: .Va variable ... \*(Pu +.Bl -tag -width ".Va char s ] ) ) ," -compact -offset 14n +.It Li \&.Va count +.Va count +.It Li \&.Va settimer , +.Va settimer , +.It Li \&.Va int\ *prt\ )\ : +.Va int\ *prt ) : +.It Li \&.Va char\ s\ ]\ )\ )\ , +.Va char\ s ] ) ) , +.El +.Pp +It is an error to call +.Ql \&.Va +without any arguments. +The +.Ql \&.Va +macro is parsed and is callable. +.Ss Manual Page Cross References +The +.Ql \&.Xr +macro expects the first argument to be +a manual page name, and the second argument, if it exists, +to be either a section page number or punctuation. +Any +remaining arguments are assumed to be punctuation. +.Pp +.Dl Usage: .Xr man_page [1,...,9] \*(Pu +.Bl -tag -width ".Xr mdoc 7 ) ) ," -compact -offset 14n +.It Li \&.Xr mdoc +.Xr mdoc +.It Li \&.Xr mdoc\ , +.Xr mdoc , +.It Li \&.Xr mdoc 7 +.Xr mdoc 7 +.It Li \&.Xr mdoc 7\ )\ )\ , +.Xr mdoc 7 ) ) , +.El +.Pp +The +.Ql \&.Xr +macro is parsed and is callable. +It is an error to call +.Ql \&.Xr +without +any arguments. +.Sh GENERAL TEXT DOMAIN +.Ss AT&T Macro +.Bd -literal -offset indent -compact +Usage: .At [v1 .. v7 | 32v | V.1 | V.4] ... \*(Pu +.Ed +.Bl -tag -width ".At v6 ) ," -compact -offset 14n +.It Li ".At" +.At +.It Li ".At v6 ." +.At v6 . +.El +.Pp +The +.Ql \&.At +macro is +.Em not +parsed and +.Em not +callable. It accepts at most two arguments. +.Ss BSD Macro +.Dl Usage: .Bx [Version/release] ... \*(Pu +.Bl -tag -width ".Bx 4.3 ) ," -compact -offset 14n +.It Li ".Bx" +.Bx +.It Li ".Bx 4.3 ." +.Bx 4.3 . +.El +.Pp +The +.Ql \&.Bx +macro is parsed and is callable. +.Ss NetBSD Macro +.Dl Usage: .Nx [Version/release] ... \*(Pu +.Bl -tag -width ".Nx 1.4 ) ," -compact -offset 14n +.It Li ".Nx" +.Nx +.It Li ".Nx 1.4 ." +.Nx 1.4 . +.El +.Pp +The +.Ql \&.Nx +macro is parsed and is callable. +.Ss FreeBSD Macro +.Dl Usage: .Fx [Version/release] ... \*(Pu +.Bl -tag -width ".Fx 2.2 ) ," -compact -offset 14n +.It Li ".Fx" +.Fx +.It Li ".Fx 2.2 ." +.Fx 2.2 . +.El +.Pp +The +.Ql \&.Fx +macro is parsed and is callable. +.Ss UNIX Macro +.Dl Usage: .Ux ... \*(Pu +.Bl -tag -width ".Ux 4.3 ) ," -compact -offset 14n +.It Li ".Ux" +.Ux +.El +.Pp +The +.Ql \&.Ux +macro is parsed and is callable. +.Ss Emphasis Macro +Text may be stressed or emphasized with the +.Ql \&.Em +macro. +The usual font for emphasis is italic. +.Pp +.Dl Usage: .Em argument ... \*(Pu +.Bl -tag -width ".Em vide infra ) ) ," -compact -offset 14n +.It Li ".Em does not" +.Em does not +.It Li ".Em exceed 1024 ." +.Em exceed 1024 . +.It Li ".Em vide infra ) ) ," +.Em vide infra ) ) , +.El +.\" .Pp +.\" The emphasis can be forced across several lines of text by using +.\" the +.\" .Ql \&.Bf +.\" macro discussed in +.\" .Sx Modes +.\" under +.\" .Sx PAGE STRUCTURE DOMAIN . +.\" .Pp +.\" .Bf -emphasis +.\" We are certain the reason most people desire a Harvard MBA +.\" so they can become to be successful philanthropists. Only +.\" mathematicians and physicists go to graduate school strictly +.\" to acquire infinite wealthy and fame. Its that inifinity +.\" word that does it to them. Ruins them. +.\" .Ef +.Pp +The +.Ql \&.Em +macro is parsed and is callable. +It is an error to call +.Ql \&.Em +without arguments. +.Ss Enclosure and Quoting Macros +The concept of enclosure is similar to quoting. +The object being to enclose one or more strings between +a pair of characters like quotes or parentheses. +The terms quoting and enclosure are used +interchangeably throughout this document. +Most of the +one line enclosure macros end +in small letter +.Ql q +to give a hint of quoting, but there are a few irregularities. +For each enclosure macro +there is also a pair of open and close macros which end +in small letters +.Ql o +and +.Ql c +respectively. +These can be used across one or more lines of text +and while they have nesting limitations, the one line quote macros +can be used inside +of them. +.Pp +.ne 5 +.Bd -filled -offset indent +.Bl -column "quote " "close " "open " "Enclose Stringx(in XX) " XXstringXX +.Em " Quote Close Open Function Result" +\&.Aq .Ac .Ao Angle Bracket Enclosure <string> +\&.Bq .Bc .Bo Bracket Enclosure [string] +\&.Dq .Dc .Do Double Quote ``string'' + .Ec .Eo Enclose String (in XX) XXstringXX +\&.Pq .Pc .Po Parenthesis Enclosure (string) +\&.Ql Quoted Literal `st' or string +\&.Qq .Qc .Qo Straight Double Quote "string" +\&.Sq .Sc .So Single Quote `string' +.El +.Ed +.Pp +Except for the irregular macros noted below, all +of the quoting macros are parsed and callable. +All handle punctuation properly, as long as it +is presented one character at a time and separated by spaces. +The quoting macros examine opening and closing punctuation +to determine whether it comes before or after the +enclosing string. This makes some nesting possible. +.Bl -tag -width xxx,xxxx +.It Li \&.Ec , \&.Eo +These macros expect the first argument to be the +opening and closing strings respectively. +.It Li \&.Ql +The quoted literal macro behaves differently for +.Xr troff +than +.Xr nroff . +If formatted with +.Xr nroff , +a quoted literal is always quoted. If formatted with +troff, an item is only quoted if the width +of the item is less than three constant width characters. +This is to make short strings more visible where the font change +to literal (constant width) is less noticeable. +.It Li \&.Pf +The prefix macro is not callable, but it is parsed: +.Bl -tag -width "(namexx" -offset indent +.It Li ".Pf ( Fa name2" +becomes +.Pf ( Fa name2 . +.El +.It Li \&.Ns +The +.Ql \&.Ns +(no space) macro, which +.Em is +callable, +performs the analogous suffix function. +.It Li ".Ap +The \&.Ap macro inserts an apostrophe and exits any special text modes, +continuing in +.Li \&.No +mode. +.El +.Pp +.ne 4 +Examples of quoting: +.Bl -tag -width ".Aq Pa ctype.h ) ,xxxxxxxx" -compact -offset indent +.It Li \&.Aq +.Aq +.It Li \&.Aq \&Ar ctype.h\ )\ , +.Aq Ar ctype.h ) , +.It Li \&.Bq +.Bq +.It Li \&.Bq \&Em Greek \&, French \&. +.Bq Em Greek , French . +.It Li \&.Dq +.Dq +.It Li ".Dq string abc ." +.Dq string abc . +.It Li ".Dq \'^[A-Z]\'" +.Dq \'^[A-Z]\' +.It Li "\&.Ql man mdoc" +.Ql man mdoc +.It Li \&.Qq +.Qq +.It Li "\&.Qq string ) ," +.Qq string ) , +.It Li "\&.Qq string Ns )," +.Qq string Ns ), +.It Li \&.Sq +.Sq +.It Li "\&.Sq string +.Sq string +.It Li "\&.Em or Ap ing +.Em or Ap ing +.El +.Pp +For a good example of nested enclosure macros, see the +.Ql \&.Op +option macro. +It was created from the same +underlying enclosure macros as those presented in the list +above. +The +.Ql \&.Xo +and +.Ql \&.Xc +extended argument list macros +were also built from the same underlying routines and are a good +example of +.Nm \-mdoc +macro usage at its worst. +.Ss No\-Op or Normal Text Macro +The macro +.Li \&.No +is +a hack for words in a macro command line which should +.Em not +be formatted and follows the conventional syntax +for content macros. +.Ss No Space Macro +The +.Ql \&.Ns +macro eliminates unwanted spaces in between macro requests. +It is useful for old style argument lists where there is no space +between the flag and argument: +.Bl -tag -width ".Op Fl I Ns Ar directoryxx" -offset indent +.It Li ".Op Fl I Ns Ar directory" +produces +.Op Fl I Ns Ar directory +.El +.Pp +Note: the +.Ql \&.Ns +macro always invokes the +.Ql \&.No +macro after eliminating the space unless another macro name +follows it. +The macro +.Ql \&.Ns +is parsed and is callable. +.Ss Section Cross References +The +.Ql \&.Sx +macro designates a reference to a section header +within the same document. +It is parsed and is callable. +.Pp +.Bl -tag -width "Li \&.Sx FILES" -offset 14n +.It Li \&.Sx FILES +.Sx FILES +.El +.Ss Symbolic +The symbolic emphasis macro is generally a boldface macro in +either the symbolic sense or the traditional English usage. +.Pp +.Dl Usage: .Sy symbol ... \*(Pu +.Bl -tag -width ".Sy Important Noticex" -compact -offset 14n +.It Li \&.Sy Important Notice +.Sy Important Notice +.El +.Pp +The +.Ql \&.Sy +macro is parsed and is callable. +Arguments to +.Ql \&.Sy +may be quoted. +.Ss References and Citations +The following macros make a modest attempt to handle references. +At best, the macros make it convenient to manually drop in a subset of +refer style references. +.Pp +.Bl -tag -width 6n -offset indent -compact +.It Li ".Rs" +Reference Start. +Causes a line break and begins collection +of reference information until the +reference end macro is read. +.It Li ".Re" +Reference End. +The reference is printed. +.It Li ".%A" +Reference author name, one name per invocation. +.It Li ".%B" +Book title. +.It Li ".\&%C" +City/place. +.It Li ".\&%D" +Date. +.It Li ".%J" +Journal name. +.It Li ".%N" +Issue number. +.It Li ".%O" +Optional information. +.It Li ".%P" +Page number. +.It Li ".%R" +Report name. +.It Li ".%T" +Title of article. +.It Li ".%V" +Volume(s). +.El +.Pp +The macros beginning with +.Ql % +are not callable, and are parsed only for the trade name macro which +returns to its caller. +(And not very predictably at the moment either.) +The purpose is to allow trade names +to be pretty printed in +.Xr troff Ns / Ns Xr ditroff +output. +.Ss Trade Names (or Acronyms and Type Names) +The trade name macro is generally a small caps macro for +all upper case words longer than two characters. +.Pp +.Dl Usage: .Tn symbol ... \*(Pu +.Bl -tag -width ".Tn ASCII" -compact -offset 14n +.It Li \&.Tn DEC +.Tn DEC +.It Li \&.Tn ASCII +.Tn ASCII +.El +.Pp +The +.Ql \&.Tn +macro +is parsed and is callable by other macros. +.Ss Extended Arguments +The +.Li \&.Xo +and +.Li \&.Xc +macros allow one to extend an argument list +on a macro boundary. +Argument lists cannot +be extended within a macro +which expects all of its arguments on one line such +as +.Ql \&.Op . +.Pp +Here is an example of +.Ql \&.Xo +using the space mode macro to turn spacing off: +.Bd -literal -offset indent +\&.Sm off +\&.It Xo Sy I Ar operation +\&.No \een Ar count No \een +\&.Xc +\&.Sm on +.Ed +.Pp +Produces +.Bd -filled -offset indent +.Bl -tag -width flag -compact +.Sm off +.It Xo Sy I Ar operation +.No \en Ar count No \en +.Xc +.Sm on +.El +.Ed +.Pp +Another one: +.Bd -literal -offset indent +\&.Sm off +\&.It Cm S No \&/ Ar old_pattern Xo +\&.No \&/ Ar new_pattern +\&.No \&/ Op Cm g +\&.Xc +\&.Sm on +.Ed +.Pp +Produces +.Bd -filled -offset indent +.Bl -tag -width flag -compact +.Sm off +.It Cm S No \&/ Ar old_pattern Xo +.No \&/ Ar new_pattern +.No \&/ Op Cm g +.Xc +.Sm on +.El +.Ed +.Pp +Another example of +.Ql \&.Xo +and using enclosure macros: +Test the value of an variable. +.Bd -literal -offset indent +\&.It Xo +\&.Ic .ifndef +\&.Oo \e&! Oc Ns Ar variable +\&.Op Ar operator variable ... +\&.Xc +.Ed +.Pp +Produces +.Bd -filled -offset indent +.Bl -tag -width flag -compact +.It Xo +.Ic .ifndef +.Oo \&! Oc Ns Ar variable +.Op Ar operator variable ... +.Xc +.El +.Ed +.Pp +All of the above examples have used the +.Ql \&.Xo +macro on the argument list of the +.Ql \&.It +(list-item) +macro. +The extend macros are not used very often, and when they are +it is usually to extend the list-item argument list. +Unfortunately, this is also where the extend macros are the +most finicky. +In the first two examples, spacing was turned off; +in the third, spacing was desired in part of the output but +not all of it. +To make these macros work in this situation make sure +the +.Ql \&.Xo +and +.Ql \&.Xc +macros are placed as shown in the third example. +If the +.Ql \&.Xo +macro is not alone on the +.Ql \&.It +argument list, spacing will be unpredictable. +The +.Ql \&.Ns +(no space macro) +must not occur as the first or last macro on a line +in this situation. +Out of 900 manual pages (about 1500 actual pages) +currently released with +.Bx +only fifteen use the +.Ql \&.Xo +macro. +.Sh PAGE STRUCTURE DOMAIN +.Ss Section Headers +The first three +.Ql \&.Sh +section header macros +list below are required in every +man page. +The remaining section headers +are recommended at the discretion of the author +writing the manual page. +The +.Ql \&.Sh +macro can take up to nine arguments. +It is parsed and but is not callable. +.Bl -tag -width ".Sh SYNOPSIS" +.It \&.Sh NAME +The +.Ql \&.Sh NAME +macro is mandatory. +If not specified, +the headers, footers and page layout defaults +will not be set and things will be rather unpleasant. +The +.Sx NAME +section consists of at least three items. +The first is the +.Ql \&.Nm +name macro naming the subject of the man page. +The second is the Name Description macro, +.Ql \&.Nd , +which separates the subject +name from the third item, which is the description. +The +description should be the most terse and lucid possible, +as the space available is small. +.It \&.Sh SYNOPSIS +The +.Sx SYNOPSIS +section describes the typical usage of the +subject of a man page. +The macros required +are either +.Ql ".Nm" , +.Ql ".Cd" , +.Ql ".Fn" , +(and possibly +.Ql ".Fo" , +.Ql ".Fc" , +.Ql ".Fd" , +.Ql ".Ft" +macros). +The function name +macro +.Ql ".Fn" +is required +for manual page sections 2 and 3, the command and general +name macro +.Ql \&.Nm +is required for sections 1, 5, 6, 7, 8. +Section 4 manuals require a +.Ql ".Nm" , ".Fd" +or a +.Ql ".Cd" +configuration device usage macro. +Several other macros may be necessary to produce +the synopsis line as shown below: +.Pp +.Bd -filled -offset indent +.Nm cat +.Op Fl benstuv +.Op Fl +.Ar +.Ed +.Pp +The following macros were used: +.Pp +.Dl \&.Nm cat +.Dl \&.Op \&Fl benstuv +.Dl \&.Op \&Fl +.Dl \&.Ar +.Pp +.Sy Note : +The macros +.Ql \&.Op , +.Ql \&.Fl , +and +.Ql \&.Ar +recognize the pipe bar character +.Ql \*(Ba , +so a command line such as: +.Pp +.Dl ".Op Fl a | Fl b" +.Pp +will not go orbital. +.Xr Troff +normally interprets a \*(Ba as a special operator. +See +.Sx PREDEFINED STRINGS +for a usable \*(Ba +character in other situations. +.It \&.Sh DESCRIPTION +In most cases the first text in the +.Sx DESCRIPTION +section +is a brief paragraph on the command, function or file, +followed by a lexical list of options and respective +explanations. +To create such a list, the +.Ql \&.Bl +begin-list, +.Ql \&.It +list-item and +.Ql \&.El +end-list +macros are used (see +.Sx Lists and Columns +below). +.El +.Pp +The following +.Ql \&.Sh +section headers are part of the +preferred manual page layout and must be used appropriately +to maintain consistency. +They are listed in the order +in which they would be used. +.Bl -tag -width SYNOPSIS +.It \&.Sh ENVIRONMENT +The +.Sx ENVIRONMENT +section should reveal any related +environment +variables and clues to their behavior and/or usage. +.It \&.Sh EXAMPLES +There are several ways to create examples. +See +the +.Sx EXAMPLES +section below +for details. +.It \&.Sh FILES +Files which are used or created by the man page subject +should be listed via the +.Ql \&.Pa +macro in the +.Sx FILES +section. +.It \&.Sh SEE ALSO +References to other material on the man page topic and +cross references to other relevant man pages should +be placed in the +.Sx SEE ALSO +section. +Cross references +are specified using the +.Ql \&.Xr +macro. +At this time +.Xr refer 1 +style references are not accommodated. +.Pp +It is recommended that the cross references are sorted on the section +number, and then alphabetically on the names within a section. +.It \&.Sh STANDARDS +If the command, library function or file adheres to a +specific implementation such as +.St -p1003.2 +or +.St -ansiC +this should be noted here. +If the +command does not adhere to any standard, its history +should be noted in the +.Sx HISTORY +section. +.It \&.Sh HISTORY +Any command which does not adhere to any specific standards +should be outlined historically in this section. +.It \&.Sh AUTHORS +Credits, if need be, should be placed here. +.It \&.Sh DIAGNOSTICS +Diagnostics from a command should be placed in this section. +.It \&.Sh ERRORS +Specific error handling, especially from library functions +(man page sections 2 and 3) should go here. +The +.Ql \&.Er +macro is used to specify an errno. +.It \&.Sh BUGS +Blatant problems with the topic go here... +.El +.Pp +User specified +.Ql \&.Sh +sections may be added, +for example, this section was set with: +.Bd -literal -offset 14n +\&.Sh PAGE LAYOUT MACROS +.Ed +.Ss Paragraphs and Line Spacing. +.Bl -tag -width 6n +.It \&.Pp +The \&.Pp paragraph command may +be used to specify a line space where necessary. +The macro is not necessary after a +.Ql \&.Sh +or +.Ql \&.Ss +macro or before +a +.Ql \&.Bl +macro. +(The +.Ql \&.Bl +macro asserts a vertical distance unless the -compact flag is given). +.El +.\" This worked with version one, need to redo for version three +.\" .Pp +.\" .Ds I +.\" .Cw (ax+bx+c) \ is\ produced\ by\ \& +.\" .\".Cw (ax+bx+c) \&.Va_by_) \&_and_\& \&[?/]m_b1_e1_f1[?/]\& +.\" .Cl Cx \t\t +.\" .Li \&.Cx\ ( +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Va ax +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Sy \+ +.\" .Cx +.\" .Cl Cx \&(\& +.\" .Va ax +.\" .Cx + +.\" .Va by +.\" .Cx + +.\" .Va c ) +.\" .Cx \t +.\" .Em is produced by +.\" .Cx \t +.\" .Li \&.Va by +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Sy \+ +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Va c ) +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Cx +.\" .Cx +.\" .Cw +.\" .De +.\" .Pp +.\" This example shows the same equation in a different format. +.\" The spaces +.\" around the +.\" .Li \&+ +.\" signs were forced with +.\" .Li \e : +.\" .Pp +.\" .Ds I +.\" .Cw (ax\ +\ bx\ +\ c) \ is\ produced\ by\ \& +.\" .\".Cw (ax+bx+c) \&.Va_by_) \&_and_\& \&[?/]m_b1_e1_f1[?/]\& +.\" .Cl Cx \t\t +.\" .Li \&.Cx\ ( +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Va a +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Sy x +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Cx \e\ +\e\ \e& +.\" .Cx +.\" .Cl Cx \&(\& +.\" .Va a +.\" .Sy x +.\" .Cx \ +\ \& +.\" .Va b +.\" .Sy y +.\" .Cx \ +\ \& +.\" .Va c ) +.\" .Cx \t +.\" .Em is produced by +.\" .Cl Cx \t\t +.\" .Li \&.Va b +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Sy y +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Cx \e\ +\e\ \e& +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Va c ) +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Cx +.\" .Cx +.\" .Cw +.\" .De +.\" .Pp +.\" The incantation below was +.\" lifted from the +.\" .Xr adb 1 +.\" manual page: +.\" .Pp +.\" .Ds I +.\" .Cw \&[?/]m_b1_e1_f1[?/]\& is\ produced\ by +.\" .Cl Cx \t\t +.\" .Li \&.Cx Op Sy ?/ +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Nm m +.\" .Cx +.\" .Cl Cx Op Sy ?/ +.\" .Nm m +.\" .Ad \ b1 e1 f1 +.\" .Op Sy ?/ +.\" .Cx \t +.\" .Em is produced by +.\" .Cx \t +.\" .Li \&.Ar \e\ b1 e1 f1 +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Op Sy ?/ +.\" .Cx +.\" .Cl Cx \t\t +.\" .Li \&.Cx +.\" .Cx +.\" .Cw +.\" .De +.\" .Pp +.Ss Keeps +The only keep that is implemented at this time is for words. +The macros are +.Ql \&.Bk +(begin-keep) +and +.Ql \&.Ek +(end-keep). +The only option that +.Ql \&.Bl +accepts is +.Fl words +and is useful for preventing line breaks in the middle of options. +In the example for the make command line arguments (see +.Sx What's in a name ) , +the keep prevented +.Xr nroff +from placing up the +flag and the argument +on separate lines. +(Actually, the option macro used to prevent this from occurring, +but was dropped when the decision (religious) was made to force +right justified margins in +.Xr troff +as options in general look atrocious when spread across a sparse +line. +More work needs to be done with the keep macros, a +.Fl line +option needs to be added.) +.Ss Examples and Displays +There are six types of displays, a quickie one line indented display +.Ql \&.D1 , +a quickie one line literal display +.Ql \&.Dl , +and block literal, block filled, block unfilled, and block ragged which use +the +.Ql \&.Bd +begin-display +and +.Ql \&.Ed +end-display macros. +.Pp +.Bl -tag -width \&.Dlxx +.It Li \&.D1 +(D-one) Display one line of indented text. +This macro is parsed, but it is not callable. +.Pp +.Dl Fl ldghfstru +.Pp +The above was produced by: +.Li \&.Dl Fl ldghfstru . +.It Li \&.Dl +(D-ell) +Display one line of indented +.Em literal +text. +The +.Ql \&.Dl +example macro has been used throughout this +file. +It allows +the indent (display) of one line of text. +Its default font is set to +constant width (literal) however +it is parsed and will recognized other macros. +It is not callable however. +.Pp +.Dl % ls -ldg /usr/local/bin +.Pp +The above was produced by +.Li \&.Dl % ls -ldg /usr/local/bin . +.It Li \&.Bd +Begin-display. +The +.Ql \&.Bd +display must be ended with the +.Ql \&.Ed +macro. +Displays may be nested within lists, but may +.Em not +contain other displays; this also prohibits nesting +of .D1 and .Dl one-line displays. +.Ql \&.Bd +has the following syntax: +.Pp +.Dl ".Bd display-type [-offset offset_value] [-compact]" +.Pp +The display-type must be one of the following four types and +may have an offset specifier for indentation: +.Ql \&.Bd . +.Pp +.Bl -tag -width "file file_name " -compact +.It Fl ragged +Fill, but do not adjust the right margin. +.It Fl unfilled +Do not fill: display a block of text as typed, the +right (and left) margin edges are left ragged. +.It Fl filled +Display a filled (formatted) block. +The block of text is formatted (the edges are filled \- +not left unjustified). +.It Fl literal +Display a literal block, useful for source code or +simple tabbed or spaced text. +.It Fl file Ar file_name +The file name following the +.Fl file +flag is read and displayed. +Literal mode is +asserted and tabs are set at 8 constant width character +intervals, however any +.Xr troff/ Ns Nm \-mdoc +commands in file will be processed. +.It Fl offset Ar string +If +.Fl offset +is specified with one of the following strings, the string +is interpreted to indicate the level of indentation for the +forthcoming block of text: +.Pp +.Bl -tag -width "indent-two" -compact +.It Ar left +Align block on the current left margin, +this is the default mode of +.Ql \&.Bd . +.It Ar center +Supposedly center the block. +At this time +unfortunately, the block merely gets +left aligned about an imaginary center margin. +.It Ar indent +Indents by one default indent value or tab. +The default +indent value is also used for the +.Ql \&.D1 +display so one is guaranteed the two types of displays +will line up. +This indent is normally set to 6n or about two +thirds of an inch (six constant width characters). +.It Ar indent-two +Indents two times the default indent value. +.It Ar right +This +.Em left +aligns the block about two inches from +the right side of the page. +This macro needs +work and perhaps may never do the right thing by +.Xr troff . +.El +.El +.It ".Ed" +End-display. +.El +.Ss Tagged Lists and Columns +There are several types of lists which may be initiated with the +.Ql ".Bl" +begin-list macro. +Items within the list +are specified with the +.Ql ".It" +item macro and +each list must end with the +.Ql ".El" +macro. +Lists other than +.Li \-enum +may be nested within themselves and within displays. +The use of columns inside of lists or lists inside of columns +is unproven. +.Pp +In addition, several list attributes may be specified such as +the width of a tag, the list offset, and compactness +(blank lines between items allowed or disallowed). +Most of this document has been formatted with a tag style list +.Pq Fl tag . +For a change of pace, the list-type used to present the list-types +is an over-hanging list +.Pq Fl ohang . +This type of list is quite popular with +.Tn TeX +users, but might look a bit funny after having read many pages of +tagged lists. +The following list types are accepted by +.Ql ".Bl" : +.Pp +.Bl -ohang -compact +.It Fl bullet +.It Fl dash +.It Fl enum +.It Fl hyphen +.It Fl item +These five are the simplest types of lists. +Once the +.Ql ".Bl" +macro has been given, items in the list are merely +indicated by a line consisting solely of the +.Ql ".It" +macro. +For example, the source text for a simple enumerated list +would look like: +.Bd -literal -offset indent-two +\&.Bl -enum -compact +\&.It +\&Item one goes here. +\&.It +\&And item two here. +\&.It +\&Lastly item three goes here. +\&.El +.Ed +.Pp +The results: +.Pp +.Bl -enum -offset indent-two -compact +.It +Item one goes here. +.It +And item two here. +.It +Lastly item three goes here. +.El +.Pp +A simple bullet list construction: +.Bd -literal -offset indent-two +\&.Bl -bullet -compact +\&.It +\&Bullet one goes here. +\&.It +\&Bullet two here. +\&.El +.Ed +.Pp +Produces: +.Bl -bullet -offset indent-two -compact +.It +Bullet one goes here. +.It +Bullet two here. +.El +.Pp +.It Fl tag +.It Fl diag +.It Fl hang +.It Fl ohang +.It Fl inset +These list-types collect arguments specified with the +.Ql \&.It +macro and create a label which may be +.Em inset +into the forthcoming text, +.Em hanged +from the forthcoming text, +.Em overhanged +from above and not indented or +.Em tagged . +This +list was constructed with the +.Ql Fl ohang +list-type. +The +.Ql \&.It +macro is parsed only for the inset, hang +and tag list-types and is not callable. +Here is an example of inset labels: +.Bl -inset -offset indent +.It Em Tag +The tagged list (also called a tagged paragraph) is the +most common type of list used in the Berkeley manuals. Use a +.Fl width +attribute as described below. +.It Em Diag +Diag lists create section four diagnostic lists +and are similar to inset lists except callable +macros are ignored. +.It Em Hang +Hanged labels are a matter of taste. +.It Em Ohang +Overhanging labels are nice when space is constrained. +.It Em Inset +Inset labels are useful for controlling blocks of +paragraphs and are valuable for converting +.Nm \-mdoc +manuals to other formats. +.El +.Pp +Here is the source text which produced the above example: +.Bd -literal -offset indent +\&.Bl -inset -offset indent +\&.It Em Tag +\&The tagged list (also called a tagged paragraph) is the +\&most common type of list used in the Berkeley manuals. +\&.It Em Diag +\&Diag lists create section four diagnostic lists +\&and are similar to inset lists except callable +\¯os are ignored. +\&.It Em Hang +\&Hanged labels are a matter of taste. +\&.It Em Ohang +\&Overhanging labels are nice when space is constrained. +\&.It Em Inset +\&Inset labels are useful for controlling blocks of +\¶graphs and are valuable for converting +\&.Nm \-mdoc +\&manuals to other formats. +\&.El +.Ed +.Pp +Here is a hanged list with just one item: +.Bl -hang -offset indent +.It Em Hanged +labels appear similar to tagged lists when the +label is smaller than the label width. +.It Em Longer hanged list labels +blend in to the paragraph unlike +tagged paragraph labels. +.El +.Pp +And the unformatted text which created it: +.Bd -literal -offset indent +\&.Bl -hang -offset indent +\&.It Em Hanged +\&labels appear similar to tagged lists when the +\&label is smaller than the label width. +\&.It Em Longer hanged list labels +\&blend in to the paragraph unlike +\&tagged paragraph labels. +\&.El +.Ed +.Pp +The tagged list which follows uses a width specifier to control +the width of the tag. +.Pp +.Bl -tag -width "PAGEIN" -compact -offset indent +.It SL +sleep time of the process (seconds blocked) +.It PAGEIN +number of disk +.Tn I/O Ns 's +resulting from references +by the process to pages not loaded in core. +.It UID +numerical user-id of process owner +.It PPID +numerical id of parent of process process priority +(non-positive when in non-interruptible wait) +.El +.Pp +The raw text: +.Bd -literal -offset indent +\&.Bl -tag -width "PAGEIN" -compact -offset indent +\&.It SL +\&sleep time of the process (seconds blocked) +\&.It PAGEIN +\&number of disk +\&.Tn I/O Ns 's +\&resulting from references +\&by the process to pages not loaded in core. +\&.It UID +\&numerical user-id of process owner +\&.It PPID +\&numerical id of parent of process process priority +\&(non-positive when in non-interruptible wait) +\&.El +.Ed +.Pp +Acceptable width specifiers: +.Bl -tag -width Ar -offset indent +.It Fl width Ar "\&Fl" +sets the width to the default width for a flag. +All callable +macros have a default width value. +The +.Ql \&.Fl , +value is presently +set to ten constant width characters or about five sixth of +an inch. +.It Fl width Ar "24n" +sets the width to 24 constant width characters or about two +inches. +The +.Ql n +is absolutely necessary for the scaling to work correctly. +.It Fl width Ar "ENAMETOOLONG" +sets width to the constant width length of the +string given. +.It Fl width Ar "\\*qint mkfifo\\*q" +again, the width is set to the constant width of the string +given. +.El +.Pp +If a width is not specified for the tag list type, the first +time +.Ql \&.It +is invoked, an attempt is made to determine an appropriate +width. +If the first argument to +.Ql ".It" +is a callable macro, the default width for that macro will be used +as if the macro name had been supplied as the width. +However, +if another item in the list is given with a different callable +macro name, a new and nested list is assumed. This effectively +means that +.Fl width +is required for the tag list type. +.Pp +.It Fl column +This list type generates multiple columns. +The number of columns and the width of each column is determined by +the arguments to the +.Fl column +list. +Each +.Ql ".It" +argument is parsed to make a row, each column within the +row is a separate argument separated by a tab or the +.Ql ".Ta" +macro. +.El +The table: +.Bl -column "String" "Nroff" "Troff" -offset indent +.It Sy "String" Ta Sy "Nroff" Ta Sy "Troff" +.It Li "<=" Ta \&<\&= Ta \*(<= +.It Li ">=" Ta \&>\&= Ta \*(>= +.El +.Pp +was produced by: +.Bd -literal -offset indent +\&.Bl -column "String" "Nroff" "Troff" -offset indent +\&.It Sy "String" Ta Sy "Nroff" Ta Sy "Troff" +\&.It Li "<=" Ta \&<\&= Ta \*(<= +\&.It Li ">=" Ta \&>\&= Ta \*(>= +\&.El +.Ed +.Sh PREDEFINED STRINGS +The following strings are predefined as may be used by +preceding with the troff string interpreting sequence +.Ql \&\e*(xx +where +.Em xx +is the name of the defined string or as +.Ql \&\e*x +where +.Em x +is the name of the string. +The interpreting sequence may be used any where in the text. +.Pp +.Bl -column "String " "Nroff " "Troff " -offset indent +.It Sy "String Nroff Troff" +.It Li "<=" Ta \&<\&= Ta \*(<= +.It Li ">=" Ta \&>\&= Ta \*(>= +.It Li "Rq" Ta "''" Ta \*(Rq +.It Li "Lq" Ta "``" Ta \*(Lq +.It Li "ua" Ta ^ Ta \*(ua +.It Li "aa" Ta ' Ta \*(aa +.It Li "ga" Ta \` Ta \*(ga +.\" .It Li "sL" Ta ` Ta \*(sL +.\" .It Li "sR" Ta ' Ta \*(sR +.It Li "q" Ta \&" Ta \*q +.It Li "Pi" Ta pi Ta \*(Pi +.It Li "Ne" Ta != Ta \*(Ne +.It Li "Le" Ta <= Ta \*(Le +.It Li "Ge" Ta >= Ta \*(Ge +.It Li "Lt" Ta < Ta \*(Gt +.It Li "Gt" Ta > Ta \*(Lt +.It Li "Pm" Ta +- Ta \*(Pm +.It Li "If" Ta infinity Ta \*(If +.It Li "Na" Ta \fINaN\fP Ta \*(Na +.It Li "Ba" Ta \fR\&|\fP Ta \*(Ba +.El +.Pp +.Sy Note : +The string named +.Ql q +should be written as +.Ql \e*q +since it is only one char. +.Sh DIAGNOSTICS +The debugging facilities for +.Nm \-mdoc +are limited, but can help detect subtle errors such +as the collision of an argument name with an internal +register or macro name. +(A what?) +A register is an arithmetic storage class for +.Xr troff +with a one or two character name. +All registers internal to +.Nm \-mdoc +for +.Xr troff +and +.Xr ditroff +are two characters and +of the form <upper_case><lower_case> such as +.Ql \&Ar , +<lower_case><upper_case> as +.Ql \&aR +or +<upper or lower letter><digit> as +.Ql \&C\&1 . +And adding to the muddle, +.Xr troff +has its own internal registers all of which are either +two lower case characters or a dot plus a letter or meta-character +character. +In one of the introduction examples, it was shown how to +prevent the interpretation of a macro name with the escape sequence +.Ql \e& . +This is sufficient for the internal register names also. +.Pp +.\" Every callable macro name has a corresponding register +.\" of the same name (<upper_case><lower_case>). +.\" There are also specific registers which have +.\" been used for stacks and arrays and are listed in the +.\" .Sx Appendix . +.\" .Bd -ragged -offset 4n +.\" [A-Z][a-z] registers corresponding to macro names (example ``Ar'') +.\" [a-z][A-Z] registers corresponding to macro names (example ``aR'') +.\" C[0-9] argument types (example C1) +.\" O[0-9] offset stack (displays) +.\" h[0-9] horizontal spacing stack (lists) +.\" o[0-9] offset (stack) (lists) +.\" t[0-9] tag stack (lists) +.\" v[0-9] vertical spacing stack (lists) +.\" w[0-9] width tag/label stack +.\" .Ed +.\" .Pp +If a non-escaped register name is given in the argument list of a request +unpredictable behavior will occur. +In general, any time huge portions +of text do not appear where expected in the output, or small strings +such as list tags disappear, chances are there is a misunderstanding +about an argument type in the argument list. +Your mother never intended for you to remember this evil stuff - so here +is a way to find out whether or not your arguments are valid: The +.Ql \&.Db +(debug) +macro displays the interpretation of the argument list for most +macros. +Macros such as the +.Ql \&.Pp +(paragraph) +macro do not contain debugging information. +All of the callable macros do, +and it is strongly advised whenever in doubt, +turn on the +.Ql \&.Db +macro. +.Pp +.Dl Usage: \&.Db [on | off] +.Pp +An example of a portion of text with +the debug macro placed above and below an +artificially created problem (a flag argument +.Ql \&aC +which should be +.Ql \e&aC +in order to work): +.Bd -literal -offset indent +\&.Db on +\&.Op Fl aC Ar file ) +\&.Db off +.Ed +.Pp +The resulting output: +.Bd -literal -offset indent +DEBUGGING ON +DEBUG(argv) MACRO: `.Op' Line #: 2 + Argc: 1 Argv: `Fl' Length: 2 + Space: `' Class: Executable + Argc: 2 Argv: `aC' Length: 2 + Space: `' Class: Executable + Argc: 3 Argv: `Ar' Length: 2 + Space: `' Class: Executable + Argc: 4 Argv: `file' Length: 4 + Space: ` ' Class: String + Argc: 5 Argv: `)' Length: 1 + Space: ` ' Class: Closing Punctuation or suffix + MACRO REQUEST: .Op Fl aC Ar file ) +DEBUGGING OFF +.Ed +.Pp +The first line of information tells the name of the calling +macro, here +.Ql \&.Op , +and the line number it appears on. +If one or more files are involved +(especially if text from another file is included) the line number +may be bogus. +If there is only one file, it should be accurate. +The second line gives the argument count, the argument +.Pq Ql \&Fl +and its length. +If the length of an argument is two characters, the +argument is tested to see if it is executable (unfortunately, any +register which contains a non-zero value appears executable). +The third line gives the space allotted for a class, and the +class type. +The problem here is the argument aC should not be +executable. +The four types of classes are string, executable, closing +punctuation and opening punctuation. +The last line shows the entire +argument list as it was read. +In this next example, the offending +.Ql \&aC +is escaped: +.Bd -literal -offset indent +\&.Db on +\&.Em An escaped \e&aC +\&.Db off +.Ed +.Bd -literal -offset indent +DEBUGGING ON +DEBUG(fargv) MACRO: `.Em' Line #: 2 + Argc: 1 Argv: `An' Length: 2 + Space: ` ' Class: String + Argc: 2 Argv: `escaped' Length: 7 + Space: ` ' Class: String + Argc: 3 Argv: `aC' Length: 2 + Space: ` ' Class: String + MACRO REQUEST: .Em An escaped &aC +DEBUGGING OFF +.Ed +.Pp +The argument +.Ql \e&aC +shows up with the same length of 2 as the +.Ql \e& +sequence produces a zero width, but a register +named +.Ql \e&aC +was not found and the type classified as string. +.Pp +Other diagnostics consist of usage statements and are self explanatory. +.Sh GROFF, TROFF AND NROFF +The +.Nm \-mdoc +package does not need compatibility mode with +.Xr groff . +.Pp +The package inhibits page breaks, and the headers and footers +which normally occur at those breaks with +.Xr nroff , +to make the manual more efficient for viewing on-line. +At the moment, +.Xr groff +with +.Fl T Ns Ar ascii +does eject the imaginary remainder of the page at end of file. +The inhibiting of the page breaks makes +.Xr nroff Ns 'd +files unsuitable for hardcopy. +There is a register named +.Ql \&cR +which can be set to zero in the site dependent style file +.Pa /usr/src/share/tmac/doc-nroff +to restore the old style behavior. +.Sh FILES +.Bl -tag -width /usr/share/misc/mdoc.template -compact +.It Pa /usr/share/tmac/tmac.doc +manual macro package +.It Pa /usr/share/misc/mdoc.template +template for writing a man page +.El +.Sh SEE ALSO +.Xr mdoc 7 , +.Xr man 1 , +.Xr troff 1 +.Sh BUGS +Undesirable hyphenation on the dash of a flag +argument is not yet resolved, and causes +occasional mishaps in the +.Sx DESCRIPTION +section. +(line break on the hyphen). +.Pp +Predefined strings are not declared in documentation. +.Pp +Section 3f has not been added to the header routines. +.Pp +.Ql \&.Nm +font should be changed in +.Sx NAME +section. +.Pp +.Ql \&.Fn +needs to have a check to prevent splitting up +if the line length is too short. +Occasionally it +separates the last parenthesis, and sometimes +looks ridiculous if a line is in fill mode. +.Pp +The method used to prevent header and footer page +breaks (other than the initial header and footer) when using +nroff occasionally places an unsightly partially filled line (blank) +at the would be bottom of the page. +.Pp +If the outer-most list definition doesn't have a +.Fl width +argument, the +.Ql ".It" +elements of inner lists may not work (producing a list where +each successive element +.Sq walks +to the right). +.Pp +The list and display macros to not do any keeps +and certainly should be able to. +.\" Note what happens if the parameter list overlaps a newline +.\" boundary. +.\" to make sure a line boundary is crossed: +.\" .Bd -literal +.\" \&.Fn struct\e\ dictionarytable\e\ *dictionarylookup struct\e\ dictionarytable\e\ *tab[] +.\" .Ed +.\" .Pp +.\" produces, nudge nudge, +.\" .Fn struct\ dictionarytable\ *dictionarylookup char\ *h struct\ dictionarytable\ *tab[] , +.\" .Fn struct\ dictionarytable\ *dictionarylookup char\ *h struct\ dictionarytable\ *tab[] , +.\" nudge +.\" .Fn struct\ dictionarytable\ *dictionarylookup char\ *h struct\ dictionarytable\ *tab[] . +.\" .Pp +.\" If double quotes are used, for example: +.\" .Bd -literal +.\" \&.Fn \*qstruct dictionarytable *dictionarylookup\*q \*qchar *h\*q \*qstruct dictionarytable *tab[]\*q +.\" .Ed +.\" .Pp +.\" produces, nudge nudge, +.\" .Fn "struct dictionarytable *dictionarylookup" "char *h" "struct dictionarytable *tab[]" , +.\" nudge +.\" .Fn "struct dictionarytable *dictionarylookup" "char *h" "struct dictionarytable *tab[]" , +.\" nudge +.\" .Fn "struct dictionarytable *dictionarylookup" "char *h" "struct dictionarytable *tab[]" . +.\" .Pp +.\" Not a pretty sight... +.\" In a paragraph, a long parameter containing unpaddable spaces as +.\" in the former example will cause +.\" .Xr troff +.\" to break the line and spread +.\" the remaining words out. +.\" The latter example will adjust nicely to +.\" justified margins, but may break in between an argument and its +.\" declaration. +.\" In +.\" .Xr nroff +.\" the right margin adjustment is normally ragged and the problem is +.\" not as severe. diff --git a/gnu/usr.bin/groff/tmac/groff_me.man b/gnu/usr.bin/groff/tmac/groff_me.man new file mode 100644 index 00000000000..49196212391 --- /dev/null +++ b/gnu/usr.bin/groff/tmac/groff_me.man @@ -0,0 +1,274 @@ +.\" Copyright (c) 1980 The Regents of the University of California. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms are permitted +.\" provided that the above copyright notice and this paragraph are +.\" duplicated in all such forms and that any documentation, +.\" advertising materials, and other materials related to such +.\" distribution and use acknowledge that the software was developed +.\" by the University of California, Berkeley. The name of the +.\" University may not be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" @(#)me.7 6.4 (Berkeley) 4/13/90 +.\" +.\" Modified for groff by jjc@jclark.com +.hc % +.TH GROFF_ME @MAN7EXT@ "@MDATE@" "Groff Version @VERSION@" +.UC 3 +.SH NAME +groff_me \- troff macros for formatting papers +.SH SYNOPSIS +.B "groff \-me" +[ options ] +file ... +.br +.B "troff \-me" +[ options ] +file ... +.SH DESCRIPTION +This manual page describes the GNU version of the \-me macros, +which is part of the groff document formatting system. +This version can be used with both GNU troff and Unix troff. +This package of +.I troff +macro definitions provides a canned formatting +facility for tech%nical papers in various formats. +.PP +The macro requests are defined below. +Many +.I troff +requests are unsafe in conjunction with +this package, however, these requests may be used with +impunity after the first .pp: +.nf +.IP +.ta \w'.sz +n 'u +\&.bp begin new page +\&.br break output line here +\&.sp n insert n spacing lines +\&.ls n (line spacing) n=1 single, n=2 double space +\&.na no alignment of right margin +\&.ce n center next n lines +\&.ul n underline next n lines +.fi +.PP +Output of the +.I pic, +.I eqn, +.I refer, +and +.I tbl +preprocessors +is acceptable as input. +.SH FILES +@MACRODIR@/tmac.e +.SH "SEE ALSO" +.BR groff (@MAN1EXT@), +.BR @g@troff (@MAN1EXT@) +.br +\-me Reference Manual, Eric P. Allman +.br +Writing Papers with Groff Using \-me +.tr &. +.SH REQUESTS +This list is incomplete; +see +.I "The \-me Reference Manual" +for interesting details. +.PP +.ta \w'.eh \'x\'y\'z\' 'u +\w'Initial 'u +\w'Cause 'u +.br +.di x + \ka +.br +.di +.in \nau +.ti 0 +Request Initial Cause Explanation +.ti 0 + Value Break +.br +.in \nau +.ti 0 +\&.(c - yes Begin centered block +.ti 0 +\&.(d - no Begin delayed text +.ti 0 +\&.(f - no Begin footnote +.ti 0 +\&.(l - yes Begin list +.ti 0 +\&.(q - yes Begin major quote +.ti 0 +\&.(x \fIx\fR - no Begin indexed item in index +.I x +.ti 0 +\&.(z - no Begin floating keep +.ti 0 +\&.)c - yes End centered block +.ti 0 +\&.)d - yes End delayed text +.ti 0 +\&.)f - yes End footnote +.ti 0 +\&.)l - yes End list +.ti 0 +\&.)q - yes End major quote +.ti 0 +\&.)x - yes End index item +.ti 0 +\&.)z - yes End floating keep +.ti 0 +\&.++ \fIm H\fR - no Define paper section. +.I m +defines the part of the paper, and can be +.B C +(chapter), +.B A +(appendix), +.B P +(preliminary, e.g., abstract, table of contents, etc.), +.B B +(bibliography), +.B RC +(chapters renumbered from page one each chapter), +or +.B RA +(appendix renumbered from page one). +.ti 0 +\&.+c \fIT\fR - yes Begin chapter (or appendix, etc., as +set by .++). +.I T +is the chapter title. +.ti 0 +\&.1c 1 yes One column format on a new page. +.ti 0 +\&.2c 1 yes Two column format. +.ti 0 +\&.EN - yes Space after equation +produced by +.I eqn +or +.IR neqn . +.ti 0 +\&.EQ \fIx y\fR - yes Precede equation; break out and +add space. +Equation number is +.IR y . +The optional argument \fIx\fR +may be +.I I +to indent equation (default), +.I L +to left-adjust the equation, or +.I C +to center the equation. +.ti 0 +\&.GE - yes End \fIgremlin\fP picture. +.ti 0 +\&.GS - yes Begin \fIgremlin\fP picture. +.ti 0 +\&.PE - yes End \fIpic\fP picture. +.ti 0 +\&.PS - yes Begin \fIpic\fP picture. +.ti 0 +\&.TE - yes End table. +.ti 0 +\&.TH - yes End heading section of table. +.ti 0 +\&.TS \fIx\fR - yes Begin table; if \fIx\fR is +.I H +table has repeated heading. +.ti 0 +\&.b \fIx\fR no no Print +.I x +in boldface; if no argument switch to boldface. +.ti 0 +\&.ba \fI+n\fR 0 yes Augments the base indent by +.I n. +This indent is used to set the indent on regular text +(like paragraphs). +.ti 0 +\&.bc no yes Begin new column +.ti 0 +\&.bi \fIx\fR no no Print +.I x +in bold italics (nofill only) +.ti 0 +\&.bu - yes Begin bulleted paragraph +.ti 0 +\&.bx \fIx\fR no no Print \fIx\fR in a box (nofill only). +.ti 0 +\&.ef \fI\'x\'y\'z\'\fR \'\'\'\' no Set even footer to x y z +.ti 0 +\&.eh \fI\'x\'y\'z\'\fR \'\'\'\' no Set even header to x y z +.ti 0 +\&.fo \fI\'x\'y\'z\'\fR \'\'\'\' no Set footer to x y z +.ti 0 +\&.hx - no Suppress headers and footers on next page. +.ti 0 +\&.he \fI\'x\'y\'z\'\fR \'\'\'\' no Set header to x y z +.ti 0 +\&.hl - yes Draw a horizontal line +.ti 0 +\&.i \fIx\fR no no Italicize +.I x; +if +.I x +missing, italic text follows. +.ti 0 +\&.ip \fIx y\fR no yes Start indented paragraph, +with hanging tag +.IR x . +Indentation is +.I y +ens (default 5). +.ti 0 +\&.lp yes yes Start left-blocked paragraph. +.ti 0 +\&.np 1 yes Start numbered paragraph. +.ti 0 +\&.of \fI\'x\'y\'z\'\fR \'\'\'\' no Set odd footer to x y z +.ti 0 +\&.oh \fI\'x\'y\'z\'\fR \'\'\'\' no Set odd header to x y z +.ti 0 +\&.pd - yes Print delayed text. +.ti 0 +\&.pp no yes Begin paragraph. +First line indented. +.ti 0 +\&.r yes no Roman text follows. +.ti 0 +\&.re - no Reset tabs to default values. +.ti 0 +\&.sh \fIn x\fR - yes Section head follows, +font automatically bold. +.I n +is level of section, +.I x +is title of section. +.ti 0 +\&.sk no no Leave the next page blank. +Only one page is remembered ahead. +.ti 0 +\&.sm \fIx\fR - no Set +.I x +in a smaller pointsize. +.ti 0 +\&.sz \fI+n\fR 10p no Augment the point size by +.I n +points. +.ti 0 +\&.tp no yes Begin title page. +.ti 0 +\&.u \fIx\fR - no Underline argument (even in \fItroff\fR). +(Nofill only). +.ti 0 +\&.uh - yes Like .sh but unnumbered. +.ti 0 +\&.xp \fIx\fR - no Print index +.I x. diff --git a/gnu/usr.bin/groff/tmac/groff_msafer.man b/gnu/usr.bin/groff/tmac/groff_msafer.man new file mode 100644 index 00000000000..0e0de775b63 --- /dev/null +++ b/gnu/usr.bin/groff/tmac/groff_msafer.man @@ -0,0 +1,59 @@ +.ig \"-*- nroff -*- +Copyright (C) 1989-1999 Free Software Foundation, Inc. + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be included in +translations approved by the Free Software Foundation instead of in +the original English. +.. +.TH GROFF_MSAFER @MAN7EXT@ "@MDATE@" "Groff Version @VERSION@" +.SH NAME +groff_msafer \- groff -msafer macros +.SH SYNOPSIS +.B groff +.B \-msafer +[ +.IR options .\|.\|. +] +[ +.IR files .\|.\|. +] +.SH DESCRIPTION +The -msafer macros remove the +.BR open , +.BR opena , +.BR pso , +.BR sy , +and +.B pi +requests. +These macros should be used when processing input from +an untrustworthy source. +For maximum safety, +they should be the first -m option on the command-line. +Normally they are invoked using the +.B \-S +option of groff, which will also pass +.B @g@pic +the +.B \-S +flag. +This is now the default; to get the old behaviour, use the +.B \-U +flag. +.SH FILES +.B @MACRODIR@/tmac.safer +.SH "SEE ALSO" +.BR groff (@MAN1EXT@), +.BR @g@troff (@MAN1EXT@), +.BR @g@pic (@MAN1EXT@) diff --git a/gnu/usr.bin/groff/tmac/tmac.arkup b/gnu/usr.bin/groff/tmac/tmac.arkup new file mode 100644 index 00000000000..b8c94df257a --- /dev/null +++ b/gnu/usr.bin/groff/tmac/tmac.arkup @@ -0,0 +1,178 @@ +.\" +.\" a simple set of macros to provide HTML documents with basic www functionality +.\" +.\" please can someone with more skill at creating macros improve on this +.\" many thanks - Gaius +.\" +.\" suggestion: maybe when run with non -Thtml all the urls should appear as +.\" references. +.\" +.\" some simple html additions to any macro set +.\" +.de HTML +.if '\*(.T'html' \X^html:\\$*^ +.. +.de HTMLINDEX +.if '\*(.T'html' \X^index:\\$*^ +.. +.\" +.\" BODYCOLOR - $1 is foreground color +.\" $2 is background color +.\" $3 is the color of an active hypertext link +.\" $4 is the color of a hypertext link not yet visited +.\" $5 is the color of a visited hypertext link +.\" +.de BODYCOLOR +. HTML <body text=\\$1 bgcolor=\\$2 link=\\$3 alink=\\$4 vlink=\\$5> +.. +.\" +.\" BACKGROUND - $1 is the background image file +.\" +.de BACKGROUND +. HTML <body background=\\$1> +.. +.\" +.\" URL - $1 is the classical underlined blue text +.\" $2 is the url +.\" +.de URL +. ie '\*(.T'html' \{\ +. HTML <a href="\\$2">\\$1</a> +. \} +. el \{\ +\\$1 (<url: \\$2>) +. \} +.. +.\" +.\" LINK - $1 is the classical underlined blue text +.\" $2 is the URL *with* the textual reference within a document +.\" +.\" example: .LINK "a nice heading" "#heading123" +.\" +.\" provides a link from "a nice heading" to the +.\" textual name reference "heading123" +.\" +.\" .LINK "The GNU FSF" "" "www.gnu.org" +.\" +.\" deprecated - use the URL macro instead +.\" +.\" +.de LINK +. ie !'\\$3'' \{\ +. @error the LINK macro has changed, use the URL (or FTP if appropriate) macro here +. @error you are advised to replace with URL or FTP macro "\\$1" "\\$3#\\$2" +. URL "\\$1" "\\$3#\\$2" +. \} +. el \{\ +. ie '\*(.T'html' \{\ +. HTML <a href=\\$2>\\$1</a> +. \} +. el \{\ +. URL "\\$1" "\\$2" +. \} +. \} +.. +.\" +.\" FTP - $1 is the classical underlined blue text +.\" $2 is the ftp url +.de FTP +. ie '\*(.T'html' \{\ +. HTML <a href=\\$2>\\$1</a> +. \} +. el \{\ +$1 (<ftp:\\$2>) +. \} +.. +.\" +.\" MAILTO - generate html email reference +.\" $1 is the email address +.\" $2 is the optional name +.\" +.\" example .MAILTO fred@foo.bar "Fredrick Bloggs" +.\" +.de MAILTO +.\" +.\" force reset after a potential heading by performing some motion.. +.\" how do we do this --fixme-- +.\" \h'\w' ''\h'-\w' '' doesn't work.. +. ie '\*(.T'html' \{\ +. ie '\\$2'' \{\ +. HTML "<a href=mailto:\\$1>\\$1</a>" +. \} +. el \{\ +. HTML "<a href=mailto:\\$1>\\$2</a>" +. \} +. \} +. el \{\ +\s-2\fB<email:\\$1>\fP\s+2 +. \} +.. +.\" +.\" +.\" TAG - generate an html name $1 +.\" +.de TAG +.HTML <a name="\\$1"></a> +.. +.\" +.\" IMAGE - reference an image +.\" $1 is the image file +.\" $2 is the x width (default if absent 400 pixels) +.\" $3 is the y width (default if absent is the x value) +.\" +.de IMAGE +. ie '\*(.T'html' \{\ +. nr HTMLWIDTH 400 +. if '\\$2'' \{\ +. nr HTMLWIDTH \\$2 +. \} +. nr HTMLHEIGHT \\n[HTMLWIDTH] +. if '\\$3'' \{\ +. nr HTMLHEIGHT \\$3 +. \} +. HTML <img src="\\$1" width=\\n[HTMLWIDTH height=\\n[HTMLHEIGHT]> +. \} +. el \{\ +. B1 +\fB\s-2<img src=\\$1>\fP\s+2 +. B2 +. \} +.. +.\" +.\" CDFTP - if we are processing this on machine \\$1 then we create a +.\" FTP reference using \\$2 --> \\$3 +.\" +.\" otherwise we create a URL from \\$2 --> \\$4 +.\" +.\" example: +.\" +.\" .CDFTP "foobar" "somegnusoftware.tar.gz" \ +.\" "ftp://ftp.gnu.org/gnu/somegnusoftware.tar.gz" \ +.\" "../../../TARGZ/somegnusoftware.tar.gz" +.\" +.\" meaning if we are on machine foobar then generate an ftp url +.\" to the GNU anonymous ftp server otherwise generate a file url +.\" to a local copy (cdrom maybe) +.\" +.\" Useful when one machine is designated as a cdrom burner and another +.\" designated as an appache server. +.\" The same source for web pages can be burnt onto a CD and also +.\" served across the network. It doesn't solve the problem of one +.\" machine doing both though :-( +.\" +.\" +.de CDFTP +. sy /bin/rm -f /tmp/tmac.n +. sy /bin/echo ".ds HOSTNAME `hostname --short`" > /tmp/tmac.n +. so /tmp/tmac.n +. sy /bin/rm -f /tmp/tmac.n +. ie '\\*[HOSTNAME]'\\$1' \{\ +. FTP "\\$2" "\\$3" +. \} +. el \{\ +. URL "\\$2" "\\$4" +. \} +.. +.\" it doesn't make sense to use hyphenation with html, so we turn it off. +.hy 0 +.nr HY 0 diff --git a/gnu/usr.bin/groff/tmac/tmac.html b/gnu/usr.bin/groff/tmac/tmac.html new file mode 100644 index 00000000000..cd8a518a7f2 --- /dev/null +++ b/gnu/usr.bin/groff/tmac/tmac.html @@ -0,0 +1,58 @@ +.nr _C \n(.C +.cp 0 +.ftr CW CR +.ftr C CR +.ftr CO CI +.ftr CX CBI +.ftr H HR +.ftr HO HI +.ftr HX HBI +.ftr NX NBI +.char \(ru \D'l .5m 0' +.char \(ul \v'.25m'\D'l .5m 0'\v'-.25m' +.char \(br \v'.25m'\D'l 0 -1m'\v'.75m' +.char \(rn \v'-.75m'\D'l .5m 0'\v'.75m' +.char ~ \v'-.55m'\\s[\\n(.s/2u]\v'.2m'\(ti\v'-.2m'\s0\v'.55m' +.char ^ \v'-.55m'\\s[\\n(.s/2u]\v'.3m'\(ha\v'-.3m'\s0\v'.55m' +.if !c\(va .char \(va \o'\(ua\(da' +.if !c\(em .char \(em -- +.if !c\(en .char \(en \- +.if !c\(fi .char \(fi fi +.if !c\(fl .char \(fl fl +.if !c\(ff .char \(ff ff +.if !c\(Fi .char \(Fi ffi +.if !c\(Fl .char \(Fl ffl +.if !c\(ci .char \(ci \v'-.25m'\h'.05m'\D'c .5m'\h'.05m'\v'.25m' +.if !c\(sq .char \(sq \h'.05m'\D'l .5m 0'\D'l 0 -.5m'\D'l -.5m 0'\D'l 0 .5m'\h'.55m' +.if !c\(ga .char \(ga \Z'\v'-.7m'\D'l .22m .18m''\h'.33m' +.if !c\(dg .char \(dg \Z'\h'.25m'\v'.15m'\D'l 0 -.8m'\v'.2m'\h'-.195m'\ +\D'l .39m 0''\h'.5m' +.if !c\(dd .char \(dd \Z'\h'.25m'\v'.15m'\D'l 0 -.8m'\v'.2m'\h'-.195m'\ +\D'l .39m 0'\v'.4m'\D'l -.39m 0''\h'.5m' +.if !c\(lq .char \(lq `` +.if !c\(rq .char \(rq '' +.if !c\(Bq .char \(bq ,, +.if !c\(OE .char \(OE O\h'-.25m'E +.if !c\(oe .char \(oe o\h'-.14m'e +.if !c\(ah .char \(ah \v'-.55m'\s[\En[.s]/2u]v\s0\v'.55m' +.if !c\(ao .char \(ao \v'-.55m'\s[\En[.s]*6u/10u]\D'c .25m'\s0\v'.55m' +.if !c\(ho .char \(ho \s[\En[.s]/2u]\v'.4m'c\v'-.4m'\s0 +.if !c\(lh .char \(lh <- +.if !c\(rh .char \(rh -> +.if !c\(bq .tr \(bq, +.if !c\(aq .tr \(aq' +.if '\*(.T'html' .char \[radicalex] \h'-\w'\(sr'u'\[radicalex]\h'\w'\(sr'u' +.if !\n(_C .mso tmac.pspic +.cp \n(_C +.\" now turn off all headers and footers for ms, me and mm macro sets +.if d EF .EF ''' +.if d EH .EH ''' +.if d OF .OF ''' +.if d OH .OH ''' +.if d ef .ef ''' +.if d of .of ''' +.if d oh .oh ''' +.if d eh .eh ''' +.\" it doesn't make sense to use hyphenation with html, so we turn it off. +.hy 0 +.nr HY 0 diff --git a/gnu/usr.bin/groff/xditview/GXditview-ad.h b/gnu/usr.bin/groff/xditview/GXditview-ad.h new file mode 100644 index 00000000000..d9be3da256b --- /dev/null +++ b/gnu/usr.bin/groff/xditview/GXditview-ad.h @@ -0,0 +1,52 @@ +"GXditview.height: 840", +"GXditview.paned.allowResize: true", +"GXditview.paned.viewport.allowVert: true", +"GXditview.paned.viewport.allowHoriz: true", +"GXditview.paned.viewport.skipAdjust: false", +"GXditview.paned.viewport.width: 600", +"GXditview.paned.viewport.height: 800", +"GXditview.paned.viewport.showGrip: false", +"GXditview.paned.label.skipAdjust: true", +"GXditview.paned.viewport.dvi.translations: #augment \ + <Btn1Down>: XawPositionSimpleMenu(menu) MenuPopup(menu)\\n\ + <Key>Next: NextPage()\\n\ + <Key>n: NextPage()\\n\ + <Key>space: NextPage()\\n\ + <Key>Return: NextPage()\\n\ + <Key>Prior: PreviousPage()\\n\ + <Key>p: PreviousPage()\\n\ + <Key>BackSpace: PreviousPage()\\n\ + <Key>Delete: PreviousPage()\\n\ + <Key>Select: SelectPage()\\n\ + <Key>Find: OpenFile()\\n\ + <Key>r: Rerasterize()\\n\ + <Key>q: Quit()", +"GXditview.paned.label.translations: #augment \ + <Btn1Down>: XawPositionSimpleMenu(menu) MenuPopup(menu)\\n\ + <Key>Next: NextPage()\\n\ + <Key>n: NextPage()\\n\ + <Key>space: NextPage()\\n\ + <Key>Return: NextPage()\\n\ + <Key>Prior: PreviousPage()\\n\ + <Key>p: PreviousPage()\\n\ + <Key>BackSpace: PreviousPage()\\n\ + <Key>Delete: PreviousPage()\\n\ + <Key>Select: SelectPage()\\n\ + <Key>Find: OpenFile()\\n\ + <Key>r: Rerasterize()\\n\ + <Key>q: Quit()", +"GXditview.menu.nextPage.label: Next Page", +"GXditview.menu.previousPage.label: Previous Page", +"GXditview.menu.selectPage.label: Select Page", +"GXditview.menu.print.label: Print", +"GXditview.menu.openFile.label: Open", +"GXditview.menu.quit.label: Quit", +"GXditview.promptShell.allowShellResize: true", +"GXditview.promptShell.promptDialog.value.translations: #override \ + <Key>Return: Accept()", +"GXditview.promptShell.promptDialog.accept.label: Accept", +"GXditview.promptShell.promptDialog.accept.translations: #override \ + <BtnUp>: Accept() unset()", +"GXditview.promptShell.promptDialog.cancel.label: Cancel", +"GXditview.promptShell.promptDialog.cancel.translations: #override \ + <BtnUp>: Cancel() unset()", diff --git a/gnu/usr.bin/groff/xditview/ad2c b/gnu/usr.bin/groff/xditview/ad2c new file mode 100644 index 00000000000..651ab8c40c5 --- /dev/null +++ b/gnu/usr.bin/groff/xditview/ad2c @@ -0,0 +1,62 @@ +#!/bin/sh +# +# ad2c : Convert app-defaults file to C strings decls. +# +# George Ferguson, ferguson@cs.rcohester.edu, 12 Nov 1990. +# 19 Mar 1991: gf +# Made it self-contained. +# 6 Jan 1992: mycroft@gnu.ai.mit.edu (Charles Hannum) +# Removed use of "-n" and ":read" label since Gnu and +# IBM sed print pattern space on "n" command. Still works +# with Sun sed, of course. +# 7 Jan 1992: matthew@sunpix.East.Sun.COM (Matthew Stier) +# Escape quotes after escaping backslashes. +# 8 Jul 1992: Version 1.6 +# Manpage fixes. +# 19 Apr 1993: Version 1.7 +# Remove comments that were inside the sed command since +# some versions of sed don't like them. The comments are +# now given here in the header. +# +# Comments on the script by line: +# /^!/d Remove comments +# /^$/d Remove blanks +# s/\\/\\\\/g Escape backslashes... +# s/\\$//g ...except the line continuation ones +# s/"/\\"/g Escape quotes +# s/^/"/ Add leading quote +# : test Establish label for later branch +# /\\$/b slash Branch to label "slash" if line ends in backslash +# s/$/",/ Otherwise add closing quote and comma... +# p ...output the line... +# d ...and clear the pattern space so it's not printed again +# : slash Branch comes here if line ends in backslash +# n Read next line, append to pattern space +# [...] The "d" and "s" commands that follow just delete +# comments and blank lines and escape control sequences +# b test Branch up to see if the line ends in backslash or not +# + +sed ' +/^!/d +/^$/d +s/\\/\\\\/g +s/\\$//g +s/"/\\"/g +s/^/"/ +: test +/\\$/b slash +s/$/",/ +p +d +: slash +n +/^!/d +/^$/d +s/"/\\"/g +s/\\\\/\\/g +s/\\n/\\\\n/g +s/\\t/\\\\t/g +s/\\f/\\\\f/g +s/\\b/\\\\b/g +b test' "$@" diff --git a/gnu/usr.bin/groff/xditview/gray1.bm b/gnu/usr.bin/groff/xditview/gray1.bm new file mode 100644 index 00000000000..c40a95e6eab --- /dev/null +++ b/gnu/usr.bin/groff/xditview/gray1.bm @@ -0,0 +1,4 @@ +#define gray1_width 3 +#define gray1_height 3 +static char gray1_bits[] = { + 0x00, 0x02, 0x00}; diff --git a/gnu/usr.bin/groff/xditview/gray2.bm b/gnu/usr.bin/groff/xditview/gray2.bm new file mode 100644 index 00000000000..e87a1bcc073 --- /dev/null +++ b/gnu/usr.bin/groff/xditview/gray2.bm @@ -0,0 +1,4 @@ +#define gray2_width 3 +#define gray2_height 3 +static char gray2_bits[] = { + 0x00, 0x03, 0x00}; diff --git a/gnu/usr.bin/groff/xditview/gray3.bm b/gnu/usr.bin/groff/xditview/gray3.bm new file mode 100644 index 00000000000..d9313ebd5e8 --- /dev/null +++ b/gnu/usr.bin/groff/xditview/gray3.bm @@ -0,0 +1,4 @@ +#define gray3_width 3 +#define gray3_height 3 +static char gray3_bits[] = { + 0x00, 0x03, 0x02}; diff --git a/gnu/usr.bin/groff/xditview/gray4.bm b/gnu/usr.bin/groff/xditview/gray4.bm new file mode 100644 index 00000000000..dad142a9b0f --- /dev/null +++ b/gnu/usr.bin/groff/xditview/gray4.bm @@ -0,0 +1,4 @@ +#define gray4_width 3 +#define gray4_height 3 +static char gray4_bits[] = { + 0x00, 0x07, 0x02}; diff --git a/gnu/usr.bin/groff/xditview/gray5.bm b/gnu/usr.bin/groff/xditview/gray5.bm new file mode 100644 index 00000000000..5f576184172 --- /dev/null +++ b/gnu/usr.bin/groff/xditview/gray5.bm @@ -0,0 +1,4 @@ +#define gray5_width 3 +#define gray5_height 3 +static char gray5_bits[] = { + 0x04, 0x07, 0x02}; diff --git a/gnu/usr.bin/groff/xditview/gray6.bm b/gnu/usr.bin/groff/xditview/gray6.bm new file mode 100644 index 00000000000..b76701db16d --- /dev/null +++ b/gnu/usr.bin/groff/xditview/gray6.bm @@ -0,0 +1,4 @@ +#define gray6_width 3 +#define gray6_height 3 +static char gray6_bits[] = { + 0x04, 0x07, 0x03}; diff --git a/gnu/usr.bin/groff/xditview/gray7.bm b/gnu/usr.bin/groff/xditview/gray7.bm new file mode 100644 index 00000000000..ef47bc692e9 --- /dev/null +++ b/gnu/usr.bin/groff/xditview/gray7.bm @@ -0,0 +1,4 @@ +#define gray7_width 3 +#define gray7_height 3 +static char gray7_bits[] = { + 0x05, 0x07, 0x03}; diff --git a/gnu/usr.bin/groff/xditview/gray8.bm b/gnu/usr.bin/groff/xditview/gray8.bm new file mode 100644 index 00000000000..12de7cb6f57 --- /dev/null +++ b/gnu/usr.bin/groff/xditview/gray8.bm @@ -0,0 +1,4 @@ +#define gray8_width 3 +#define gray8_height 3 +static char gray8_bits[] = { + 0x05, 0x07, 0x07}; |