1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388
|
;;; w3.el --- Main functions for emacs-w3 on all platforms/versions
;; Author: wmperry
;; Created: 1997/12/24 20:09:55
;; Version: 1.151
;; Keywords: faces, help, comm, news, mail, processes, mouse, hypermedia
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Copyright (c) 1993 - 1996 by William M. Perry <wmperry@cs.indiana.edu>
;;; Copyright (c) 1996, 1997 Free Software Foundation, Inc.
;;;
;;; This file is part of GNU Emacs.
;;;
;;; GNU Emacs 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.
;;;
;;; GNU Emacs 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 GNU Emacs; see the file COPYING. If not, write to the
;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;;; Boston, MA 02111-1307, USA.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; This is a major mode for browsing documents written in Hypertext Markup ;;;
;;; Language (HTML). These documents are typicallly part of the World Wide ;;;
;;; Web (WWW), a project to create a global information net in hypertext ;;;
;;; format. ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; first start by making sure the load path is properly set. This code
;;; is mostly taken from calc-2.02b
;;;
;;; this allows you to put the following in your .emacs file, instead of
;;; having to know what the load-path for the w3 files is.
;;;
;;; (autoload 'w3 "w3/w3" "WWW Browser" t)
;;; If w3 files exist on the load-path, we're all set.
(let ((name (and (fboundp 'w3)
(eq (car-safe (symbol-function 'w3)) 'autoload)
(nth 1 (symbol-function 'w3))))
(p load-path))
(while (and p (not (file-exists-p
(expand-file-name "w3-vars.elc" (car p)))))
(setq p (cdr p)))
(or p
;;; If w3 is autoloaded using a path name, look there for w3 files.
;;; This works for both relative ("w3/w3.elc") and absolute paths.
(and name (file-name-directory name)
(let ((p2 load-path)
(name2 (concat (file-name-directory name)
"w3-vars.elc")))
(while (and p2 (not (file-exists-p
(expand-file-name name2 (car p2)))))
(setq p2 (cdr p2)))
(if p2
(setq load-path (nconc load-path
(list
(directory-file-name
(file-name-directory
(expand-file-name
name (car p2)))))))))))
)
(require 'w3-sysdp)
(require 'mule-sysdp)
(require 'widget)
(or (featurep 'efs)
(featurep 'efs-auto)
(condition-case ()
(require 'ange-ftp)
(error nil)))
(require 'cl)
(require 'css)
(require 'w3-vars)
(eval-and-compile
(require 'w3-display))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Code for printing out roman numerals
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun w3-decimal-to-roman (n)
;; Convert from decimal to roman numerals
(let ((curmod 1000)
(str "")
(j 7)
i2 k curcnt)
(while (>= curmod 1)
(if (>= n curmod)
(progn
(setq curcnt (/ n curmod)
n (- n (* curcnt curmod)))
(if (= 4 (% curcnt 5))
(setq i2 (+ j (if (> curcnt 5) 1 0))
str (format "%s%c%c" str
(aref w3-roman-characters (1- j))
(aref w3-roman-characters i2)))
(progn
(if (>= curcnt 5)
(setq str (format "%s%c" str (aref w3-roman-characters j))
curcnt (- curcnt 5)))
(setq k 0)
(while (< k curcnt)
(setq str (format "%s%c" str
(aref w3-roman-characters (1- j)))
k (1+ k)))))))
(setq curmod (/ curmod 10)
j (- j 2)))
str))
(defun w3-decimal-to-alpha (n)
;; Convert from decimal to alphabetical (a, b, c, ..., aa, ab,...)
(cond
((< n 1) (char-to-string ?Z))
((<= n 26) (char-to-string (+ ?A (1- n))))
(t (concat (char-to-string (+ ?A (1- (/ n 27))))
(w3-decimal-to-alpha (% n 26))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Functions to pass files off to external viewers
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun w3-start-viewer (fname cmd &optional view)
"Start a subprocess, named FNAME, executing CMD.
If third arg VIEW is non-nil, show the output in a buffer when
the subprocess exits."
(if view (save-excursion
(set-buffer (get-buffer-create view))
(erase-buffer)))
(start-process fname view shell-file-name shell-command-switch cmd))
(defun w3-viewer-filter (proc string)
;; A process filter for asynchronous external viewers
(let ((buff (get-buffer-create (url-generate-new-buffer-name
(symbol-name
(read (nth 2 (process-command proc))))))))
(save-excursion
(set-buffer buff)
(erase-buffer)
(insert string)
(set-process-buffer proc buff)
(set-process-filter proc nil))))
(defun w3-viewer-sentinel (proc string)
;; Delete any temp files left from a viewer process.
(let ((fname (process-name proc))
(buffr (process-buffer proc))
(status (process-exit-status proc)))
(if buffr
(w3-notify-when-ready buffr))
(and (/= 0 status)
(funcall url-confirmation-func
(format "Viewer for %s failed... save to disk? " fname))
(copy-file fname (read-file-name "Save as: ") t))
(if (and (file-exists-p fname)
(file-writable-p fname))
(delete-file fname)))
;; FSF Emacs doesn't do this after calling a process-sentinel
(set-buffer (window-buffer (selected-window))))
(defun w3-notify-when-ready (buff)
"Notify the user when BUFF is ready.
See the variable `w3-notify' for the different notification behaviors."
(if (stringp buff) (setq buff (get-buffer buff)))
(cond
((null buff) nil)
((eq w3-notify 'newframe)
;; Since we run asynchronously, perhaps while Emacs is waiting for input,
;; we must not leave a different buffer current.
;; We can't rely on the editor command loop to reselect
;; the selected window's buffer.
(save-excursion
(set-buffer buff)
(make-frame)))
((eq w3-notify 'bully)
(pop-to-buffer buff)
(delete-other-windows))
((eq w3-notify 'semibully)
(condition-case nil
(switch-to-buffer buff)
(error (message "W3 buffer %s is ready." (buffer-name buff)))))
((eq w3-notify 'aggressive)
(pop-to-buffer buff))
((eq w3-notify 'friendly)
(display-buffer buff 'not-this-window))
((eq w3-notify 'polite)
(beep)
(message "W3 buffer %s is ready." (buffer-name buff)))
((eq w3-notify 'quiet)
(message "W3 buffer %s is ready." (buffer-name buff)))
(t (message ""))))
(defun w3-pass-to-viewer ()
;; Pass a w3 buffer to a viewer
(set-buffer url-working-buffer)
(let* ((info url-current-mime-viewer) ; All the MIME viewer info
(view (cdr-safe (assoc "viewer" info))) ; How to view this file
(url (url-view-url t))
(fmt (cdr-safe (assoc "nametemplate" info)))) ; Template for name
(cond
(fmt nil)
((cdr-safe (assoc "type" info))
(setq fmt (mm-type-to-file (cdr-safe (assoc "type" info))))
(if fmt
(setq fmt (concat "%s" (car fmt)))
(setq fmt (concat "%s" (url-file-extension
(url-filename url-current-object)))))))
(if (null view)
(setq view 'indented-text-mode))
(cond
((symbolp view)
(if (not (memq view '(w3-prepare-buffer w3-print w3-source
w3-default-local-file
mm-multipart-viewer)))
(let ((bufnam (url-generate-new-buffer-name
(file-name-nondirectory
(or (url-filename url-current-object)
"Unknown")))))
(if (string= bufnam "")
(setq bufnam (url-generate-new-buffer-name
(url-view-url t))))
(rename-buffer bufnam)
;; Make the URL show in list-buffers output
(make-local-variable 'list-buffers-directory)
(setq list-buffers-directory (url-view-url t))
(set-buffer-modified-p nil)
(buffer-enable-undo)
(funcall view)
(w3-notify-when-ready bufnam))
(funcall view)))
((stringp view)
(let ((fname (url-generate-unique-filename fmt))
(proc nil))
(if (url-file-directly-accessible-p (url-view-url t))
(make-symbolic-link (url-filename url-current-object) fname t)
(mule-write-region-no-coding-system (point-min) (point-max) fname))
(if (get-buffer url-working-buffer)
(kill-buffer url-working-buffer))
(setq view (mm-viewer-unescape view fname url))
(message "Passing to viewer %s " view)
(setq proc (w3-start-viewer fname view))
(set-process-filter proc 'w3-viewer-filter)
(set-process-sentinel proc 'w3-viewer-sentinel)))
((listp view)
(set-buffer-modified-p nil)
(buffer-enable-undo)
(eval view))
(t
(message "Unknown viewer specified: %s" view)
(w3-notify-when-ready url-working-buffer)))))
(defun w3-save-binary-file ()
"Save a buffer to disk - this is used when `w3-dump-to-disk' is non-nil"
;; Ok, this is truly fucked. In XEmacs, if you use the mouse to select
;; a URL that gets saved via this function, read-file-name will pop up a
;; dialog box for file selection. For some reason which buffer we are in
;; gets royally screwed (even with save-excursions and the whole nine
;; yards). SO, we just keep the old buffer name around and away we go.
(let ((old-buff (current-buffer))
(file (read-file-name "Filename to save as: "
(or mm-download-directory "~/")
(url-remove-compressed-extensions
(file-name-nondirectory (url-view-url t)))
nil
(url-remove-compressed-extensions
(file-name-nondirectory (url-view-url t)))))
(require-final-newline nil))
(set-buffer old-buff)
(mule-write-region-no-coding-system (point-min) (point-max) file)
(kill-buffer (current-buffer))))
;;;###autoload
(defun w3-open-local (fname)
"Find a local file, and interpret it as a hypertext document.
It will prompt for an existing file or directory, and retrieve it as a
hypertext document."
(interactive "FLocal file: ")
(setq fname (expand-file-name fname))
(if (not w3-setup-done) (w3-do-setup))
(w3-fetch (concat "file:" fname)))
;;;###autoload
(defun w3-find-file (fname)
"Find a local file, and interpret it as a hypertext document.
It will prompt for an existing file or directory, and retrieve it as a
hypertext document."
(interactive "FLocal file: ")
(w3-open-local fname))
;;;###autoload
(defun w3-fetch-other-frame (&optional url)
"Attempt to follow the hypertext reference under point in a new frame.
With prefix-arg P, ignore viewers and dump the link straight
to disk."
(interactive (list (w3-read-url-with-default)))
(cond
((and (fboundp 'make-frame)
(fboundp 'select-frame)
(not (eq (device-type) 'tty)))
(let ((frm (make-frame)))
(select-frame frm)
(delete-other-windows)
(w3-fetch url)))
(t (w3-fetch url))))
(defun w3-fetch-other-window (&optional url)
"Attempt to follow the hypertext reference under point in a new window.
With prefix-arg P, ignore viewers and dump the link straight
to disk."
(interactive (list (w3-read-url-with-default)))
(split-window)
(w3-fetch url))
;; Ripped off from red gnus
(defun w3-find-etc-directory (package &optional file)
"Go through the path and find the \".../etc/PACKAGE\" directory.
If FILE, find the \".../etc/PACKAGE\" file instead."
(let ((path load-path)
dir result)
;; We try to find the dir by looking at the load path,
;; stripping away the last component and adding "etc/".
(while path
(if (and (car path)
(file-exists-p
(setq dir (concat
(file-name-directory
(directory-file-name (car path)))
"etc/" package
(if file "" "/"))))
(or file (file-directory-p dir)))
(setq result dir
path nil)
(setq path (cdr path))))
result))
(defun w3-url-completion-function (string predicate function)
(if (not w3-setup-done) (w3-do-setup))
(cond
((eq function nil)
(let ((list nil))
(cl-maphash (function (lambda (key val)
(setq list (cons (cons key val)
list))))
url-global-history-hash-table)
(try-completion string (nreverse list) predicate)))
((eq function t)
(let ((stub (concat "^" (regexp-quote string)))
(retval nil))
(cl-maphash
(function
(lambda (url time)
(if (string-match stub url)
(setq retval (cons url retval)))))
url-global-history-hash-table)
retval))
((eq function 'lambda)
(and url-global-history-hash-table
(cl-gethash string url-global-history-hash-table)
t))
(t
(error "w3-url-completion-function very confused."))))
(defun w3-read-url-with-default ()
(url-do-setup)
(let* ((completion-ignore-case t)
(default
(cond
((null w3-fetch-with-default) nil)
((eq major-mode 'w3-mode)
(or (and current-prefix-arg (w3-view-this-url t))
(url-view-url t)))
((url-get-url-at-point)
(url-get-url-at-point))
(t "http://www.")))
(url nil))
(setq url
(completing-read "URL: " 'w3-url-completion-function
nil nil default))
(if (string= url "")
(setq url (if (eq major-mode 'w3-mode)
(if (and current-prefix-arg (w3-view-this-url t))
(w3-view-this-url t)
(url-view-url t))
(url-get-url-at-point))))
url))
;;;###autoload
(defun w3-fetch (&optional url target)
"Retrieve a document over the World Wide Web.
Defaults to URL of the current document, if any.
With prefix argument, use the URL of the hyperlink under point instead."
(interactive (list (w3-read-url-with-default)))
(if (not w3-setup-done) (w3-do-setup))
(if (boundp 'w3-working-buffer)
(setq w3-working-buffer url-working-buffer))
(if (and (boundp 'command-line-args-left)
command-line-args-left
(string-match url-nonrelative-link (car command-line-args-left)))
(setq url (car command-line-args-left)
command-line-args-left (cdr command-line-args-left)))
(if (equal url "") (error "No document specified!"))
;; legal use for relative URLs ?
(if (string-match "^www:[^/].*" url)
(setq url (concat (file-name-directory (url-filename
url-current-object))
(substring url 4))))
;; In the common case, this is probably cheaper than searching.
(while (= (string-to-char url) ? )
(setq url (substring url 1)))
(or target (setq target w3-base-target))
(if (stringp target)
(setq target (intern (downcase target))))
(and target
(let ((window-distance (cdr-safe (assq target w3-target-window-distances))))
(if (numberp window-distance)
(other-window window-distance)
(case target
((_blank external)
(w3-fetch-other-frame url))
(_top
(delete-other-windows))
(otherwise
(message "target %S not found." target))))))
(cond
((= (string-to-char url) ?#)
(w3-relative-link url))
((or (and (interactive-p) current-prefix-arg) w3-dump-to-disk)
(w3-download-url url))
(t
(let ((x (url-view-url t))
(lastbuf (current-buffer))
(buf (url-buffer-visiting url)))
(if (or (not buf)
(cond
((not (equal (downcase (or url-request-method "GET")) "get")) t)
((memq w3-reuse-buffers '(no never reload)) t)
((memq w3-reuse-buffers '(yes reuse always)) nil)
(t
(if (and w3-reuse-buffers (not (eq w3-reuse-buffers 'ask)))
(progn
(ding)
(message
"Warning: Invalid value for variable w3-reuse-buffers: %s"
(prin1-to-string w3-reuse-buffers))
(sit-for 2)))
(not (funcall url-confirmation-func
(format "Reuse URL in buffer %s? "
(buffer-name buf)))))))
(let* ((status (url-retrieve url))
(cached (car status))
(url-working-buffer (cdr status)))
(if w3-track-last-buffer
(setq w3-last-buffer (get-buffer url-working-buffer)))
(if (get-buffer url-working-buffer)
(cond
((and url-be-asynchronous (not cached))
(save-excursion
(set-buffer url-working-buffer)
(w3-history-push x (url-view-url t))
(setq w3-current-last-buffer lastbuf)))
(t
(w3-history-push x url)
(w3-sentinel lastbuf)))))
(if w3-track-last-buffer
(setq w3-last-buffer buf))
(let ((w3-notify (if (memq w3-notify '(newframe bully
semibully aggressive))
w3-notify
'aggressive)))
(w3-notify-when-ready buf))
(if (string-match "#\\(.*\\)" url)
(progn
(push-mark (point) t)
(w3-find-specific-link (url-match url 1))))
(or (w3-maybe-fetch-frames)
(message "Reusing URL. To reload, type %s."
(substitute-command-keys "\\[w3-reload-document]"))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; History for forward/back buttons
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar w3-history-stack nil
"History stack viewing history.
This is an assoc list, with the oldest items first.
Each element is a cons cell of (url . timeobj), where URL
is the normalized URL (default ports removed, etc), and TIMEOBJ is
a standard Emacs time. See the `current-time' function documentation
for information on this format.")
(defun w3-history-find-url-internal (url)
"Search in the history list for URL.
Returns a cons cell, where the car is the 'back' node, and
the cdr is the 'next' node."
(let* ((node (assoc url w3-history-stack))
(next (cadr (memq node w3-history-stack)))
(last nil)
(temp nil)
(todo w3-history-stack))
;; Last node is a little harder to find without using back links
(while (and (not last) todo)
(if (string= (caar todo) url)
(setq last (or temp 'none))
(setq temp (pop todo))))
(cons (if (not (symbolp last)) last)
next)))
(defun w3-history-forward ()
"Go forward in the history from this page"
(interactive)
(let ((next (cadr (w3-history-find-url-internal (url-view-url t))))
(w3-reuse-buffers 'yes))
(if next
(w3-fetch next))))
(defun w3-history-backward ()
"Go backward in the history from this page"
(interactive)
(let ((last (caar (w3-history-find-url-internal (url-view-url t))))
(w3-reuse-buffers 'yes))
(if last
(w3-fetch last))))
(defun w3-history-push (referer url)
"REFERER is the url we followed this link from. URL is the link we got to."
(if (not referer)
(setq w3-history-stack (list (cons url (current-time))))
(let ((node (memq (assoc referer w3-history-stack) w3-history-stack)))
(if node
(setcdr node (list (cons url (current-time))))
(setq w3-history-stack (append w3-history-stack
(list
(cons url (current-time)))))))))
(defalias 'w3-add-urls-to-history 'w3-history-push)
(defalias 'w3-backward-in-history 'w3-history-backward)
(defalias 'w3-forward-in-history 'w3-history-forward)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Miscellaneous functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun w3-describe-entities ()
"Show an DTD fragment listing all the entities currently defined."
(interactive)
(switch-to-buffer (get-buffer-create "W3 Entities"))
(let ((buffer-file-name (concat (make-temp-name "entities") ".dtd")))
(set-auto-mode))
(erase-buffer)
(let (entity)
(mapatoms
(function
(lambda (x)
(setq entity (get x 'html-entity-expansion))
(if entity
(insert (format "<!entity %s %s \"%s\">\n" x (car entity)
(cdr entity))))))))
(goto-char (point-min)))
(defun w3-executable-exists-in-path (exec &optional path)
(let ((paths (if (consp path)
path
(mm-string-to-tokens (or path
(getenv "PATH")
(concat
"/usr/bin:/bin:/usr/local/bin:"
"/usr/bin/X11:"
(expand-file-name "~/bin"))) ?:)))
(done nil))
(while (and paths (not done))
(if (file-exists-p (expand-file-name exec (car paths)))
(setq done t))
(setq paths (cdr paths)))
done))
(defun w3-document-information (&optional buff)
"Display information on the document in buffer BUFF"
(interactive)
(if (interactive-p)
(let ((w3-notify 'friendly))
(if (get-buffer "Document Information")
(kill-buffer (get-buffer "Document Information")))
(w3-fetch "about:document"))
(setq buff (or buff (current-buffer)))
(save-excursion
(set-buffer buff)
(let* ((url (url-view-url t))
(cur-links w3-current-links)
(title (buffer-name))
(case-fold-search t)
(possible-lastmod (save-excursion
(goto-char (point-min))
(if (re-search-forward "^Last modified:\\(.*\\)" nil t)
(buffer-substring (match-beginning 1)
(match-end 1)))))
(attributes (url-file-attributes url))
(lastmod (or (cdr-safe (assoc "last-modified"
url-current-mime-headers))
(nth 5 attributes)))
(hdrs url-current-mime-headers)
(size (or (cdr (assoc "content-length" url-current-mime-headers))
(buffer-size)))
(info w3-current-metainfo))
(set-buffer (get-buffer-create url-working-buffer))
(setq url-current-can-be-cached nil)
(erase-buffer)
(cond
((stringp lastmod) nil)
((equal '(0 . 0) lastmod) (setq lastmod possible-lastmod))
((consp lastmod) (setq lastmod (current-time-string lastmod)))
(t (setq lastmod possible-lastmod)))
(setq url-current-mime-type "text/html")
(insert "<html>\n"
" <head>\n"
" <title>Document Information</title>\n"
" </head>\n"
" <body\n"
" <table border>\n"
" <tr><th colspan=2>Document Information</th></tr>\n"
" <tr><td>Title:</td><td>" title "</td></tr>\n"
" <tr><td>Location:</td><td>" url "</td></tr>\n"
" <tr><td>Size:</td><td>" (url-pretty-length
(if (stringp size)
(string-to-int size)
size)) "</td></tr>\n"
" <tr><td>Last Modified:</td><td>" (or lastmod "None Given")
"</td></tr>\n")
(if hdrs
(let* ((maxlength (car (sort (mapcar (function (lambda (x)
(length (car x))))
hdrs)
'>)))
(fmtstring (format " <tr><td align=right>%%%ds:</td><td>%%s</td></tr>" maxlength)))
(insert " <tr><th colspan=2>MetaInformation</th></tr>\n"
(mapconcat
(function
(lambda (x)
(if (/= (length (car x)) 0)
(format fmtstring
(url-insert-entities-in-string
(capitalize (car x)))
(url-insert-entities-in-string
(if (numberp (cdr x))
(int-to-string (cdr x))
(cdr x)))))))
(sort hdrs
(function
(lambda (x y) (string-lessp (car x) (car y)))))
"\n"))))
;; FIXME!!! Need to reimplement showing rel/rev links for the new
;; storage format.
(if info
(let* ((maxlength (car (sort (mapcar (function (lambda (x)
(length (car x))))
info)
'>)))
(fmtstring (format " <tr><td>%%%ds:</td><td>%%s</td></tr>" maxlength)))
(insert " <tr><th colspan=2>Miscellaneous Variables</th></tr>\n")
(while info
(if (and (caar info) (cdar info))
(insert (format fmtstring
(url-insert-entities-in-string
(capitalize (caar info)))
(url-insert-entities-in-string
(cdar info))) "\n"))
(setq info (cdr info))
)
)
)
(insert " </table>\n"
" </body>\n"
"</html>\n")))))
(defun w3-truncate-menu-item (string)
(if (<= (length string) w3-max-menu-width)
string
(concat (substring string 0 w3-max-menu-width) "$")))
(defun w3-insert-formatted-url (p)
"Insert a formatted url into a buffer. With prefix arg, insert the url
under point."
(interactive "P")
(let (buff str)
(cond
(p
(setq p (widget-at (point)))
(or p (error "No url under point"))
(setq str (format "<a href=\"%s\">%s</a>" (widget-get p :href)
(read-string "Link text: "
(buffer-substring
(widget-get p :from)
(widget-get p :to))))))
(t
(setq str (format "<a href=\"%s\">%s</a>" (url-view-url t)
(read-string "Link text: " (buffer-name))))))
(setq buff (read-buffer "Insert into buffer: " nil t))
(if buff
(save-excursion
(set-buffer buff)
(insert str))
(message "Cancelled."))))
(defun w3-first-n-items (l n)
"Return the first N items from list L"
(let ((x 0)
y)
(if (> n (length l))
(setq y l)
(while (< x n)
(setq y (nconc y (list (nth x l)))
x (1+ x))))
y))
(defun w3-widget-button-press ()
(interactive)
(if (widget-at (point))
(widget-button-press (point))))
(defun w3-widget-button-click (e)
(interactive "@e")
(cond
((and (event-point e)
(widget-at (event-point e)))
(widget-button-click e))
((and (fboundp 'event-glyph)
(event-glyph e)
(glyph-property (event-glyph e) 'widget))
(widget-button-click e))))
(defun w3-breakup-menu (menu-desc max-len)
(if (> (length menu-desc) max-len)
(cons (cons "More..." (w3-first-n-items menu-desc max-len))
(w3-breakup-menu (nthcdr max-len menu-desc) max-len))
menu-desc))
;;;###autoload
(defun w3-maybe-follow-link-mouse (e)
"Maybe follow a hypertext link under point.
If there is no link under point, this will try using
url-get-url-at-point"
(interactive "e")
(save-excursion
(mouse-set-point e)
(w3-maybe-follow-link)))
;;;###autoload
(defun w3-maybe-follow-link ()
"Maybe follow a hypertext link under point.
If there is no link under point, this will try using
url-get-url-at-point"
(interactive)
(require 'w3)
(if (not w3-setup-done) (w3-do-setup))
(let* ((widget (widget-at (point)))
(url1 (and widget (widget-get widget :href)))
(url2 (url-get-url-at-point)))
(cond
(url1 (widget-button-press))
((and url2 (string-match url-nonrelative-link url2)) (w3-fetch url2))
(t (message "No URL could be found!")))))
;;;###autoload
(defun w3-follow-url-at-point-other-frame (&optional pt)
"Follow the URL under PT, defaults to link under (point)"
(interactive "d")
(let ((url (url-get-url-at-point pt)))
(and url (w3-fetch-other-frame url))))
;;;###autoload
(defun w3-follow-url-at-point (&optional pt)
"Follow the URL under PT, defaults to link under (point)"
(interactive "d")
(let ((url (url-get-url-at-point pt)))
(and url (w3-fetch url))))
(defun w3-fix-spaces (x)
"Remove spaces/tabs at the beginning of a string,
and convert newlines into spaces."
(url-convert-newlines-to-spaces
(url-strip-leading-spaces
(url-eat-trailing-space x))))
(defun w3-reload-all-files ()
"Reload all w3 files"
(interactive)
(setq w3-setup-done nil
url-setup-done nil
w3-hotlist nil
url-mime-accept-string nil)
(let ((x '(w3 base64 css mule-sysdp w3-e19 mm url w3-xemac
w3-e20 dsssl dsssl-flow font images ssl url-auth
url-cache url-cookie url-file url-gopher url-gw
url-http url-mail url-misc url-news url-ns url-parse
url-vars w3-about w3-cus w3-display w3-e20 w3-elisp
w3-emulate w3-forms w3-hot w3-imap w3-jscript
w3-keyword w3-latex w3-menu w3-mouse w3-parse
w3-prefs w3-print w3-props w3-script w3-speak w3-style
w3-sysdp w3-toolbar w3-vars w3-widget w3-xemac w3
w3-toolbar font)))
(while x
(setq features (delq (car x) features)
x (cdr x)))
(require 'w3))
(mapatoms (function
(lambda (sym)
(if (or (string-match "^w3-" (symbol-name sym))
(string-match "^url-" (symbol-name sym))
(string-match "^ssl-" (symbol-name sym))
(string-match "^base64-" (symbol-name sym))
(string-match "^dsssl-" (symbol-name sym))
(string-match "^mm-" (symbol-name sym)))
(progn
(fmakunbound sym)
(makunbound sym))))))
(require 'w3))
(defun w3-source-document-at-point ()
"View source to the document pointed at by link under point"
(interactive)
(w3-source-document t))
(defun w3-source-document (under)
"View this document's source"
(interactive "P")
(let* ((url (if under (w3-view-this-url) (url-view-url t)))
(src
(cond
((null url)
(error "No URL found!"))
((and under (null url)) (error "No link at point!"))
((and (not under) (equal url-current-mime-type "text/plain"))
(buffer-string))
((and (not under) w3-current-source) w3-current-source)
(t
(prog2
(url-retrieve url)
(buffer-string)
(kill-buffer (current-buffer))))))
(tmp (url-generate-new-buffer-name url)))
(if (and url (get-buffer url))
(cond
((memq w3-reuse-buffers '(no never reload))
(kill-buffer url))
((memq w3-reuse-buffers '(yes reuse always))
(w3-notify-when-ready (get-buffer url))
(setq url nil))
((funcall url-confirmation-func
(concat "Source for " url " found, reuse? "))
(w3-notify-when-ready (get-buffer url)))))
(if (not url) nil
(set-buffer (get-buffer-create tmp))
(insert src)
(put-text-property (point-min) (point-max) 'w3-base url)
(goto-char (point-min))
(setq buffer-file-truename url
buffer-file-name url)
;; Null filename bugs `set-auto-mode' in Mule ...
(condition-case ()
(set-auto-mode)
(error nil))
(setq buffer-file-truename nil
buffer-file-name nil)
(buffer-enable-undo)
(set-buffer-modified-p nil)
(w3-notify-when-ready (get-buffer tmp))))
(run-hooks 'w3-source-file-hook))
(defun w3-mail-document-under-point ()
"Mail the document pointed to by the hyperlink under point."
(interactive)
(w3-mail-current-document t))
(defun w3-mail-current-document (under &optional format)
"Mail the current-document to someone"
(interactive "P")
(let* ((completion-ignore-case t)
(format (or format
(completing-read
"Format: "
'(("HTML Source")
("Formatted Text")
("PostScript")
("LaTeX Source")
)
nil t)))
(case-fold-search t)
(url (cond
((stringp under) under)
(under (w3-view-this-url t))
(t (url-view-url t))))
(content-type "text/plain; charset=iso-8859-1")
(str
(save-excursion
(cond
((and (equal "HTML Source" format) under)
(setq content-type "text/html; charset=iso-8859-1")
(let ((url-source t))
(url-retrieve url)))
((equal "HTML Source" format)
(setq content-type "text/html; charset=iso-8859-1")
(if w3-current-source
(let ((x w3-current-source))
(set-buffer (get-buffer-create url-working-buffer))
(erase-buffer)
(insert x))
(url-retrieve url)))
((and under (equal "PostScript" format))
(setq content-type "application/postscript")
(w3-fetch url)
(require 'ps-print)
(let ((ps-spool-buffer-name " *w3-temp*"))
(if (get-buffer ps-spool-buffer-name)
(kill-buffer ps-spool-buffer-name))
(ps-spool-buffer-with-faces)
(set-buffer ps-spool-buffer-name)))
((equal "PostScript" format)
(require 'ps-print)
(let ((ps-spool-buffer-name " *w3-temp*"))
(if (get-buffer ps-spool-buffer-name)
(kill-buffer ps-spool-buffer-name))
(setq content-type "application/postscript")
(ps-spool-buffer-with-faces)
(set-buffer ps-spool-buffer-name)))
((and under (equal "Formatted Text" format))
(setq content-type "text/plain; charset=iso-8859-1")
(w3-fetch url))
((equal "Formatted Text" format)
(setq content-type "text/plain; charset=iso-8859-1"))
((and under (equal "LaTeX Source" format))
(let ((old-asynch (default-value 'url-be-asynchronous)))
(setq content-type "application/x-latex; charset=iso-8859-1")
(unwind-protect
(progn
(setq-default url-be-asynchronous nil)
(url-retrieve url))
(setq-default url-be-asynchronous old-asynch))
(w3-parse-tree-to-latex (w3-parse-buffer (current-buffer))
url)))
((equal "LaTeX Source" format)
(setq content-type "application/x-latex; charset=iso-8859-1")
(w3-parse-tree-to-latex w3-current-parse url)))
(buffer-string))))
(funcall url-mail-command)
(mail-subject)
(if (and (boundp 'mime/editor-mode-flag) mime/editor-mode-flag)
(insert format " from <URL: " url ">")
(insert format " from <URL: " url ">\n"
"Mime-Version: 1.0\n"
"Content-transfer-encoding: 8bit\n"
"Content-type: " content-type))
(re-search-forward mail-header-separator nil)
(forward-char 1)
(if (and (boundp 'mime/editor-mode-flag) mime/editor-mode-flag)
(insert (format mime-tag-format content-type) "\n"))
(save-excursion
(insert str))
(cond ((equal "HTML Source" format)
(if (or (search-forward "<head>" nil t)
(search-forward "<html>" nil t))
(insert "\n"))
(insert (format "<base href=\"%s\">" url))))
(mail-to)))
(defun w3-internal-use-history (hist-item)
;; Go to the link in the history
(let ((url (nth 0 hist-item))
(buf (nth 1 hist-item))
(pnt (nth 2 hist-item)))
(cond
((null buf) ; Find a buffer with same url
(let ((x (buffer-list))
(found nil))
(while (and x (not found))
(save-excursion
(set-buffer (car x))
(setq found (string= (url-view-url t) url))
(if (not found) (setq x (cdr x)))))
(cond
(found
(switch-to-buffer (car x))
(if (number-or-marker-p pnt) (goto-char pnt)))
(t
(w3-fetch url)))))
((buffer-name buf) ; Reuse the old buffer if possible
(switch-to-buffer buf)
(if (number-or-marker-p pnt) (goto-char pnt))
(if (and url (= ?# (string-to-char url))) ; Destination link
(progn
(goto-char (point-min))
(w3-find-specific-link (substring url 1 nil)))))
(url (url-maybe-relative url)) ; Get the link
(t (message "Couldn't understand whats in the history.")))))
(defun w3-relative-link (url)
(if (equal "#" (substring url 0 1))
(progn
(push-mark (point) t)
(goto-char (point-min))
(w3-find-specific-link (substring url 1 nil)))
(w3-fetch (url-expand-file-name url))))
(defun w3-maybe-eval ()
;; Maybe evaluate a buffer of emacs lisp code
(if (funcall url-confirmation-func "This is emacs-lisp code, evaluate it?")
(eval-buffer (current-buffer))
(emacs-lisp-mode)))
(defun w3-build-continuation ()
;; Build a series of functions to be run on this file
(save-excursion
(set-buffer url-working-buffer)
(let ((cont w3-default-continuation)
(extn (url-file-extension
(url-filename url-current-object))))
(if (assoc extn url-uncompressor-alist)
(setq extn (url-file-extension
(substring (url-filename url-current-object)
0 (- (length extn))))))
(if w3-source
(setq url-current-mime-viewer '(("viewer" . w3-source))))
(if (not url-current-mime-viewer)
(setq url-current-mime-viewer
(mm-mime-info (or url-current-mime-type
(mm-extension-to-mime extn)) nil 5)))
(if url-current-mime-viewer
(setq cont (append cont '(w3-pass-to-viewer)))
(setq cont (append cont (list 'w3-prepare-buffer))))
cont)))
(defun w3-use-links ()
"Select one of the <LINK> tags from this document and fetch it."
(interactive)
(and (not w3-current-links)
(error "No links defined for this document."))
(w3-fetch "about:document"))
(defun w3-find-this-file ()
"Do a find-file on the currently viewed html document if it is a file: or
ftp: reference"
(interactive)
(or url-current-object
(error "Not a URL-based buffer"))
(let ((type (url-type url-current-object)))
(cond
((equal type "file")
(find-file (url-filename url-current-object)))
((equal type "ftp")
(find-file
(format "/%s@%s:%s"
(url-user url-current-object)
(url-host url-current-object)
(url-filename url-current-object))))
(t (message "Sorry, I can't get that file so you can alter it.")))))
(defun w3-insert-this-url (pref-arg)
"Insert the current url in another buffer, with prefix ARG,
insert URL under point"
(interactive "P")
(let ((thebuf (get-buffer (read-buffer "Insert into buffer: ")))
(oldbuf (current-buffer))
(url (if pref-arg (w3-view-this-url t) (url-view-url t))))
(if (and url (not (equal "Not on a link!" url)))
(progn
(set-buffer thebuf)
(insert url)
(set-buffer oldbuf))
(message "Not on a link!"))))
(defun w3-show-hotlist ()
"View the hotlist in hypertext form"
(interactive)
(if (not w3-setup-done) (w3-do-setup))
(if (not w3-hotlist)
(error "Sorry, no hotlist is in memory.")
(let ((x (url-buffer-visiting "www:/auto/hotlist")))
(while x
(kill-buffer x)
(setq x (url-buffer-visiting "www:/auto/hotlist"))))
(w3-fetch "www://auto/hotlist")))
(defun url-maybe-relative (url)
"Take a url and either fetch it, or resolve relative refs, then fetch it"
(cond
((not
(string-match url-nonrelative-link url))
(w3-relative-link url))
(t (w3-fetch url))))
(defun w3-in-assoc (elt list)
"Check to see if ELT matches any of the regexps in the car elements of LIST"
(let (rslt)
(while (and list (not rslt))
(and (car (car list))
(stringp (car (car list)))
(not (string= (car (car list)) ""))
(string-match (car (car list)) elt)
(setq rslt (car list)))
(setq list (cdr list)))
rslt))
(defun w3-goto-last-buffer ()
"Go to last WWW buffer visited"
(interactive)
(if w3-current-last-buffer
(if w3-frame-name
(progn
(delete-other-windows)
(set-buffer w3-current-last-buffer)
(w3-goto-last-buffer))
(w3-notify-when-ready w3-current-last-buffer))
(message "No previous buffer found.")))
(fset 'w3-replace-regexp 'url-replace-regexp)
;;;###autoload
(defun w3-preview-this-buffer ()
"See what this buffer will look like when its formatted as HTML.
HTML is the HyperText Markup Language used by the World Wide Web to
specify formatting for text. More information on HTML can be found at
ftp.w3.org:/pub/www/doc."
(interactive)
(w3-fetch (concat "www://preview/" (buffer-name))))
(defun w3-source ()
"Show the source of a file"
(let ((tmp (buffer-name (generate-new-buffer "Document Source"))))
(set-buffer url-working-buffer)
(kill-buffer tmp)
(rename-buffer tmp)
;; Make the URL show in list-buffers output
(make-local-variable 'list-buffers-directory)
(setq list-buffers-directory (url-view-url t))
(set-buffer-modified-p nil)
(buffer-enable-undo)
(w3-notify-when-ready (get-buffer tmp))))
(defvar w3-mime-list-for-code-conversion
'("text/plain" "text/html")
"List of MIME types that require Mules' code conversion.")
(defun w3-convert-code-for-mule (mmtype)
"Convert current data into the appropriate coding system"
(and (or (not mmtype)
(member mmtype w3-mime-list-for-code-conversion))
(mule-code-convert-region
(point-min) (point-max)
(mule-detect-coding-version (point-min) (point-max)))))
(defun w3-sentinel (&optional proc string)
(set-buffer url-working-buffer)
(if (or (stringp proc)
(bufferp proc)) (setq w3-current-last-buffer proc))
(remove-hook 'after-change-functions 'url-after-change-function)
(if url-be-asynchronous
(progn
(cond
((not (get-buffer url-working-buffer)) nil)
((url-mime-response-p) (url-parse-mime-headers)))
(if (not url-current-mime-type)
(setq url-current-mime-type (or (mm-extension-to-mime
(url-file-extension
(url-filename
url-current-object)))
"text/html")))))
(if (not (string-match "^www:" (or (url-view-url t) "")))
(w3-convert-code-for-mule url-current-mime-type))
(let ((x (w3-build-continuation))
(url (url-view-url t)))
(while x
(funcall (pop x)))))
(defun w3-show-history-list ()
"Format the url-history-list prettily and show it to the user"
(interactive)
(w3-fetch "www://auto/history"))
(defun w3-save-as (&optional type)
"Save a document to the local disk"
(interactive)
(save-excursion
(let* ((completion-ignore-case t)
(format (or type (completing-read
"Format: "
'(("HTML Source")
("Formatted Text")
("LaTeX Source")
("PostScript")
("Binary"))
nil t)))
(fname (expand-file-name
(read-file-name "File name: " default-directory)))
(url (url-view-url t)))
(cond
((equal "Binary" format)
(if (not w3-current-source)
(let ((url-be-asynchronous nil))
(url-retrieve url))))
((equal "HTML Source" format)
(if (not w3-current-source)
(let ((url-be-asynchronous nil))
(url-retrieve url)) ; Get the document if necessary
(let ((txt w3-current-source))
(set-buffer (get-buffer-create url-working-buffer))
(erase-buffer)
(insert txt)))
(goto-char (point-min))
(if (re-search-forward "<head>" nil t)
(insert "\n"))
(insert (format "<BASE HREF=\"%s\">\n" url)))
((or (equal "Formatted Text" format)
(equal "" format))
nil) ; Do nothing - we have the text already
((equal "PostScript" format)
(require 'ps-print)
(let ((ps-spool-buffer-name " *w3-temp*"))
(if (get-buffer ps-spool-buffer-name)
(kill-buffer ps-spool-buffer-name))
(ps-spool-buffer-with-faces)
(set-buffer ps-spool-buffer-name)))
((equal "LaTeX Source" format)
(w3-parse-tree-to-latex w3-current-parse url)))
(write-region (point-min) (point-max) fname))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Functions to parse out <A> tags and replace it with a hyperlink zone
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun w3-popup-image-info (url)
(interactive)
(let* ((glyph (cdr-safe (assoc url w3-graphics-list)))
image w h d info)
(save-excursion
(if (or (not glyph) (not (glyphp glyph)))
(error "No information available."))
(setq image (glyph-image-instance glyph))
(if (or (not image) (not (image-instance-p image)))
(error "No information available."))
(setq w (glyph-width glyph)
h (glyph-height glyph)
d (image-instance-depth image)
info (url-popup-info url)
)
(set-buffer (get-buffer-create "*Image Info*"))
(erase-buffer)
(insert
"Information for: " url "\n"
(make-string (1- (window-width)) ?-)
(format "\n%-20s: %s\n" "Type" (image-instance-type image))
(format "%-20s: %d x %d\n" "Dimensions" w h)
(format "%-20s: %d-bit\n" "Color" d))
(set-extent-begin-glyph (make-extent (point) (point)) glyph)
(insert
"\n"
(make-string (1- (window-width)) ?-)
(or info ""))
(display-buffer (current-buffer) t))))
(defun w3-popup-info (&optional url)
"Show information about the link under point. (All SGML attributes)"
(interactive (list (or (w3-view-this-url t)
(w3-read-url-with-default))))
(let (dat widget)
(if (interactive-p)
nil
(setq widget (widget-at (point))
dat (and widget (widget-get widget 'attributes))))
(if url
(save-excursion
(set-buffer (get-buffer-create "*Header Info*"))
(erase-buffer)
(insert "URL: " url "\n" (make-string (1- (window-width)) ?-) "\n")
(if (and dat (listp dat))
(insert
"Link attributes:\n"
(make-string (1- (window-width)) ?-) "\n"
(mapconcat
(function
(lambda (info)
(format "%20s :== %s" (car info) (or (cdr info) "On"))))
dat "\n")
"\n" (make-string (1- (window-width)) ?-) "\n"))
(insert (save-excursion (url-popup-info url)))
(goto-char (point-min))
(display-buffer (current-buffer) t))
(message "No URL to get information on!"))))
(fset 'w3-document-information-this-url 'w3-popup-info)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Functions for logging of bad HTML
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun w3-reconstruct-tag (tagname desc)
(concat "<" tagname " "
(mapconcat
(function (lambda (x)
(if (cdr x)
(concat (car x) "=\"" (cdr x) "\"")
(car x)))) desc " ") ">"))
(defun w3-debug-if-found (regexp type desc)
(and w3-debug-html
(save-excursion
(if (re-search-forward regexp nil t)
(w3-log-bad-html type desc)))))
(defun w3-log-bad-html (type desc)
;; Log bad HTML to the buffer specified by w3-debug-buffer
(if w3-debug-html
(save-excursion
(set-buffer (get-buffer-create w3-debug-buffer))
(goto-char (point-max))
(insert (make-string (1- (window-width)) w3-horizontal-rule-char) "\n")
(cond
((stringp type) (insert type "\n" desc "\n"))
((eq type 'bad-quote)
(insert "Unterminated quoting character in SGML attribute value.\n"
desc "\n"))
((eq type 'no-quote)
(insert "Unquoted SGML attribute value.\n" desc "\n"))
((eq type 'no-textarea-end)
(insert "Unterminated <textarea> tag.\n"
(w3-reconstruct-tag "textarea" desc) "\n"))
((eq type 'bad-link-tag)
(insert "Must specify either REL or REV with a <link> tag.\n"
(w3-reconstruct-tag "link" desc) "\n"))
((eq type 'no-a-end)
(insert "Unterminated <a> tag.\n"
(w3-reconstruct-tag "a" desc) "\n"))
((eq type 'no-form-end)
(insert "Unterminated <form> tag.\n"
(w3-reconstruct-tag "form" desc) "\n"))
((eq type 'bad-base-tag)
(insert "Malformed <base> tag.\n"
(w3-reconstruct-tag "base" desc) "\n"))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Functions to handle formatting an html buffer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun w3-add-delayed-graphic (widget)
;; Add a delayed image for the current buffer.
(setq w3-delayed-images (cons widget w3-delayed-images)))
(defun w3-load-flavors ()
;; Load the correct emacsen specific stuff
(cond
((and w3-running-xemacs (eq system-type 'ms-windows))
(error "WinEmacs no longer supported."))
(w3-running-xemacs (require 'w3-xemac))
(t ; Assume we are the FSF variant
(require (intern (format "w3-e%d" emacs-major-version)))))
(if (featurep 'emacspeak)
(condition-case ()
(progn
(require 'dtk-css-speech)
(require 'w3-speak))))
(condition-case ()
(require 'w3-site-init)
(error nil)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Automatic bug submission. ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun w3-submit-bug ()
"Submit a bug on Emacs-w3"
(interactive)
(require 'reporter)
(and (yes-or-no-p "Do you really want to submit a bug on Emacs-w3? ")
(let ((url (url-view-url t))
(vars '(window-system
window-system-version
system-type
ange-ftp-version
url-gateway-method
efs-version
ange-ftp-version
url-version
url-be-asynchronous
url)))
(if (and url (string= url "file:nil")) (setq url nil))
(mapcar
(function
(lambda (x)
(if (not (and (boundp x) (symbol-value x)))
(setq vars (delq x vars))))) vars)
(reporter-submit-bug-report w3-bug-address
(concat "WWW v" w3-version-number " of "
w3-version-date)
vars
nil nil
"Description of Problem:"))))
(defalias 'w3-bug 'w3-submit-bug)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Support for searching ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun w3-nuke-spaces-in-search (x)
"Remove spaces from search strings . . ."
(let ((new ""))
(while (not (equal x ""))
(setq new (concat new (if (= (string-to-char x) 32) "+"
(substring x 0 1)))
x (substring x 1 nil)))
new))
(defun w3-search ()
"Perform a search, if this is a searchable index."
(interactive)
(let* (querystring ; The string to send to the server
(data
(cond
((null w3-current-isindex)
(let ((rels (cdr-safe (assq 'rel w3-current-links)))
val cur)
(while rels
(setq cur (car rels)
rels (cdr rels))
(if (and (or (string-match "^isindex$" (car cur))
(string-match "^index$" (car cur)))
(plist-get (cadr cur) 'href))
(setq val (plist-get (cadr cur) 'href)
rels nil))
)
(if val
(cons val "Search on (+ separates keywords): "))))
((eq w3-current-isindex t)
(cons (url-view-url t) "Search on (+ separates keywords): "))
((consp w3-current-isindex)
w3-current-isindex)
(t nil)))
index)
(if (null data) (error "Not a searchable index!"))
(setq index (car data))
(setq querystring (w3-nuke-spaces-in-search (read-string (cdr data))))
(if (string-match "\\(.*\\)\\?.*" index)
(setq index (url-match index 1)))
(w3-fetch
(concat index (if (= ?? (string-to-char (substring index -1 nil)))
"" "?") querystring))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Auto documentation, etc ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun w3-help ()
"Print documentation on w3 mode."
(interactive)
(w3-fetch "about:"))
;;;###autoload
(defun w3-version (&optional here)
"Show the version number of W3 in the minibuffer.
If optional argument HERE is non-nil, insert info at point."
(interactive "P")
(let ((version-string
(format "WWW %s, URL %s, MM %s"
w3-version-number
url-version
mm-version)))
(if here
(insert version-string)
(if (interactive-p)
(message "%s" version-string)
version-string))))
;;;###autoload
(defun w3 ()
"Retrieve the default World Wide Web home page.
The World Wide Web is a global hypertext system started by CERN in
Switzerland in 1991.
The home page is specified by the variable w3-default-homepage. The
document should be specified by its fully specified Uniform Resource
Locator. The document will be parsed as HTML (if appropriate) and
displayed in a new buffer."
(interactive)
(if (not w3-setup-done) (w3-do-setup))
(if (and w3-track-last-buffer
(bufferp w3-last-buffer)
(buffer-name w3-last-buffer))
(progn
(switch-to-buffer w3-last-buffer)
(message "Reusing buffer. To reload, type %s."
(substitute-command-keys "\\[w3-reload-document]")))
(cond
((null w3-default-homepage) (call-interactively 'w3-fetch))
((not (stringp w3-default-homepage))
(error "Invalid setting for w3-default-homepage: %S"
w3-default-homepage))
((not (string-match ".*:.*" w3-default-homepage))
(w3-fetch (concat "file:" w3-default-homepage)))
(t
(w3-fetch w3-default-homepage)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Leftover stuff that didn't quite fit into url.el
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun w3-generate-error (type data)
;; Generate an HTML error buffer for error TYPE with data DATA.
(setq url-current-mime-type "text/html")
(cond
((equal type "nofile")
(let ((error (save-excursion
(set-buffer (get-buffer-create " *url-error*"))
(buffer-string))))
(if (string= "" error)
(setq error
(format (concat "The file %s could not be found. "
"Either it does not exist, or it "
"is unreadable.") data)))
(insert "<html>\n <head>\n"
" <title>Error</title>\n"
" </head>\n <body>\n"
" <h1>Error accessing " data "</h1>\n"
" <hr>\n <p>"
error
"\n </p>\n")))
((equal type "nobuf")
(insert "<title>Error</title>\n"
"<H1>No buffer " data " found</h1>\n"
"<HR>\n"
"The buffer " data " could not be found. It has either\n"
"been killed or renamed.\n"))
((equal type "nohist")
(insert "<TITLE>Error</TITLE>\n"
"<H1>No history items found.</H1>\n"
"<HR>\n"
"There is no history list available at this time. Either\n"
"you have not visited any nodes, or the variable <i>\n"
"url-keep-history</i> is nil.\n"))
)
(insert "<hr>\n"
"If you feel this is a bug in Emacs-W3, <a href=\"mailto:"
w3-bug-address "\">send mail to " w3-bug-address
"</a>\n<hr>"))
(defun w3-generate-auto-html (type)
;; Generate one of several automatic html pages
(setq url-current-mime-type "text/html"
url-current-mime-headers '(("content-type" . "text/html")))
(cond
((equal type "hotlist")
(let ((tmp (reverse w3-hotlist)))
(insert "<html>\n\t<head>\n\t\t"
"<title> Hotlist </title>\n\t</head>\n"
"\t<body>\n\t\t<div>\n\t\t\t<h1>Hotlist from " w3-hotlist-file
"</h1>\n\t\t\t<ol>\n")
(while tmp
(insert "\t\t\t\t<li> <a href=\"" (car (cdr (car tmp)))
"\">" (url-insert-entities-in-string
(car (car tmp))) "</a></li>\n")
(setq tmp (cdr tmp)))
(insert "\n\t\t\t</ol>\n\t\t</div>\n\t</body>\n</html>\n")))
((equal type "history")
(if (not url-history-list)
(url-retrieve "www://error/nohist")
(insert "<html>\n\t<head>\n\t\t"
"<title> History List For This Session of W3</title>"
"\n\t</head>\n\t<body>\n\t\t<div>\n\t\t\t<h1>"
"History List For This Session of W3</h1>\n\t\t\t<ol>\n")
(cl-maphash
(function
(lambda (url desc)
(insert (format "\t\t\t\t<li> <a href=\"%s\">%s</a>\n"
url (url-insert-entities-in-string desc)))))
url-history-list)
(insert "\n\t\t\t</ol>\n\t\t</div>\n\t</body>\n</html>\n")))))
(defun w3-internal-handle-preview (buffer)
(setq buffer (get-buffer buffer))
(let ((base (get-text-property (point-min) 'w3-base buffer)))
(if base
(setq base (url-generic-parse-url base)))
(insert-buffer buffer)
(let ((inhibit-read-only t))
(set-text-properties (point-min) (point-max) nil))
(cond
(base
(setq url-current-object base))
((buffer-file-name buffer)
(setq url-current-object
(url-generic-parse-url (concat "file:"
(buffer-file-name buffer)))))
(t
(setq url-current-object
(url-generic-parse-url "file:/")
url-current-mime-type "text/html")))))
(defun w3-internal-url (url)
;; Handle internal urls (previewed buffers, etc)
(if (not (string-match "www:/+\\([^/]+\\)/\\(.*\\)" url))
(w3-fetch "www://error/")
(let ((type (url-match url 1))
(data (url-match url 2)))
(set-buffer (get-buffer-create url-working-buffer))
(cond
((equal type "preview") ; Previewing a document
(if (get-buffer data) ; Buffer still exists
(w3-internal-handle-preview data)
(url-retrieve (concat "www://error/nobuf/" data))))
((equal type "error") ; Error message
(if (string-match "\\([^/]+\\)/\\(.*\\)" data)
(w3-generate-error (url-match data 1) (url-match data 2))
(w3-generate-error data "")))
((equal type "auto") ; Hotlist or help stuff
(w3-generate-auto-html data))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Stuff for good local file handling
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun w3-ff (file)
"Find a file in any window already displaying it, otherwise just as
display-buffer, and using this function"
(if (not (eq 'tty (device-type)))
(let ((f (window-frame (display-buffer (find-file-noselect file)))))
(set-mouse-position f 1 0)
(raise-frame f)
(unfocus-frame))
(display-buffer (find-file-noselect file))))
(defun w3-default-local-file()
"Use find-file to open the local file"
(w3-ff (url-filename url-current-object)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Mode definition ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun w3-search-forward (string)
(interactive "sSearch: ")
(setq w3-last-search-item string)
(if (and (not (search-forward string nil t))
(funcall url-confirmation-func
"End of document reached; continue from beginning? "))
(progn
(goto-char (point-min))
(w3-search-forward string))))
(defun w3-search-again ()
(interactive)
(if (and w3-last-search-item
(stringp w3-last-search-item))
(if (and (not (search-forward w3-last-search-item nil t))
(funcall url-confirmation-func
"End of document reached; continue from beginning? "))
(progn
(goto-char (point-min))
(w3-search-again)))))
(defun w3-find-specific-link (link)
(let ((pos (assq (intern link) w3-id-positions)))
(if pos
(progn
(goto-char (cdr pos))
(if (and (eolp) (not (eobp)))
(forward-char 1)))
(message "Link #%s not found." link))))
(defun w3-force-reload-document ()
"Reload the current document. Take it from the network, even if
cached and in local mode."
(let ((url-standalone-mode nil))
(w3-reload-document)))
(defun w3-reload-document ()
"Reload the current document"
(interactive)
(let ((tmp (url-view-url t))
(pnt (point))
(window-start (progn
(move-to-window-line 0)
(point)))
(url-request-extra-headers '(("Pragma" . "no-cache"))))
(kill-buffer (current-buffer))
(w3-fetch tmp)
(goto-char pnt)
(set-window-start (selected-window) (min window-start (point-max)))))
(defun w3-leave-buffer ()
"Bury this buffer, but don't kill it."
(interactive)
(let ((x w3-current-last-buffer))
(if w3-frame-name
(w3-leave-or-quit-frameset x nil)
(progn
(bury-buffer nil)
(if (and (bufferp x) (buffer-name x))
(w3-notify-when-ready x))))))
(defun w3-quit (&optional mega)
"Quit WWW mode"
(interactive "P")
(if mega
(mapcar
(function
(lambda (x)
(save-excursion
(set-buffer (get-buffer x))
(if (eq major-mode 'w3-mode)
(w3-quit nil)))))
(buffer-list))
(let ((x w3-current-last-buffer))
(if w3-frame-name
(w3-leave-or-quit-frameset x t)
(progn
(kill-buffer (current-buffer))
(if (and (bufferp x) (buffer-name x))
(w3-notify-when-ready x)))))))
(defun w3-leave-or-quit-frameset (x quit-p &optional top-down-p)
(set-buffer x)
(delete-other-windows)
(let ((structure (reverse w3-frameset-structure)))
(while structure
(let ((elt (car structure)))
(if (eq (car elt) 'frame)
(let* ((url (nth 2 elt))
(buf (url-buffer-visiting url)))
(if buf
(progn
(set-buffer buf)
(if w3-frameset-structure
(w3-leave-or-quit-frameset buf quit-p t)
(if quit-p
(kill-buffer buf)
(bury-buffer buf))))))))
(pop structure)))
(if top-down-p
(if quit-p
(kill-buffer x)
(bury-buffer x))
(progn
(set-buffer x)
(if quit-p
(w3-quit nil)
(w3-leave-buffer)))))
(defun w3-view-this-url (&optional no-show)
"View the URL of the link under point"
(interactive)
(let* ((widget (widget-at (point)))
(parent (and widget (widget-get widget :parent)))
(href (or (and widget (widget-get widget :href))
(and parent (widget-get parent :href)))))
(cond
((and no-show href)
href)
(href
(message "%s" (url-truncate-url-for-viewing href)))
(no-show
nil)
(widget
(widget-echo-help (point)))
(t
nil))))
(defun w3-load-delayed-images ()
"Load inlined images that were delayed, if any."
(interactive)
(let ((w3-delay-image-loads nil)
(todo w3-delayed-images))
(setq w3-delayed-images nil)
(while todo
(w3-maybe-start-image-download (car todo))
(setq todo (cdr todo)))))
(defun w3-save-this-url ()
"Save url under point in the kill ring"
(interactive)
(w3-save-url t))
(defun w3-save-url (under-pt)
"Save current url in the kill ring"
(interactive "P")
(let ((x (cond
((stringp under-pt) under-pt)
(under-pt (w3-view-this-url t))
(t (url-view-url t)))))
(if x
(progn
(setq kill-ring (cons x kill-ring))
(setq kill-ring-yank-pointer kill-ring)
(message "Stored URL in kill-ring.")
(if (fboundp 'w3-store-in-clipboard)
(w3-store-in-clipboard x)))
(error "No URL to store."))))
(fset 'w3-end-of-document 'end-of-buffer)
(fset 'w3-start-of-document 'beginning-of-buffer)
(defun w3-scroll-up (&optional lines)
"Scroll forward in View mode, or exit if end of text is visible.
No arg means whole window full. Arg is number of lines to scroll."
(interactive "P")
(if (and (pos-visible-in-window-p (point-max))
;; Allow scrolling backward at the end of the buffer.
(or (null lines)
(> lines 0)))
nil
(let ((view-lines (1- (window-height))))
(setq lines
(if lines (prefix-numeric-value lines)
view-lines))
(if (>= lines view-lines)
(scroll-up nil)
(if (>= (- lines) view-lines)
(scroll-down nil)
(scroll-up lines)))
(cond ((pos-visible-in-window-p (point-max))
(goto-char (point-max))
(recenter -1)))
(move-to-window-line -1)
(beginning-of-line))))
(defun w3-mail-document-author ()
"Send mail to the author of this document, if possible."
(interactive)
(let ((x w3-current-links)
(y nil)
(found nil))
(setq found (cdr-safe (assoc "reply-to" url-current-mime-headers)))
(if (and found (not (string-match url-nonrelative-link found)))
(setq found (list (concat "mailto:" found))))
(while (and x (not found))
(setq y (car x)
x (cdr x)
found (cdr-safe (assoc "made" y))))
(if found
(let ((possible nil)
(href nil))
(setq x (car found)) ; Fallback if no mail(to|server) found
(while found
(setq href (plist-get (pop found) 'href))
(if (and href (string-match "^mail[^:]+:" href))
(setq possible (cons href possible))))
(case (length possible)
(0 ; No mailto links found
(w3-fetch x)) ; fall back onto first 'made' link
(1 ; Only one found, get it
(w3-fetch (car possible)))
(otherwise
(w3-fetch (completing-read "Choose an address: "
(mapcar 'list possible)
nil t (car possible))))))
(message "Could not automatically determine authors address, sorry."))))
(defun w3-kill-emacs-func ()
"Routine called when exiting emacs. Do miscellaneous clean up."
(and (eq url-keep-history t)
url-global-history-hash-table
(url-write-global-history))
(message "Cleaning up w3 storage...")
(let ((x (nconc
(and (file-exists-p w3-temporary-directory)
(directory-files w3-temporary-directory t "url-tmp.*"))
(and (file-exists-p url-temporary-directory)
(directory-files url-temporary-directory t
(concat "url"
(int-to-string
(user-real-uid)) ".*")))
(and (file-exists-p url-temporary-directory)
(directory-files url-temporary-directory t "url-tmp.*")))))
(while x
(condition-case ()
(delete-file (car x))
(error nil))
(setq x (cdr x))))
(message "Cleaning up w3 storage... done."))
(cond
((fboundp 'display-warning)
(fset 'w3-warn 'display-warning))
((fboundp 'warn)
(defun w3-warn (class message &optional level)
(if (and (eq class 'html)
(not w3-debug-html))
nil
(warn "(%s/%s) %s" class (or level 'warning) message))))
(t
(defun w3-warn (class message &optional level)
(if (and (eq class 'html)
(not w3-debug-html))
nil
(save-excursion
(set-buffer (get-buffer-create "*W3-WARNINGS*"))
(goto-char (point-max))
(save-excursion
(insert (format "(%s/%s) %s\n" class (or level 'warning) message)))
(display-buffer (current-buffer)))))))
(defun w3-internal-expander (urlobj defobj)
;; URL Expansion routine for internally handled routines
(url-identity-expander urlobj defobj))
(defun w3-map-links (function &optional buffer from to maparg)
"Map FUNCTION over the hypertext links which overlap region in BUFFER,
starting at FROM and ending at TO. FUNCTION is called with the arguments
WIDGET and MAPARG.
The arguments FROM, TO, MAPARG, and BUFFER default to the beginning of
BUFFER, the end of BUFFER, nil, and (current-buffer), respectively."
(let ((parent)
(highly-unlikely-name-for-a-variable-holding-a-function function))
(widget-map-buttons
(function
(lambda (widget arg)
(setq parent (and widget (widget-get widget :parent)))
;; Check to see if its got a URL tacked on it somewhere
(cond
((and widget (widget-get widget :href))
(funcall highly-unlikely-name-for-a-variable-holding-a-function
widget maparg))
((and parent (widget-get parent :href))
(funcall highly-unlikely-name-for-a-variable-holding-a-function
widget maparg))
(t nil))
nil)))))
(defun w3-emit-image-warnings-if-necessary ()
(if (and (not w3-delay-image-loads)
(fboundp 'w3-insert-graphic)
(or (not (featurep 'gif))
(not (featurep 'jpeg)))
(not (w3-executable-exists-in-path "ppmtoxpm"))
(not (or
(w3-executable-exists-in-path "pbmtoxbm")
(w3-executable-exists-in-path "ppmtoxbm"))))
(w3-warn
'image
(concat
"Could not find some vital ppm utilities in exec-path.\n"
"This probably means that you will be unable to view any\n"
"inlined images other than: "
(mapconcat
(function
(lambda (x)
(if (featurep x) (concat (symbol-name x) ",\n"))))
'(png jpg gif xpm xbm) "")
"\n\n"
"If you do not have the PPM utilities from either the PBMPLUS\n"
"or NETPBM distributions installed on your machine, then\n"
"please set the variable `w3-delay-image-loads' to t with a\n"
"line like:\n\n"
"\t(setq w3-delay-image-loads t)\n\n"
"in your ~/.emacs file.\n\n"
"You can find the NETPBM utilities in:\n"
"\tftp://ftp.cs.indiana.edu/pub/elisp/w3/images/\n"
))))
(defun w3-refresh-stylesheets ()
"Reload all stylesheets."
(interactive)
(setq w3-user-stylesheet nil
w3-face-cache nil)
(w3-find-default-stylesheets)
)
(defvar w3-loaded-stylesheets nil
"A list of all the stylesheets Emacs-W3 loaded at startup.")
(defun w3-find-default-stylesheets ()
(setq w3-loaded-stylesheets nil)
(let* ((lightp (css-color-light-p 'default))
(longname (if lightp "stylesheet-light" "stylesheet-dark"))
(shortname (if lightp "light.css" "dark.css"))
(w3-lisp (file-name-directory (locate-library "w3")))
(w3-root (expand-file-name "../.." w3-lisp))
(no-user-init (= 0 (length user-init-file)))
(w3-configuration-directory (if no-user-init
"/this/is/a/highly/unlikely/directory/name"
w3-configuration-directory))
(directories (list
(if (fboundp 'locate-data-directory)
(locate-data-directory "w3"))
data-directory
(concat data-directory "w3/")
(expand-file-name "../../w3" data-directory)
w3-lisp
w3-root
(expand-file-name "w3" w3-root)
(expand-file-name "etc" w3-root)
(expand-file-name "etc/w3" w3-root)
(expand-file-name "../" w3-lisp)
(expand-file-name "../w3" w3-lisp)
(expand-file-name "../etc" w3-lisp)
w3-configuration-directory))
(total-found 0)
(possible (append
(apply
'append
(mapcar
(function
(lambda (dir)
(list
(expand-file-name shortname dir)
(expand-file-name longname dir)
(expand-file-name "stylesheet" dir)
(expand-file-name "default.css" dir))))
directories))
(and (not no-user-init)
(list w3-default-stylesheet))))
(remember possible)
(old-asynch (default-value 'url-be-asynchronous))
(found nil)
(cur nil)
(url nil))
(unwind-protect
(progn
(setq-default url-be-asynchronous nil)
(while possible
(setq cur (car possible)
possible (cdr possible)
found (and cur (file-exists-p cur) (file-readable-p cur)
(not (file-directory-p cur)) cur))
(if found
(setq total-found (1+ total-found)
w3-loaded-stylesheets (cons cur w3-loaded-stylesheets)
w3-user-stylesheet (css-parse (concat "file:" cur) nil
w3-user-stylesheet)))))
(setq-default url-be-asynchronous old-asynch))
(if (= 0 total-found)
(progn
(w3-warn
'style
(concat
"No stylesheets found! Check configuration! DANGER DANGER!\n"
"Emacs-W3 checked for its stylesheet in the following places\n"
"and did not find one. This means that some formatting will\n"
"be wrong, and most colors and fonts will not be set up correctly.\n"
"------\n"
(mapconcat 'identity remember "\n")
"------"))
(error "No stylesheets found! Check configuration! DANGER DANGER!")))))
(defvar w3-widget-global-map nil)
;;;###autoload
(defun w3-do-setup ()
"Do setup - this is to avoid conflict with user settings when W3 is
dumped with emacs."
(url-do-setup)
(url-register-protocol 'about 'w3-about 'url-identity-expander)
(url-register-protocol 'www 'w3-internal-url 'w3-internal-expander)
(w3-load-flavors)
(w3-setup-version-specifics)
(setq w3-default-configuration-file (expand-file-name
(or w3-default-configuration-file
"profile")
w3-configuration-directory))
(if (and init-file-user
w3-default-configuration-file
(file-exists-p w3-default-configuration-file))
(condition-case e
(load w3-default-configuration-file nil t)
(error
(let ((buf-name " *Configuration Error*"))
(if (get-buffer buf-name)
(kill-buffer (get-buffer buf-name)))
(display-error e (get-buffer-create buf-name))
(save-excursion
(switch-to-buffer-other-window buf-name)
(shrink-window-if-larger-than-buffer))
(w3-warn 'configuration
(format (eval-when-compile
(concat
"Configuration file `%s' contains an error.\n"
"Please consult the `%s' buffer for details."))
w3-default-configuration-file buf-name))))))
(if (and (eq w3-user-colors-take-precedence 'guess)
(not (eq (device-type) 'tty))
(not (eq (device-class) 'mono)))
(progn
(setq w3-user-colors-take-precedence t)
(w3-warn
'html
"Disabled document color specification because of mono display.")))
(w3-refresh-stylesheets)
(setq w3-setup-done t)
(if (not url-global-history-file)
(setq url-global-history-file
(expand-file-name "history"
w3-configuration-directory)))
(add-minor-mode 'w3-netscape-emulation-minor-mode " NS"
w3-netscape-emulation-minor-mode-map)
(add-minor-mode 'w3-lynx-emulation-minor-mode " Lynx"
w3-lynx-emulation-minor-mode-map)
(setq url-package-version w3-version-number
url-package-name "Emacs-W3")
(w3-setup-terminal-chars)
(w3-emit-image-warnings-if-necessary)
(cond
((memq system-type '(ms-dos ms-windows))
(setq w3-hotlist-file (or w3-hotlist-file
(expand-file-name "~/mosaic.hot"))
))
((memq system-type '(axp-vms vax-vms))
(setq w3-hotlist-file (or w3-hotlist-file
(expand-file-name "~/mosaic.hotlist-default"))
))
(t
(setq w3-hotlist-file (or w3-hotlist-file
(expand-file-name "~/.mosaic-hotlist-default"))
)))
; Set up a hook that will save the history list when
; exiting emacs
(add-hook 'kill-emacs-hook 'w3-kill-emacs-func)
(mm-parse-mailcaps)
(mm-parse-mimetypes)
; Load in the hotlist if they haven't set it already
(or w3-hotlist (w3-parse-hotlist))
; Set the default home page, honoring their defaults, then
; the standard WWW_HOME, then default to the documentation @ IU
(or w3-default-homepage
(setq w3-default-homepage
(or (getenv "WWW_HOME")
"http://www.cs.indiana.edu/elisp/w3/docs.html")))
(run-hooks 'w3-load-hook))
(defun w3-mark-link-as-followed (ext dat)
;; Mark a link as followed
(message "Reimplement w3-mark-link-as-followed"))
(defun w3-only-links ()
(let* (result temp)
(w3-map-links (function
(lambda (x y)
(setq result (cons x result)))))
result))
(defun w3-download-callback (fname buff)
(if (and (get-buffer buff) (buffer-name buff))
(save-excursion
(set-buffer buff)
(let ((require-final-newline nil)
(file-name-handler-alist nil)
(write-file-hooks nil)
(write-contents-hooks nil)
(enable-multibyte-characters t) ; mule 2.4
(buffer-file-coding-system mule-no-coding-system) ; mule 2.4
(file-coding-system mule-no-coding-system) ; mule 2.3
(mc-flag t)) ; mule 2.3
(write-file fname)
(message "Download of %s complete." (url-view-url t))
(sit-for 3)
(kill-buffer buff)))))
(defun w3-download-url-at-point ()
"Download the URL under point."
(interactive)
(w3-download-url-wrapper t))
(defun w3-download-this-url ()
"Download the current URL."
(interactive)
(w3-download-url-wrapper nil))
(defun w3-download-url-wrapper (under-pt)
"Download current URL."
(let ((x (if under-pt (w3-view-this-url t) (url-view-url t))))
(if x
(w3-download-url x)
(error "No link found."))))
(defun w3-download-url (url &optional file-name)
(interactive (list (w3-read-url-with-default)))
(let* ((old-asynch (default-value 'url-be-asynchronous))
(url-inhibit-uncompression t)
(url-mime-accept-string "*/*")
(urlobj (url-generic-parse-url url))
(url-working-buffer
(generate-new-buffer (concat " *" url " download*")))
(stub-fname (url-basepath (or (url-filename urlobj) "") t))
(dir (or mm-download-directory "~/"))
(fname (or file-name
(expand-file-name
(read-file-name "Filename to save as: "
dir
stub-fname
nil
stub-fname) dir))))
(unwind-protect
(progn
(or file-name
(setq-default url-be-asynchronous t))
(save-excursion
(set-buffer url-working-buffer)
(or file-name
(setq url-current-callback-data (list fname (current-buffer))
url-be-asynchronous t
url-current-callback-func 'w3-download-callback))
(url-retrieve url)
(and file-name
(w3-download-callback fname (current-buffer) t))))
(or file-name
(setq-default url-be-asynchronous old-asynch)))))
;;;###autoload
(defun w3-follow-link-other-frame (&optional p)
"Attempt to follow the hypertext reference under point in a new frame.
With prefix-arg P, ignore viewers and dump the link straight
to disk."
(cond
((and (fboundp 'make-frame)
(fboundp 'select-frame))
(let ((frm (make-frame)))
(select-frame frm)
(w3-follow-link p)))
(t (w3-follow-link p))))
;;;###autoload
(defun w3-follow-link (&optional p)
"Attempt to follow the hypertext reference under point.
With prefix-arg P, ignore viewers and dump the link straight
to disk."
(interactive "P")
(let* ((widget (widget-at (point)))
(href (and widget (widget-get widget :href))))
(cond
((null href) nil)
((or p w3-dump-to-disk)
(w3-download-url href))
(t
(w3-fetch href)))))
(defun w3-widget-forward (arg)
"Move point to the next field or button.
With optional ARG, move across that many fields."
(interactive "p")
(widget-forward arg))
(defun w3-widget-backward (arg)
"Move point to the previous field or button.
With optional ARG, move across that many fields."
(interactive "p")
(w3-widget-forward (- arg)))
(defun w3-complete-link ()
"Choose a link from the current buffer and follow it"
(interactive)
(let (links-alist
link-at-point
choice
(completion-ignore-case t))
(setq link-at-point (widget-at (point))
link-at-point (and
link-at-point
(widget-get link-at-point :href)
(widget-get link-at-point :from)
(widget-get link-at-point :to)
(w3-fix-spaces
(buffer-substring-no-properties
(widget-get link-at-point :from)
(widget-get link-at-point :to)))))
(w3-map-links (function
(lambda (widget arg)
(if (and (widget-get widget :from)
(widget-get widget :to))
(setq links-alist (cons
(cons
(w3-fix-spaces
(buffer-substring-no-properties
(widget-get widget :from)
(widget-get widget :to)))
(widget-get widget :href))
links-alist))))))
(if (not links-alist) (error "No links in current document."))
(setq links-alist (sort links-alist (function
(lambda (x y)
(string< (car x) (car y))))))
;; Destructively remove duplicate entries from links-alist.
(let ((remaining-links links-alist))
(while remaining-links
(if (equal (car remaining-links) (car (cdr remaining-links)))
(setcdr remaining-links (cdr (cdr remaining-links)))
(setq remaining-links (cdr remaining-links)))))
(setq choice (completing-read
(if link-at-point
(concat "Link (default "
(if (< (length link-at-point) 20)
link-at-point
(concat
(substring link-at-point 0 17) "..."))
"): ")
"Link: ") links-alist nil t))
(if (and (string= choice "") link-at-point)
(setq choice link-at-point))
(let ((match (try-completion choice links-alist)))
(cond
((eq t match) ; We have an exact match
(setq choice (cdr (assoc choice links-alist))))
((stringp match)
(setq choice (cdr (assoc match links-alist))))
(t (setq choice nil)))
(if choice
(w3-fetch choice)))))
(defun w3-display-errors ()
"Display any HTML errors for the current page."
(interactive)
(let ((w3-notify 'friendly)
(inhibit-read-only t)
(buffer nil)
(todo w3-current-badhtml)
(url (url-view-url t)))
(if (not todo)
(error "No HTML errors on this page! Amazing, isn't it?"))
(save-excursion
(set-buffer
(get-buffer-create (concat "HTML Errors for: " (or url "???"))))
(setq buffer (current-buffer))
(erase-buffer)
(while todo
(goto-char (point-min))
(insert "\n" (car todo))
(setq todo (cdr todo)))
(if url
(progn
(goto-char (point-min))
(insert (format "HTML Errors for: <URL:%s>\n" url))))
(set (make-local-variable 'font-lock-keywords) w3-html-errors-font-lock-keywords)
(set (make-local-variable 'font-lock-keywords-only) nil)
(set (make-local-variable 'font-lock-keywords-case-fold-search) nil)
(set (make-local-variable 'font-lock-syntax-table) nil)
(set (make-local-variable 'font-lock-beginning-of-syntax-function) 'beginning-of-line)
(run-hooks 'w3-display-errors-hook))
(w3-notify-when-ready buffer)))
(defun w3-mode ()
"Mode for viewing HTML documents. If called interactively, will
display the current buffer as HTML.
Current keymap is:
\\{w3-mode-map}"
(interactive)
(or w3-setup-done (w3-do-setup))
(if (interactive-p)
(w3-preview-this-buffer)
(let ((tmp (mapcar (function (lambda (x) (cons x (symbol-value x))))
w3-persistent-variables)))
;; Oh gross, this kills buffer-local faces in XEmacs
;;(kill-all-local-variables)
(use-local-map w3-mode-map)
(setq mode-name "WWW")
(mapcar (function (lambda (x) (set-variable (car x) (cdr x)))) tmp)
(setq major-mode 'w3-mode)
(w3-mode-version-specifics)
(w3-menu-install-menus)
(setq url-current-passwd-count 0
truncate-lines t
mode-line-format w3-modeline-format)
(run-hooks 'w3-mode-hook)
(widget-setup))))
(require 'mm)
(require 'url)
(require 'w3-parse)
(require 'w3-display)
(require 'w3-auto)
(require 'w3-emulate)
(require 'w3-menu)
(require 'w3-mouse)
(provide 'w3)
|