diff options
| author | Eli Zaretskii | 2015-07-18 13:23:22 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2015-07-18 13:23:22 +0300 |
| commit | 166ffcb6c7a012ed5f655d7bb0fad97319ad54fc (patch) | |
| tree | b003c93eae7a22c64e78be8e738ec5b0c2b7bc2c | |
| parent | d3816bf8ad1fcfed2a32d23216a55850ee4325b5 (diff) | |
| download | emacs-166ffcb6c7a012ed5f655d7bb0fad97319ad54fc.tar.gz emacs-166ffcb6c7a012ed5f655d7bb0fad97319ad54fc.zip | |
Fix following Info cross-references to anchors
* lisp/info.el (Info-read-subfile): Add to the returned value the
length of subfile preamble, after converting it to file's byte
offset, as expected by the caller. Use bufferpos-to-filepos.
(Info-find-node-2): If searching for a node with a
1000-character slop fails, try again with a 10000-character slop,
to account for known bugs in Texinfo 5.0 and 5.1. (Bug#21055)
* lisp/international/mule-util.el (bufferpos-to-filepos): New
function.
* etc/NEWS: Mention bufferpos-to-filepos.
| -rw-r--r-- | etc/NEWS | 2 | ||||
| -rw-r--r-- | lisp/info.el | 21 | ||||
| -rw-r--r-- | lisp/international/mule-util.el | 73 |
3 files changed, 92 insertions, 4 deletions
| @@ -911,7 +911,7 @@ be updated accordingly. | |||
| 911 | 911 | ||
| 912 | * Lisp Changes in Emacs 25.1 | 912 | * Lisp Changes in Emacs 25.1 |
| 913 | 913 | ||
| 914 | ** New function `filepos-to-bufferpos'. | 914 | ** New functions `filepos-to-bufferpos' and `bufferpos-to-filepos'. |
| 915 | 915 | ||
| 916 | ** The default value of `load-read-function' is now `read'. | 916 | ** The default value of `load-read-function' is now `read'. |
| 917 | 917 | ||
diff --git a/lisp/info.el b/lisp/info.el index 413928bcfbc..bcff7ccffd3 100644 --- a/lisp/info.el +++ b/lisp/info.el | |||
| @@ -1217,6 +1217,18 @@ is non-nil)." | |||
| 1217 | (goto-char pos) | 1217 | (goto-char pos) |
| 1218 | (throw 'foo t))) | 1218 | (throw 'foo t))) |
| 1219 | 1219 | ||
| 1220 | ;; If the Texinfo source had an @ifnottex block of text | ||
| 1221 | ;; before the Top node, makeinfo 5.0 and 5.1 mistakenly | ||
| 1222 | ;; omitted that block's size from the starting position | ||
| 1223 | ;; of the 1st subfile, which makes GUESSPOS overshoot | ||
| 1224 | ;; the correct position by the length of that text. So | ||
| 1225 | ;; we try again with a larger slop. | ||
| 1226 | (goto-char (max (point-min) (- guesspos 10000))) | ||
| 1227 | (let ((pos (Info-find-node-in-buffer regexp strict-case))) | ||
| 1228 | (when pos | ||
| 1229 | (goto-char pos) | ||
| 1230 | (throw 'foo t))) | ||
| 1231 | |||
| 1220 | (when (string-match "\\([^.]+\\)\\." nodename) | 1232 | (when (string-match "\\([^.]+\\)\\." nodename) |
| 1221 | (let (Info-point-loc) | 1233 | (let (Info-point-loc) |
| 1222 | (Info-find-node-2 | 1234 | (Info-find-node-2 |
| @@ -1553,10 +1565,13 @@ is non-nil)." | |||
| 1553 | (if (looking-at "\^_") | 1565 | (if (looking-at "\^_") |
| 1554 | (forward-char 1) | 1566 | (forward-char 1) |
| 1555 | (search-forward "\n\^_")) | 1567 | (search-forward "\n\^_")) |
| 1556 | ;; Don't add the length of the skipped summary segment to | ||
| 1557 | ;; the value returned to `Info-find-node-2'. (Bug#14125) | ||
| 1558 | (if (numberp nodepos) | 1568 | (if (numberp nodepos) |
| 1559 | (- nodepos lastfilepos)))) | 1569 | ;; Our caller ('Info-find-node-2') wants the (zero-based) byte |
| 1570 | ;; offset corresponding to NODEPOS, from the beginning of the | ||
| 1571 | ;; subfile. This is especially important if NODEPOS is for an | ||
| 1572 | ;; anchor reference, because for those the position is all we | ||
| 1573 | ;; have. | ||
| 1574 | (+ (- nodepos lastfilepos) (bufferpos-to-filepos (point) 'exact))))) | ||
| 1560 | 1575 | ||
| 1561 | (defun Info-unescape-quotes (value) | 1576 | (defun Info-unescape-quotes (value) |
| 1562 | "Unescape double quotes and backslashes in VALUE." | 1577 | "Unescape double quotes and backslashes in VALUE." |
diff --git a/lisp/international/mule-util.el b/lisp/international/mule-util.el index 8dd83b43290..f3aa70fd66c 100644 --- a/lisp/international/mule-util.el +++ b/lisp/international/mule-util.el | |||
| @@ -412,6 +412,79 @@ QUALITY can be: | |||
| 412 | (decode-coding-region (point-min) | 412 | (decode-coding-region (point-min) |
| 413 | (min (point-max) (+ pm byte)) | 413 | (min (point-max) (+ pm byte)) |
| 414 | coding-system t)))))))))))) | 414 | coding-system t)))))))))))) |
| 415 | ;;;###autoload | ||
| 416 | (defun bufferpos-to-filepos (position &optional quality coding-system) | ||
| 417 | "Try to return the file byte corresponding to a particular buffer POSITION. | ||
| 418 | Value is the file position given as a (0-based) byte count. | ||
| 419 | The function presumes the file is encoded with CODING-SYSTEM, which defaults | ||
| 420 | to `buffer-file-coding-system'. | ||
| 421 | QUALITY can be: | ||
| 422 | `approximate', in which case we may cut some corners to avoid | ||
| 423 | excessive work. | ||
| 424 | `exact', in which case we may end up re-(en/de)coding a large | ||
| 425 | part of the file/buffer. | ||
| 426 | nil, in which case we may return nil rather than an approximation." | ||
| 427 | (unless coding-system (setq coding-system buffer-file-coding-system)) | ||
| 428 | (let* ((eol (coding-system-eol-type coding-system)) | ||
| 429 | (lineno (if (= eol 1) (1- (line-number-at-pos position)) 0)) | ||
| 430 | (type (coding-system-type coding-system)) | ||
| 431 | (base (coding-system-base coding-system)) | ||
| 432 | byte) | ||
| 433 | (and (eq type 'utf-8) | ||
| 434 | ;; Any post-read/pre-write conversions mean it's not really UTF-8. | ||
| 435 | (not (null (coding-system-get coding-system :post-read-conversion))) | ||
| 436 | (setq type 'not-utf-8)) | ||
| 437 | (and (memq type '(charset raw-text undecided)) | ||
| 438 | ;; The following are all of type 'charset', but they are | ||
| 439 | ;; actually variable-width encodings. | ||
| 440 | (not (memq base '(chinese-gbk chinese-gb18030 euc-tw euc-jis-2004 | ||
| 441 | korean-iso-8bit chinese-iso-8bit | ||
| 442 | japanese-iso-8bit chinese-big5-hkscs | ||
| 443 | japanese-cp932 korean-cp949))) | ||
| 444 | (setq type 'single-byte)) | ||
| 445 | (pcase type | ||
| 446 | (`utf-8 | ||
| 447 | (setq byte (position-bytes position)) | ||
| 448 | (when (null byte) | ||
| 449 | (if (<= position 0) | ||
| 450 | (setq byte 1) | ||
| 451 | (setq byte (position-bytes (point-max))))) | ||
| 452 | (setq byte (1- byte)) | ||
| 453 | (+ byte | ||
| 454 | ;; Account for BOM, if any. | ||
| 455 | (if (coding-system-get coding-system :bom) 3 0) | ||
| 456 | ;; Account for CR in CRLF pairs. | ||
| 457 | lineno)) | ||
| 458 | (`single-byte | ||
| 459 | (+ position -1 lineno)) | ||
| 460 | ((and `utf-16 | ||
| 461 | ;; FIXME: For utf-16, we could use the same approach as used for | ||
| 462 | ;; dos EOLs (counting the number of non-BMP chars instead of the | ||
| 463 | ;; number of lines). | ||
| 464 | (guard (not (eq quality 'exact)))) | ||
| 465 | ;; In approximate mode, assume all characters are within the | ||
| 466 | ;; BMP, i.e. each one takes up 2 bytes. | ||
| 467 | (+ (* (1- position) 2) | ||
| 468 | ;; Account for BOM, if any. | ||
| 469 | (if (coding-system-get coding-system :bom) 2 0) | ||
| 470 | ;; Account for CR in CRLF pairs. | ||
| 471 | lineno)) | ||
| 472 | (_ | ||
| 473 | (pcase quality | ||
| 474 | (`approximate (+ (position-bytes position) -1 lineno)) | ||
| 475 | (`exact | ||
| 476 | ;; Rather than assume that the file exists and still holds the right | ||
| 477 | ;; data, we reconstruct its relevant portion. | ||
| 478 | (let ((buf (current-buffer))) | ||
| 479 | (with-temp-buffer | ||
| 480 | (set-buffer-multibyte nil) | ||
| 481 | (let ((tmp-buf (current-buffer))) | ||
| 482 | (with-current-buffer buf | ||
| 483 | (save-restriction | ||
| 484 | (widen) | ||
| 485 | (encode-coding-region (point-min) (min (point-max) position) | ||
| 486 | coding-system tmp-buf))) | ||
| 487 | (1- (point-max))))))))))) | ||
| 415 | 488 | ||
| 416 | (provide 'mule-util) | 489 | (provide 'mule-util) |
| 417 | 490 | ||