aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2015-07-18 13:23:22 +0300
committerEli Zaretskii2015-07-18 13:23:22 +0300
commit166ffcb6c7a012ed5f655d7bb0fad97319ad54fc (patch)
treeb003c93eae7a22c64e78be8e738ec5b0c2b7bc2c
parentd3816bf8ad1fcfed2a32d23216a55850ee4325b5 (diff)
downloademacs-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/NEWS2
-rw-r--r--lisp/info.el21
-rw-r--r--lisp/international/mule-util.el73
3 files changed, 92 insertions, 4 deletions
diff --git a/etc/NEWS b/etc/NEWS
index e56d498d4fe..07bff641720 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -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.
418Value is the file position given as a (0-based) byte count.
419The function presumes the file is encoded with CODING-SYSTEM, which defaults
420to `buffer-file-coding-system'.
421QUALITY 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