From 9d92d076b6dcdc1a326685d1ef71007c86b8d45d Mon Sep 17 00:00:00 2001 From: Thomas Wolmer Date: Sun, 29 May 2005 20:49:01 +0000 Subject: [PATCH] Added footnotes support! git-svn-id: https://projectaon.org/data/trunk@68 f6f3e2d7-ff33-0410-aaf5-b4bee2cdac11 --- scripts/aon.el | 182 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 178 insertions(+), 4 deletions(-) diff --git a/scripts/aon.el b/scripts/aon.el index b099dd9..9547a4b 100755 --- a/scripts/aon.el +++ b/scripts/aon.el @@ -4,7 +4,7 @@ ;; Author: Thomas Wolmer ;; Created: 17 Aug 2003 -;; Version: 0.12 +;; Version: 0.13 ;; Keywords: aon ;;; Commentary: @@ -42,6 +42,7 @@ ;; 2005-02-05: 0.10: Added a function for inserting large illustrations ;; 2005-05-06: 0.11: Added a function for inserting inline illustrations ;; 2005-05-23: 0.12: Fixed bug in aon-re-get-errata-entry-id. +;; 2005-05-29: 0.13: Introduced full footnote support. ;; A slight limitation: We can only handle one illustrator at a time. @@ -90,9 +91,12 @@ used instead (unless it is also 'nonindexed').") (defconst aon-re-get-sect-id "" "Regexp used to find the id of asection.") (defconst aon-re-get-errata-entry-id "

()" - "Regexp used to find the id of an errata list entry.") + "Regexp used to find the id of an errata list entry.") ; and footnotes too! (defconst aon-re-get-title "\\(.+?\\)" "Regexp used to find the title of a section.") +(defconst aon-re-get-footnote-num + "" + "Regexp used to locate the sequence number of a footnote.") ;; The errata item texts (as templates to be fed to 'format') ;; These are only (hardcoded) reader-visible texts inserted by this hack! @@ -444,7 +448,7 @@ The illustrations list is not updated (TBD)." (list xnum xheight xcaption))) (let ((startpos (point)) (endpos (save-excursion - (insert (format "\n \n %s\n %s\n \n \n \n " + (insert (format "\n\n%s\n%s\n\n\n\n" aon-illustrator-name caption number aon-large-illustration-width height number aon-large-illustration-width height)) @@ -466,6 +470,10 @@ The illustrations list is not updated (TBD)." (point)))) (aon-indent-block startpos endpos))) +;; TODO: Create a method that takes a function which adds text, and then +;; indents the added text. Now each caller of this function must add some +;; codes to handle start and end positions. + (defun aon-indent-block (startpos endpos) "Indents the text between startpos and endpos. The positions need not be start or end of lines. Leaves point at end of block." @@ -473,6 +481,172 @@ The positions need not be start or end of lines. Leaves point at end of block." (indent-according-to-mode) (forward-line 1))) +;; TODO: Clean up the whole footnote code, it is a mess. + +(defun aon-footnote-add (pos text) + "Adds a footnote at the current position. +Note that the footnote text must contain all

aragraph tags, and that line +breaks are not allowed." + (interactive + (let ((xpos (point)) + (xtext (read-string "Footnote text: "))) + (list xpos xtext))) + (if (string= text "") + (error "No footnote text!")) + (let ((tpos (string-match "

" text))) + (unless (and tpos (= 0 tpos)) + (error "Footnotes must contain

aragraph start and end tags!"))) + (save-excursion + (let* + ((sectid (aon-get-sect-id)) + (fblockstart (aon-find-footnote-block sectid)) + (fnum (if fblockstart + (aon-get-next-footnote-num fblockstart) + 1)) + (fid (format "%s-%s" sectid fnum)) + (fentry + (format "\n%s" + fid fid text)) + (fref + (format "" + fid fid)) + (fnth (1+ (aon-count-previous-footnotes sectid))) + (flistref + (format "(%s)" sectid (aon-get-sect-title))) + (flistinsertpos + (aon-find-footnote-list-insert-pos sectid flistref fnth))) + ;; First insert errata list entry + (goto-char flistinsertpos) + (let ((startpos (point)) + (endpos (save-excursion + (insert "\n" text) + (point)))) + (aon-indent-block startpos endpos)) + (goto-char flistinsertpos) + (search-forward "

") ; no line-end-position in xemacs + (insert flistref " ") + ;; Then errata ref + (goto-char pos) + (insert fref) + ;; And last errata entry in section errata block (which may be created) + (if fblockstart + (progn ; block exists, go to the right position in it + (goto-char fblockstart) + (dotimes (i (1- fnth)) + (search-forward "" + (save-excursion + (goto-char fblockstart) + (search-forward ""))))) + (goto-char (aon-create-footnote-block sectid))) + (let ((startpos (point)) + (endpos (save-excursion + (insert fentry) + (point)))) + (aon-indent-block startpos endpos))))) + +(defun aon-create-footnote-block (sect) + "Creates a footnote block and returns insertion point." + (save-excursion + (goto-char (aon-get-sect-pos sect)) + (search-forward "") + (save-excursion + (let ((spos (point)) + (endpos (save-excursion + (insert "\n\n\n") + (point)))) + (aon-indent-block spos endpos))) + (search-forward ""))) + +(defun aon-find-footnote-block (sect) + "Returns the start of the footnote block of the current section, or nil." + (save-excursion + (goto-char (aon-get-sect-pos sect)) + (search-forward "") + (let* + ((datastart (save-excursion + (search-forward ""))) + (footstart (save-excursion + (search-forward "" datastart t)))) + footstart))) + +(defun aon-get-footnote-num (pos) + "Return the numerical sequence number of the footnote on the current line. +If there are no more footnotes defined here, it returns nil." + (interactive "p") + (let ((fend (save-excursion + (search-forward "")))) + (save-excursion + (and + (re-search-forward aon-re-get-footnote-num fend t) + (string-to-number (match-string 1)))))) + +(defun aon-get-next-footnote-num (pos) + "Returns the next footnote id number. +This will always be the previously highest number plus one." + (let ((seq '())) + (save-excursion + (goto-char pos) + (while (setq x (aon-get-footnote-num (point))) + (setq seq (cons x seq)) + (search-forward "") + (forward-line 1))) + (if seq + (1+ (car (sort seq '>))) ; prior highest + 1 + 1))) ; the first + +(defun aon-count-previous-footnotes (sect) + "Based on the current position, counts the number of footnotes before..." + (save-excursion + (let ((sectstart (aon-get-sect-pos sect)) + (count 0)) + (while (re-search-backward + "" sectstart t) + (setq count (1+ count))) + count))) + +(defun aon-find-footnote-list-insert-pos (sect ref nth) + "" + (save-excursion + (let ((flistsectpos (aon-get-sect-pos "footnotz"))) + (if (= nth 1) + (aon-find-new-footnote-list-entry-pos (aon-get-sect-pos sect)) + (progn + (goto-char flistsectpos) + (dotimes (i (1- nth)) + (search-forward ref)) + (end-of-line) + (point)))))) + +;; TODO: This code is mostly copied from the errata code. Merge them? + +(defun aon-find-new-footnote-list-entry-pos (sectpos) + "Return the position where a new footnote list entry shall be created." + (save-excursion + (goto-char (aon-get-sect-pos "footnotz")) + (search-forward "") + (forward-line 1) ; pos is now on the line of the first

(if it exists) + (let ((endofflist + (save-excursion + (if (search-forward "") + (point) + (error "Could not find the end of the footnotes list!"))))) + (while (let ((id (save-excursion + (if (re-search-forward aon-re-get-errata-entry-id + endofflist + t) + (match-string 1) + "illstrat" ; hack warning! to avoid getting too far + )))) + (unless (setq thissectpos (aon-get-sect-pos id)) + (error + "Section %s has a footnote list entry, but does not exist!" + id)) + (< thissectpos sectpos)) + (forward-line 1))) + (forward-line -1) + (end-of-line) + (point))) + (global-set-key "\C-cr" 'aon-errata-replace) (global-set-key "\C-cd" 'aon-errata-delete) (global-set-key "\C-ca" 'aon-errata-add) @@ -483,7 +657,7 @@ The positions need not be start or end of lines. Leaves point at end of block." (global-set-key "\C-cl" 'aon-illustration-large) (global-set-key "\C-ci" 'aon-illustration-inline) - +(global-set-key "\C-cf" 'aon-footnote-add) ;; Errata examples ;; -- 2.34.1