|
|
1.1 ! root 1: /* ! 2: * t6.c ! 3: * ! 4: * width functions, sizes and fonts ! 5: */ ! 6: ! 7: #include "tdef.h" ! 8: #include "dev.h" ! 9: #include <ctype.h> ! 10: #include "ext.h" ! 11: ! 12: /* ! 13: fitab[f][c] is 0 if c is not on font f ! 14: if it's non-zero, c is in fontab[f] at position fitab[f][c]. ! 15: */ ! 16: extern struct Font *fontbase[NFONT+1]; ! 17: extern char *codetab[NFONT+1]; ! 18: extern int nchtab; ! 19: ! 20: int fontlab[NFONT+1]; ! 21: short *pstab; ! 22: int cstab[NFONT+1]; ! 23: int ccstab[NFONT+1]; ! 24: int bdtab[NFONT+1]; ! 25: int sbold = 0; ! 26: ! 27: width(j) ! 28: register tchar j; ! 29: { ! 30: register i, k; ! 31: ! 32: if (j & (ZBIT|MOT)) { ! 33: if (iszbit(j)) ! 34: return(0); ! 35: if (isvmot(j)) ! 36: return(0); ! 37: k = absmot(j); ! 38: if (isnmot(j)) ! 39: k = -k; ! 40: return(k); ! 41: } ! 42: i = cbits(j); ! 43: if (i < 32) { ! 44: if (i == '\b') ! 45: return(-widthp); ! 46: if (i == PRESC) ! 47: i = eschar; ! 48: else if (iscontrol(i)) ! 49: return(0); ! 50: } ! 51: if (i == ohc) ! 52: return(0); ! 53: i = trtab[i] - 32; /* fails for \N */ ! 54: if (i < 0) ! 55: return(0); ! 56: if (sfbits(j) == oldbits) { ! 57: xfont = pfont; ! 58: xpts = ppts; ! 59: } else ! 60: xbits(j, 0); ! 61: if (i < nchtab + 128-32 && widcache[i].fontpts == (xfont<<8) + xpts && !setwdf) ! 62: k = widcache[i].width; ! 63: else { ! 64: k = getcw(i); ! 65: if (bd) ! 66: k += (bd - 1) * HOR; ! 67: if (cs) ! 68: k = cs; ! 69: } ! 70: widthp = k; ! 71: return(k); ! 72: } ! 73: ! 74: /* ! 75: * clear width cache-- s means just space ! 76: */ ! 77: zapwcache(s) ! 78: { ! 79: register i; ! 80: ! 81: if (s) { ! 82: widcache[0].fontpts = 0; ! 83: return; ! 84: } ! 85: for (i=0; i<NWIDCACHE; i++) ! 86: widcache[i].fontpts = 0; ! 87: } ! 88: ! 89: getcw(i) ! 90: register int i; ! 91: { ! 92: register int k; ! 93: register char *p; ! 94: register int x, j; ! 95: int nocache = 0; ! 96: ! 97: bd = 0; ! 98: if (i >= nchtab + 128-32) { ! 99: j = abscw(i + 32 - (nchtab+128)); ! 100: goto g0; ! 101: } ! 102: if (i == 0) { /* a blank */ ! 103: k = (fontab[xfont][0] * spacesz + 6) / 12; ! 104: /* this nonsense because .ss cmd uses 1/36 em as its units */ ! 105: /* and default is 12 */ ! 106: goto g1; ! 107: } ! 108: if ((j = fitab[xfont][i] & BYTEMASK) == 0) { /* it's not on current font */ ! 109: /* search through search list of xfont ! 110: /* to see what font it ought to be on. ! 111: /* searches S, then remaining fonts in wraparound order. ! 112: */ ! 113: nocache = 1; ! 114: if (smnt) { ! 115: int ii, jj; ! 116: for (ii=smnt, jj=0; jj < nfonts; jj++, ii=ii % nfonts + 1) { ! 117: j = fitab[ii][i] & BYTEMASK; ! 118: if (j != 0) { ! 119: p = fontab[ii]; ! 120: k = *(p + j); ! 121: if (xfont == sbold) ! 122: bd = bdtab[ii]; ! 123: if (setwdf) ! 124: numtab[CT].val |= kerntab[ii][j]; ! 125: goto g1; ! 126: } ! 127: } ! 128: } ! 129: k = fontab[xfont][0]; /* leave a space-size space */ ! 130: goto g1; ! 131: } ! 132: g0: ! 133: p = fontab[xfont]; ! 134: if (setwdf) ! 135: numtab[CT].val |= kerntab[xfont][j]; ! 136: k = *(p + j); ! 137: g1: ! 138: if (!bd) ! 139: bd = bdtab[xfont]; ! 140: if (cs = cstab[xfont]) { ! 141: nocache = 1; ! 142: if (ccs = ccstab[xfont]) ! 143: x = ccs; ! 144: else ! 145: x = xpts; ! 146: cs = (cs * EMPTS(x)) / 36; ! 147: } ! 148: k = ((k&BYTEMASK) * xpts + (Unitwidth / 2)) / Unitwidth; ! 149: if (nocache|bd) ! 150: widcache[i].fontpts = 0; ! 151: else { ! 152: widcache[i].fontpts = (xfont<<8) + xpts; ! 153: widcache[i].width = k; ! 154: } ! 155: return(k); ! 156: /* Unitwidth is Units/Point, where ! 157: /* Units is the fundamental digitization ! 158: /* of the character set widths, and ! 159: /* Point is the number of goobies in a point ! 160: /* e.g., for cat, Units=36, Point=6, so Unitwidth=36/6=6 ! 161: /* In effect, it's the size at which the widths ! 162: /* translate directly into units. ! 163: */ ! 164: } ! 165: ! 166: abscw(n) /* return index of abs char n in fontab[], etc. */ ! 167: { register int i, ncf; ! 168: ! 169: ncf = fontbase[xfont]->nwfont & BYTEMASK; ! 170: for (i = 0; i < ncf; i++) ! 171: if (codetab[xfont][i] == n) ! 172: return i; ! 173: return 0; ! 174: } ! 175: ! 176: xbits(i, bitf) ! 177: register tchar i; ! 178: { ! 179: register k; ! 180: ! 181: xfont = fbits(i); ! 182: k = sbits(i); ! 183: if (k) { ! 184: xpts = pstab[--k]; ! 185: oldbits = sfbits(i); ! 186: pfont = xfont; ! 187: ppts = xpts; ! 188: return; ! 189: } ! 190: switch (bitf) { ! 191: case 0: ! 192: xfont = font; ! 193: xpts = pts; ! 194: break; ! 195: case 1: ! 196: xfont = pfont; ! 197: xpts = ppts; ! 198: break; ! 199: case 2: ! 200: xfont = mfont; ! 201: xpts = mpts; ! 202: } ! 203: } ! 204: ! 205: ! 206: tchar setch(c) ! 207: { ! 208: register j; ! 209: char temp[50]; ! 210: register char *s; ! 211: extern char *chname; ! 212: extern short *chtab; ! 213: ! 214: s = temp; ! 215: if (c == '(') { /* \(xx */ ! 216: if ((*s++ = getach()) == 0 || (*s++ = getach()) == 0) ! 217: return(0); ! 218: } else { /* \C'...' */ ! 219: c = getach(); ! 220: while ((*s = getach()) != c && *s != 0 && s < temp + sizeof(temp) - 1) ! 221: s++; ! 222: } ! 223: *s = '\0'; ! 224: for (j = 0; j < nchtab; j++) ! 225: if (strcmp(&chname[chtab[j]], temp) == 0) ! 226: return(j + 128 | chbits); ! 227: return(0); ! 228: } ! 229: ! 230: tchar setabs() /* set absolute char from \N'...' */ ! 231: { ! 232: int n; ! 233: ! 234: getch(); ! 235: n = 0; ! 236: n = inumb(&n); ! 237: getch(); ! 238: if (nonumb) ! 239: return 0; ! 240: if (n > (fontbase[xfont]->nwfont & BYTEMASK)) { ! 241: errprint("\\N'%d' toooo large", n); ! 242: return 0; ! 243: } ! 244: return n + nchtab + 128 | chbits; ! 245: } ! 246: ! 247: ! 248: findft(i) ! 249: register int i; ! 250: { ! 251: register int k, c0, c1; ! 252: ! 253: c0 = i & BYTEMASK; /* unPAIR: allows for 2-digit font numbers */ ! 254: c1 = (i >> BYTE) & BYTEMASK; ! 255: if (isdigit(c0)) { ! 256: if (c1 == 0) ! 257: k = c0 - '0'; ! 258: else if (isdigit(c1)) ! 259: k = 10 * (c0 - '0') + c1 - '0'; ! 260: else ! 261: k = -1; ! 262: if (k >= 0 && k <= nfonts && k < smnt) ! 263: return(k); ! 264: } ! 265: for (k = 0; fontlab[k] != i; k++) ! 266: if (k > nfonts) ! 267: return(-1); ! 268: return(k); ! 269: } ! 270: ! 271: ! 272: caseps() ! 273: { ! 274: register i; ! 275: ! 276: if (skip()) ! 277: i = apts1; ! 278: else { ! 279: noscale++; ! 280: i = inumb(&apts); /* this is a disaster for fractional point sizes */ ! 281: noscale = 0; ! 282: if (nonumb) ! 283: return; ! 284: } ! 285: casps1(i); ! 286: } ! 287: ! 288: ! 289: casps1(i) ! 290: register int i; ! 291: { ! 292: ! 293: /* ! 294: * in olden times, it used to ignore changes to 0 or negative. ! 295: * this is meant to allow the requested size to be anything, ! 296: * in particular so eqn can generate lots of \s-3's and still ! 297: * get back by matching \s+3's. ! 298: ! 299: if (i <= 0) ! 300: return; ! 301: */ ! 302: apts1 = apts; ! 303: apts = i; ! 304: pts1 = pts; ! 305: pts = findps(i); ! 306: mchbits(); ! 307: } ! 308: ! 309: ! 310: findps(i) ! 311: register int i; ! 312: { ! 313: register j, k; ! 314: ! 315: for (j=k=0 ; pstab[j] != 0 ; j++) ! 316: if (abs(pstab[j]-i) < abs(pstab[k]-i)) ! 317: k = j; ! 318: ! 319: return(pstab[k]); ! 320: } ! 321: ! 322: ! 323: mchbits() ! 324: { ! 325: register i, j, k; ! 326: ! 327: i = pts; ! 328: for (j = 0; i > (k = pstab[j]); j++) ! 329: if (!k) { ! 330: j--; ! 331: break; ! 332: } ! 333: chbits = 0; ! 334: setsbits(chbits, ++j); ! 335: setfbits(chbits, font); ! 336: sps = width(' ' | chbits); ! 337: zapwcache(1); ! 338: } ! 339: ! 340: setps() ! 341: { ! 342: register int i, j; ! 343: ! 344: i = cbits(getch()); ! 345: if (isdigit(i)) { /* \sd or \sdd */ ! 346: i -= '0'; ! 347: if (i == 0) /* \s0 */ ! 348: j = apts1; ! 349: else if (i <= 3 && isdigit(j = cbits(ch=getch()))) { /* \sdd */ ! 350: j = 10 * i + j - '0'; ! 351: ch = 0; ! 352: } else /* \sd */ ! 353: j = i; ! 354: } else if (i == '(') { /* \s(dd */ ! 355: j = cbits(getch()) - '0'; ! 356: j = 10 * j + cbits(getch()) - '0'; ! 357: if (j == 0) /* \s(00 */ ! 358: j = apts1; ! 359: } else if (i == '+' || i == '-') { /* \s+, \s- */ ! 360: j = cbits(getch()); ! 361: if (isdigit(j)) { /* \s+d, \s-d */ ! 362: j -= '0'; ! 363: } else if (j == '(') { /* \s+(dd, \s-(dd */ ! 364: j = cbits(getch()) - '0'; ! 365: j = 10 * j + cbits(getch()) - '0'; ! 366: } ! 367: if (i == '-') ! 368: j = -j; ! 369: j += apts; ! 370: } ! 371: casps1(j); ! 372: } ! 373: ! 374: ! 375: tchar setht() /* set character height from \H'...' */ ! 376: { ! 377: int n; ! 378: tchar c; ! 379: ! 380: getch(); ! 381: n = inumb(&apts); ! 382: getch(); ! 383: if (n == 0 || nonumb) ! 384: n = apts; /* does this work? */ ! 385: c = CHARHT; ! 386: c |= ZBIT; ! 387: setsbits(c, n); ! 388: return(c); ! 389: } ! 390: ! 391: tchar setslant() /* set slant from \S'...' */ ! 392: { ! 393: int n; ! 394: tchar c; ! 395: ! 396: getch(); ! 397: n = 0; ! 398: n = inumb(&n); ! 399: getch(); ! 400: if (nonumb) ! 401: n = 0; ! 402: c = SLANT; ! 403: c |= ZBIT; ! 404: setsfbits(c, n+180); ! 405: return(c); ! 406: } ! 407: ! 408: ! 409: caseft() ! 410: { ! 411: skip(); ! 412: setfont(1); ! 413: } ! 414: ! 415: ! 416: setfont(a) ! 417: int a; ! 418: { ! 419: register i, j; ! 420: ! 421: if (a) ! 422: i = getrq(); ! 423: else ! 424: i = getsn(); ! 425: if (!i || i == 'P') { ! 426: j = font1; ! 427: goto s0; ! 428: } ! 429: if (i == 'S' || i == '0') ! 430: return; ! 431: if ((j = findft(i)) == -1) ! 432: if ((j = setfp(0, i, (char*)0)) == -1) /* try to put it in position 0 */ ! 433: return; ! 434: s0: ! 435: font1 = font; ! 436: font = j; ! 437: mchbits(); ! 438: } ! 439: ! 440: ! 441: setwd() ! 442: { ! 443: register base, wid; ! 444: register tchar i; ! 445: int delim, emsz, k; ! 446: int savhp, savapts, savapts1, savfont, savfont1, savpts, savpts1; ! 447: ! 448: base = numtab[ST].val = numtab[ST].val = wid = numtab[CT].val = 0; ! 449: if (ismot(i = getch())) ! 450: return; ! 451: delim = cbits(i); ! 452: savhp = numtab[HP].val; ! 453: numtab[HP].val = 0; ! 454: savapts = apts; ! 455: savapts1 = apts1; ! 456: savfont = font; ! 457: savfont1 = font1; ! 458: savpts = pts; ! 459: savpts1 = pts1; ! 460: setwdf++; ! 461: while (cbits(i = getch()) != delim && !nlflg) { ! 462: k = width(i); ! 463: wid += k; ! 464: numtab[HP].val += k; ! 465: if (!ismot(i)) { ! 466: emsz = POINT * xpts; ! 467: } else if (isvmot(i)) { ! 468: k = absmot(i); ! 469: if (isnmot(i)) ! 470: k = -k; ! 471: base -= k; ! 472: emsz = 0; ! 473: } else ! 474: continue; ! 475: if (base < numtab[SB].val) ! 476: numtab[SB].val = base; ! 477: if ((k = base + emsz) > numtab[ST].val) ! 478: numtab[ST].val = k; ! 479: } ! 480: setn1(wid, 0, (tchar) 0); ! 481: numtab[HP].val = savhp; ! 482: apts = savapts; ! 483: apts1 = savapts1; ! 484: font = savfont; ! 485: font1 = savfont1; ! 486: pts = savpts; ! 487: pts1 = savpts1; ! 488: mchbits(); ! 489: setwdf = 0; ! 490: } ! 491: ! 492: ! 493: tchar vmot() ! 494: { ! 495: dfact = lss; ! 496: vflag++; ! 497: return(mot()); ! 498: } ! 499: ! 500: ! 501: tchar hmot() ! 502: { ! 503: dfact = EM; ! 504: return(mot()); ! 505: } ! 506: ! 507: ! 508: tchar mot() ! 509: { ! 510: register int j, n; ! 511: register tchar i; ! 512: ! 513: j = HOR; ! 514: getch(); /*eat delim*/ ! 515: if (n = atoi()) { ! 516: if (vflag) ! 517: j = VERT; ! 518: i = makem(quant(n, j)); ! 519: } else ! 520: i = 0; ! 521: getch(); ! 522: vflag = 0; ! 523: dfact = 1; ! 524: return(i); ! 525: } ! 526: ! 527: ! 528: tchar sethl(k) ! 529: int k; ! 530: { ! 531: register j; ! 532: tchar i; ! 533: ! 534: j = EM / 2; ! 535: if (k == 'u') ! 536: j = -j; ! 537: else if (k == 'r') ! 538: j = -2 * j; ! 539: vflag++; ! 540: i = makem(j); ! 541: vflag = 0; ! 542: return(i); ! 543: } ! 544: ! 545: ! 546: tchar makem(i) ! 547: register int i; ! 548: { ! 549: register tchar j; ! 550: ! 551: if ((j = i) < 0) ! 552: j = -j; ! 553: j |= MOT; ! 554: if (i < 0) ! 555: j |= NMOT; ! 556: if (vflag) ! 557: j |= VMOT; ! 558: return(j); ! 559: } ! 560: ! 561: ! 562: tchar getlg(i) ! 563: tchar i; ! 564: { ! 565: tchar j, k; ! 566: register int lf; ! 567: ! 568: if ((lf = fontbase[fbits(i)]->ligfont) == 0) /* font lacks ligatures */ ! 569: return(i); ! 570: j = getch0(); ! 571: if (cbits(j) == 'i' && (lf & LFI)) ! 572: j = LIG_FI; ! 573: else if (cbits(j) == 'l' && (lf & LFL)) ! 574: j = LIG_FL; ! 575: else if (cbits(j) == 'f' && (lf & LFF)) { ! 576: if ((lf & (LFFI|LFFL)) && lg != 2) { ! 577: k = getch0(); ! 578: if (cbits(k)=='i' && (lf&LFFI)) ! 579: j = LIG_FFI; ! 580: else if (cbits(k)=='l' && (lf&LFFL)) ! 581: j = LIG_FFL; ! 582: else { ! 583: *pbp++ = k; ! 584: j = LIG_FF; ! 585: } ! 586: } else ! 587: j = LIG_FF; ! 588: } else { ! 589: *pbp++ = j; ! 590: j = i; ! 591: } ! 592: return(i & SFMASK | j); ! 593: } ! 594: ! 595: ! 596: caselg() ! 597: { ! 598: ! 599: lg = 1; ! 600: if (skip()) ! 601: return; ! 602: lg = atoi(); ! 603: } ! 604: ! 605: ! 606: casefp() ! 607: { ! 608: register int i, j; ! 609: ! 610: skip(); ! 611: i = cbits(getch()); ! 612: if (isdigit(i)) { ! 613: i -= '0'; ! 614: j = cbits(getch()); ! 615: if (isdigit(j)) ! 616: i = 10 * i + j - '0'; ! 617: } ! 618: if (i <= 0 || i > nfonts) ! 619: errprint("fp: bad font position %d", i); ! 620: else if (skip() || !(j = getrq())) ! 621: errprint("fp: no font name"); ! 622: else if (skip() || !getname()) ! 623: setfp(i, j, (char*)0); ! 624: else /* 3rd argument = filename */ ! 625: setfp(i, j, nextf); ! 626: } ! 627: ! 628: setfp(pos, f, truename) /* mount font f at position pos[0...nfonts] */ ! 629: int pos, f; ! 630: char *truename; ! 631: { ! 632: register k; ! 633: int onw, nw; ! 634: char longname[NS], shortname[NS]; ! 635: ! 636: zapwcache(0); ! 637: if (truename) { ! 638: strcpy(shortname, truename); ! 639: } else { ! 640: shortname[0] = f & BYTEMASK; ! 641: shortname[1] = f >> BYTE; ! 642: shortname[2] = '\0'; ! 643: } ! 644: if (truename[0] == '/') /* full pathname -- use verbatim.out */ ! 645: sprintf(longname, "%s.out", truename); ! 646: else ! 647: sprintf(longname, "%s/dev%s/%s.out", fontdir, devname, shortname); ! 648: if ((k = open(longname, 0)) < 0) { ! 649: errprint("Can't open %s", longname); ! 650: return(-1); ! 651: } ! 652: onw = fontbase[pos]->nwfont & BYTEMASK; ! 653: read(k, (char *) fontbase[pos], 3*onw + nchtab + 128-32 + sizeof(struct Font)); ! 654: nw = fontbase[pos]->nwfont & BYTEMASK; ! 655: kerntab[pos] = (char *) fontab[pos] + nw; ! 656: codetab[pos] = (char *) fontab[pos] + 2 * nw; ! 657: /* have to reset the fitab pointer because the width may be different */ ! 658: fitab[pos] = (char *) fontab[pos] + 3 * nw; ! 659: if (nw > onw) { ! 660: errprint("Font %s too big for position %d", shortname, pos); ! 661: fontbase[pos]->nwfont = onw; ! 662: return(-1); ! 663: } ! 664: fontbase[pos]->nwfont = onw; /* so can load a larger one again later */ ! 665: close(k); ! 666: if (pos == smnt) { ! 667: smnt = 0; ! 668: sbold = 0; ! 669: } ! 670: if ((fontlab[pos] = f) == 'S') ! 671: smnt = pos; ! 672: bdtab[pos] = cstab[pos] = ccstab[pos] = 0; ! 673: /* if there is a directory, no place to store its name. */ ! 674: /* if position isn't zero, no place to store its value. */ ! 675: /* only time a FONTPOS is pushed back is if it's a */ ! 676: /* standard font on position 0 (i.e., mounted implicitly. */ ! 677: /* there's a bug here: if there are several input lines */ ! 678: /* that look like .ft XX in short successtion, the output */ ! 679: /* will all be in the last one because the "x font ..." */ ! 680: /* comes out too soon. pushing back FONTPOS doesn't work */ ! 681: /* with .ft commands because input is flushed after .xx cmds */ ! 682: ptfpcmd(pos, shortname); ! 683: if (pos == 0) ! 684: ch = (tchar) FONTPOS | (tchar) f << 16; ! 685: return(pos); ! 686: } ! 687: ! 688: ! 689: casecs() ! 690: { ! 691: register i, j; ! 692: ! 693: noscale++; ! 694: skip(); ! 695: if (!(i = getrq()) || (i = findft(i)) < 0) ! 696: goto rtn; ! 697: skip(); ! 698: cstab[i] = atoi(); ! 699: skip(); ! 700: j = atoi(); ! 701: if (nonumb) ! 702: ccstab[i] = 0; ! 703: else ! 704: ccstab[i] = findps(j); ! 705: rtn: ! 706: zapwcache(0); ! 707: noscale = 0; ! 708: } ! 709: ! 710: ! 711: casebd() ! 712: { ! 713: register i, j, k; ! 714: ! 715: zapwcache(0); ! 716: k = 0; ! 717: bd0: ! 718: if (skip() || !(i = getrq()) || (j = findft(i)) == -1) { ! 719: if (k) ! 720: goto bd1; ! 721: else ! 722: return; ! 723: } ! 724: if (j == smnt) { ! 725: k = smnt; ! 726: goto bd0; ! 727: } ! 728: if (k) { ! 729: sbold = j; ! 730: j = k; ! 731: } ! 732: bd1: ! 733: skip(); ! 734: noscale++; ! 735: bdtab[j] = atoi(); ! 736: noscale = 0; ! 737: } ! 738: ! 739: ! 740: casevs() ! 741: { ! 742: register i; ! 743: ! 744: skip(); ! 745: vflag++; ! 746: dfact = INCH; /* default scaling is points! */ ! 747: dfactd = 72; ! 748: res = VERT; ! 749: i = inumb(&lss); ! 750: if (nonumb) ! 751: i = lss1; ! 752: if (i < VERT) ! 753: i = VERT; ! 754: lss1 = lss; ! 755: lss = i; ! 756: } ! 757: ! 758: ! 759: casess() ! 760: { ! 761: register i; ! 762: ! 763: noscale++; ! 764: skip(); ! 765: if (i = atoi()) { ! 766: spacesz = i & 0177; ! 767: zapwcache(0); ! 768: sps = width(' ' | chbits); ! 769: } ! 770: noscale = 0; ! 771: } ! 772: ! 773: ! 774: tchar xlss() ! 775: { ! 776: /* stores \x'...' into ! 777: /* two successive tchars. ! 778: /* the first contains HX, the second the value, ! 779: /* encoded as a vertical motion. ! 780: /* decoding is done in n2.c by pchar(). ! 781: */ ! 782: int i; ! 783: ! 784: getch(); ! 785: dfact = lss; ! 786: i = quant(atoi(), VERT); ! 787: dfact = 1; ! 788: getch(); ! 789: if (i >= 0) ! 790: *pbp++ = MOT | VMOT | i; ! 791: else ! 792: *pbp++ = MOT | VMOT | NMOT | -i; ! 793: return(HX); ! 794: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.