From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.devel Subject: Texinfo XML support in Emacs Info browser Date: Sun, 03 Jun 2007 02:03:03 +0300 Organization: JURTA Message-ID: <87r6ouot6c.fsf@jurta.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: sea.gmane.org 1180825980 22904 80.91.229.12 (2 Jun 2007 23:13:00 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Sat, 2 Jun 2007 23:13:00 +0000 (UTC) Cc: karl@gnu.org To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Jun 03 01:12:59 2007 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1HucmG-0006s7-3y for ged-emacs-devel@m.gmane.org; Sun, 03 Jun 2007 01:12:56 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HucmF-0001CV-Ae for ged-emacs-devel@m.gmane.org; Sat, 02 Jun 2007 19:12:55 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Hucl9-0000YI-LB for emacs-devel@gnu.org; Sat, 02 Jun 2007 19:11:47 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Hucl7-0000Ww-JD for emacs-devel@gnu.org; Sat, 02 Jun 2007 19:11:46 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Hucl7-0000Wr-EU for emacs-devel@gnu.org; Sat, 02 Jun 2007 19:11:45 -0400 Original-Received: from smarty.dreamhost.com ([208.113.175.8]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Hucl5-00010P-5U; Sat, 02 Jun 2007 19:11:43 -0400 Original-Received: from schnapps.dreamhost.com (apache2-noxim.schnapps.dreamhost.com [208.113.175.112]) by smarty.dreamhost.com (Postfix) with ESMTP id A5F45EE256; Sat, 2 Jun 2007 16:11:42 -0700 (PDT) Original-Received: from localhost (localhost [127.0.0.1]) by schnapps.dreamhost.com (Postfix) with ESMTP id 59A38A8702; Sat, 2 Jun 2007 16:11:41 -0700 (PDT) User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1.50 (gnu/linux) X-detected-kernel: Linux 2.6, seldom 2.4 (older, 4) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:72083 Archived-At: --=-=-= Here is the initial version of the Emacs package that provides support for Texinfo XML format in the Emacs Info browser. This format is generated by the command `makeinfo --xml' that maps Texinfo markup commands into XML syntax. The current implementation uses a lot of defadvices on basic info.el functions. This was done for adding new format seamlessly, and leaving old Info API for the new format. Later these functions could be modified to allow switching between different Info formats natively. I'd like to hear all comments about whether this is the right direction and so on. Thanks. --=-=-= Content-Type: application/emacs-lisp Content-Disposition: inline; filename=info-xml.el Content-Transfer-Encoding: quoted-printable ;;; info-xml.el --- Info browser support for Texinfo XML output of makeinfo ;; Copyright (C) 2007 Juri Linkov ;; Author: Juri Linkov ;; Keywords: help ;; Version: 0.0.1 ;; This file 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. ;; This file 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., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. ;;; Commentary: ;; `makeinfo --xml' generates output Info files in an XML-based format ;; that merely translates the Texinfo markup commands into XML syntax. ;; This package allows Emacs Info browser to open and display Info files ;; in this format. ;;; Code: (require 'info) (defvar Info-xml-buffer 'auto-detect "Non-nil if current buffer contains an Info manual in Texinfo XML format.= ") (defun Info-xml-buffer (&optional filename) "Check if the current buffer (or FILENAME if given) is in Texinfo XML for= mat." (if (and filename (equal Info-current-file filename) (memq Info-xml-buffer '(nil t))) Info-xml-buffer (let ((found nil)) (if (stringp filename) (setq found (string-match "\.xml\.info" filename)) (save-excursion (goto-char (point-min)) (condition-case () (if (and (re-search-forward "[ \n] *" (if (stringp nodename) (regexp-quote nodename= ) "") " *"))) (catch 'foo ;; Now search from beg of buffer to find the actual node. (let ((pos (Info-xml-find-node-in-buffer regexp))) (when pos (goto-char pos) (throw 'foo t))) ;; No such anchor in tag table or node in tag table or file (error "No such node or anchor: %s" nodename)) (Info-xml-select-node) (goto-char (point-min)))) ;; If we did not finish finding the specified node, ;; go back to the previous one. (or Info-current-node no-going-back (null Info-history) (let ((hist (car Info-history))) (setq Info-history (cdr Info-history)) (Info-find-node (nth 0 hist) (nth 1 hist) t) (goto-char (nth 2 hist)))))) (defun Info-xml-find-node-in-buffer (regexp) (let (found) (save-excursion (goto-char (point-min)) (when (and (re-search-forward regexp nil t) (re-search-backward "" nil t)) (beginning-of-line) (setq found (point))) found))) (defun Info-xml-select-node () "Select the XML Info node that point is in." (save-excursion ;; Find beginning of node. (if (or (looking-at " *") (search-backward "" nil 'move)) (beginning-of-line) (signal 'search-failed (list ""))) ;; Get nodename spelled as it is in the node. (save-excursion (re-search-forward (concat " *\\(.*\\) *")) (setq Info-current-node (match-string-no-properties 1))) (Info-set-mode-line) ;; Find the end of it, and narrow. (beginning-of-line) ;; Narrow to the node contents (narrow-to-region (point) (if (re-search-forward "" nil t) (point) (point-max))) ;; Add a new unique history item to full history list (Info-history-add Info-current-file Info-current-node) (setq Info-history-forward nil) (if (not (eq Info-fontify-maximum-menu-size nil)) (Info-xml-render)) ;;(Info-xml-display-images-node) (run-hooks 'Info-xml-selection-hook))) ;; RENDERING (defun Info-xml-render () (save-excursion (let ((inhibit-read-only t)) (dolist (render Info-xml-render) (let ((what (car render)) (how (cdr render))) (goto-char (point-min)) (while (re-search-forward what nil t) (replace-match (funcall how) nil t))))))) (defvar Info-xml-render '(("\n* *\n?\\([^\^_]*?\\)" . Info-xml-render-node) ("\n* *\\(.*?\\)" . Info-xml-render-nodename) ("\n* *\\(.*?\\)" . Info-xml-render-nodenext) ("\n* *\\(.*?\\)" . Info-xml-render-nodeprev) ("\n* *\\(.*?\\)" . Info-xml-render-nodeup) (" *\\(.*?\\)" . Info-xml-render-title) ("\\(.*?\\)" . Info-xml-render-cite) ("\\(.*?\\)" . Info-xml-render-key) ("\\(.*?\\)" . Info-xml-render-kbd) ("—" . (lambda () (string (decode-char 'ucs #x2014)))) (" *\\([^\^_]*?\\)" . Info-xml-render-xref) (" *\\([^\^_]*?\\)" . Info-xml-render-menu) (" *\\([^\^_]*?\\)" . Info-xml-render-menuentry) (" *\\([^\^_]*?\\)" . Info-xml-render-para) ("\n* *" . (lambda () "")) ; remove XML comments ("<[^>]+>" . (lambda () "")) ;;(" *<\\([^>]+\\)>\\([^\^_]*?\\)" . Info-xml-render-other) )) (defun Info-xml-render-node () (match-string 1)) (defun Info-xml-render-nodename () (format "File: %s, Node: %s" (file-name-nondirectory Info-current-file) (propertize (match-string 1) 'face 'info-node))) (defun Info-xml-render-nodenext () (set (make-local-variable 'Info-xml-node-next) (match-string 1)) (format ", Next: %s" (propertize (match-string 1) 'face 'info-xref 'info-xref (match-string 1)))) (defun Info-xml-render-nodeprev () (set (make-local-variable 'Info-xml-node-prev) (match-string 1)) (format ", Prev: %s" (propertize (match-string 1) 'face 'info-xref 'info-xref (match-string 1)))) (defun Info-xml-render-nodeup () (set (make-local-variable 'Info-xml-node-up) (match-string 1)) (format ", Up: %s" (propertize (match-string 1) 'face 'info-xref 'info-xref (match-string 1)))) (defun Info-xml-render-title () (format "%s\n" (propertize (match-string 1) 'face 'info-title-1))) (defun Info-xml-render-cite () (propertize (match-string 1) 'face 'italic)) (defun Info-xml-render-kbd () (propertize (match-string 1) 'face 'mode-line)) (defun Info-xml-render-key () (propertize (match-string 1) 'face 'mode-line)) (defun Info-xml-render-menu () (concat "\n" (propertize "* Menu:" 'face 'info-menu-header) "\n" (match-s= tring 1))) (defun Info-xml-render-menuentry () (let ((menuentry (match-string 1)) menunode menutitle menucomment) (save-match-data (if (string-match "\\(.*?\\)" menuentry) (setq menunode (match-string 1 menuentry))) (if (string-match "\\(.*?\\)" menuentry) (setq menutitle (match-string 1 menuentry))) (if (string-match "\\(.*?\\)" menuentry) (setq menucomment (match-string 1 menuentry))) (format "* %s %s" (propertize menutitle 'face 'info-xref 'info-xref (format "(%s)%s" Info-current-file men= unode)) menucomment)))) (defun Info-xml-render-xref () (let ((xref (match-string 1)) xrefnodename xrefinfoname xrefprintedname) (save-match-data (if (string-match "\\(.*?\\)" xref) (setq xrefnodename (match-string 1 xref))) (if (string-match "\\(.*?\\)" xref) (setq xrefinfofile (match-string 1 xref))) (if (string-match "\\(.*?\\)" xref) (setq xrefinfoname (match-string 1 xref))) (if (string-match "\\(.*?\\)" xref) (setq xrefprintedname (match-string 1 xref))) (format "%s" (propertize (or xrefprintedname xrefnodename) 'face 'info-xref 'info-xref (format "(%s)%s" (or xrefinfofile Info-cur= rent-file) xrefnodename)))))) (defun Info-xml-render-para () (format "\n%s\n" (let ((para (match-string 1))) (save-match-data (with-temp-buffer (let ((fill-column (- (window-width) 8))) (insert para) (fill-individual-paragraphs (point-min) (point-max)) (buffer-string))))))) (defun Info-xml-render-other () (match-string 2)) ;;; NAVIGATION (defadvice Info-next-reference (around Info-xml-Info-next-reference act) (if (Info-xml-buffer Info-current-file) (Info-xml-next-reference recur) ad-do-it)) (defun Info-xml-next-reference (&optional recur) (interactive) (if (get-text-property (point) 'info-xref) (goto-char (next-single-property-change (point) 'info-xref))) (goto-char (or (next-single-property-change (point) 'info-xref) (point)))) (defadvice Info-prev-reference (around Info-xml-Info-prev-reference act) (if (Info-xml-buffer Info-current-file) (Info-xml-prev-reference recur) ad-do-it)) (defun Info-xml-prev-reference (&optional recur) (interactive) (if (get-text-property (point) 'info-xref) (goto-char (previous-single-property-change (point) 'info-xref))) (goto-char (or (previous-single-property-change (point) 'info-xref) (poin= t)))) (defadvice Info-follow-nearest-node (around Info-xml-Info-follow-nearest-no= de act) (if (Info-xml-buffer Info-current-file) (Info-xml-follow-nearest-node fork) ad-do-it)) (defun Info-xml-follow-nearest-node (&optional fork) (let ((xref (get-text-property (point) 'info-xref))) (if xref (Info-goto-node xref)))) (provide 'info-xml) ;;; info-xml.el ends here --=-=-= -- Juri Linkov http://www.jurta.org/emacs/ --=-=-= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel --=-=-=--