psgml / psgml-api.el

Full commit
;;; psgml-api.el --- Extra API functions for PSGML
;; $Id$

;; Copyright (C) 1994 Lennart Staflin

;; Author: Lennart Staflin <>

;; This program 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
;; of the License, or (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program; if not, write to the Free Software
;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

;;; Commentary:

;; Provides some extra functions for the API to PSGML.

;;; Code:

(provide 'psgml-api)
(require 'psgml)
(require 'psgml-parse)

;;;; Mapping: map and modify

(defun sgml-map-element-modify (el-fun element)
  "Apply EL-FUN to ELEMENT and the elements in its content.
The EL-FUN may change the buffer.  But if it changes the buffer and
leaves the element with no start-tag some elements may be ignored."
  (let ((level				; level in the element tree
	(tick				; change counter
    (while element
      (funcall el-fun element)
      ;; If the function has modified the buffer, a fresh parse is needed
      (when (/= tick (buffer-modified-tick))
	(setq element (sgml-find-element-of (sgml-element-start element)))
	(setq tick (buffer-modified-tick)))
       ;; Map content if any
       ((setq next (sgml-element-content element))
	(incf level))
       ;; If in a sub-tree, move to next element
	(while (and (> level 0)
		    (null (setq next (sgml-element-next element))))
	  (setq element (sgml-element-parent element))
	  (decf level))))
      (setq element next))))
;;;; Map content

(defun sgml-map-content (element element-fun
				 &optional data-fun pi-fun entity-fun)
  "Map content of ELEMENT, calling ELEMENT-FUN for every element.
Also calling DATA-FUN, if non-nil, with data in content."
  (sgml-element-end element)		; Make sure all content is parsed
  (let ((main-buffer-max (point-max)))
      (sgml-set-parse-state element 'start)
      (when (eobp) (sgml-pop-entity))
      (when (eolp) (forward-char 1))
      (sgml-parse-data main-buffer-max data-fun pi-fun entity-fun)
      (let ((c (sgml-tree-content element)))
	(while c
	  (funcall element-fun c)
	  (sgml-set-parse-state c 'after)
	  (sgml-parse-data main-buffer-max data-fun pi-fun entity-fun)
	  (setq c (sgml-tree-next c)))))

(defun sgml-parse-data (sgml-goal sgml-data-function sgml-pi-function
  (let ((sgml-throw-on-element-change 'el-done))
    (catch sgml-throw-on-element-change
       (sgml-parser-loop nil)))))
;;;; Entity management

(defun sgml-push-to-string (string)
  "Create an entity from STRING and push it on the top of the entity stack.
After this the current buffer will be a scratch buffer containing the text
of the new entity with point at the first character.
    Use `sgml-pop-entity' to exit from this buffer."
  (sgml-push-to-entity (sgml-make-entity "#STRING" 'text string)))

;;; psgml-api.el ends here