Browse Source

Merge branch 'master' of orgmode.org:org-mode

Bastien Guerry 14 years ago
parent
commit
896654edc2
4 changed files with 74 additions and 64 deletions
  1. 22 18
      doc/org.texi
  2. 3 2
      lisp/ob-exp.el
  3. 4 24
      lisp/ob-latex.el
  4. 45 20
      lisp/org-table.el

+ 22 - 18
doc/org.texi

@@ -2269,12 +2269,14 @@ field, or press @kbd{C-c @}} to toggle the display of a grid.
 Formulas can reference the value of another field in two ways.  Like in
 Formulas can reference the value of another field in two ways.  Like in
 any other spreadsheet, you may reference fields with a letter/number
 any other spreadsheet, you may reference fields with a letter/number
 combination like @code{B3}, meaning the 2nd field in the 3rd row.
 combination like @code{B3}, meaning the 2nd field in the 3rd row.
-@c Such references are always fixed to that field, they don't change
-@c when you copy and paste a formula to a different field.  So
-@c Org's @code{B3} behaves like @code{$B$3} in other spreadsheets.
 
 
 @noindent
 @noindent
-Org also uses another, more general operator that looks like this:
+@vindex org-table-use-standard-references
+Org prefers@footnote{Org will understand references typed by the user as
+@samp{B4}, but it will not use this syntax when offering a formula for
+editing.  You can customize this behavior using the variable
+@code{org-table-use-standard-references}.}  to use another, more general
+operator that looks like this:
 @example
 @example
 @@@var{row}$@var{column}
 @@@var{row}$@var{column}
 @end example
 @end example
@@ -2286,23 +2288,25 @@ references make it possible to store a formula only once and use it in many
 fields without copying and modifying it.
 fields without copying and modifying it.
 
 
 Column references can be absolute like @samp{1}, @samp{2},...@samp{@var{N}},
 Column references can be absolute like @samp{1}, @samp{2},...@samp{@var{N}},
-or relative to the current column like @samp{+1} or @samp{-2}.
+or relative to the current column like @samp{+1} or @samp{-2}.  @code{$>}
+references the last column in the table, and you can use offsets like
+@code{$>-2}, meaning the third column from the right.
 
 
 The row specification only counts data lines and ignores horizontal separator
 The row specification only counts data lines and ignores horizontal separator
-lines (hlines).  You can use absolute row numbers @samp{1}...@samp{@var{N}},
-and row numbers relative to the current row like @samp{+3} or @samp{-1}.  A
-special case is @code{@@L} which stands for the last row in the
+lines (hlines).  Like with columns, you can use absolute row numbers
+@samp{1}...@samp{@var{N}}, and row numbers relative to the current row like
+@samp{+3} or @samp{-1}, and @code{@@>} references the last row in the
 table@footnote{For backward compatibility you can also use special names like
 table@footnote{For backward compatibility you can also use special names like
 @samp{$LR5} and @samp{$LR12} to refer in a stable way to the 5th and 12th
 @samp{$LR5} and @samp{$LR12} to refer in a stable way to the 5th and 12th
 field in the last row of the table.  However, this syntax is deprecated, it
 field in the last row of the table.  However, this syntax is deprecated, it
-should not be used for new documents.}, and you can use offsets from it like
-@code{@@L-2}.  Or specify the row relative to one of the hlines: @samp{I}
-refers to the first hline@footnote{Note that only hlines are counted that
-@emph{separate} table lines.  If the table starts with a hline above the
-header, it does not count.}, @samp{II} to the second, etc@.  @samp{-I} refers
-to the first such line above the current line, @samp{+I} to the first such
-line below the current line.  You can also write @samp{III+2} which is the
-second data line after the third hline in the table.
+should not be used for new documents.}.  You may also specify the row
+relative to one of the hlines: @samp{I} refers to the first
+hline@footnote{Note that only hlines are counted that @emph{separate} table
+lines.  If the table starts with a hline above the header, it does not
+count.}, @samp{II} to the second, etc@.  @samp{-I} refers to the first such
+line above the current line, @samp{+I} to the first such line below the
+current line.  You can also write @samp{III+2} which is the second data line
+after the third hline in the table.
 
 
 @samp{0} refers to the current row and column.  Also, if you omit
 @samp{0} refers to the current row and column.  Also, if you omit
 either the column or the row part of the reference, the current
 either the column or the row part of the reference, the current
@@ -2603,7 +2607,7 @@ same formula will be used in all fields of that column, with the following
 very convenient exceptions: (i) If the table contains horizontal separator
 very convenient exceptions: (i) If the table contains horizontal separator
 hlines, everything before the first such line is considered part of the table
 hlines, everything before the first such line is considered part of the table
 @emph{header} and will not be modified by column formulas.  (ii) Fields that
 @emph{header} and will not be modified by column formulas.  (ii) Fields that
-already get a value from a fild/range formula will be left alone by column
+already get a value from a field/range formula will be left alone by column
 formulas.  These conditions make column formulas very easy to use.
 formulas.  These conditions make column formulas very easy to use.
 
 
 To assign a formula to a column, type it directly into any field in the
 To assign a formula to a column, type it directly into any field in the
@@ -2615,7 +2619,7 @@ and the current field replaced with the result.  If the field contains only
 column, Org will only remember the most recently used formula.  In the
 column, Org will only remember the most recently used formula.  In the
 @samp{#+TBLFM:} line, column formulas will look like @samp{$4=$1+$2}.  The
 @samp{#+TBLFM:} line, column formulas will look like @samp{$4=$1+$2}.  The
 left-hand side of a column formula can not be the name of column, it must be
 left-hand side of a column formula can not be the name of column, it must be
-the numeric column reference.
+the numeric column reference or @code{$>}.
 
 
 Instead of typing an equation into the field, you may also use the
 Instead of typing an equation into the field, you may also use the
 following command:
 following command:

+ 3 - 2
lisp/ob-exp.el

@@ -248,8 +248,9 @@ This function is called by `org-babel-exp-do-export'.  The code
 block will be evaluated.  Optional argument SILENT can be used to
 block will be evaluated.  Optional argument SILENT can be used to
 inhibit insertion of results into the buffer."
 inhibit insertion of results into the buffer."
   (when (and org-export-babel-evaluate
   (when (and org-export-babel-evaluate
-	     (not (equal hash (org-babel-exp-in-export-file (nth 0 info)
-				(org-babel-result-hash)))))
+	     (not (and hash
+		       (equal hash (org-babel-exp-in-export-file (nth 0 info)
+				     (org-babel-result-hash))))))
     (let ((lang (nth 0 info))
     (let ((lang (nth 0 info))
 	  (body (nth 1 info)))
 	  (body (nth 1 info)))
       ;; skip code blocks which we can't evaluate
       ;; skip code blocks which we can't evaluate

+ 4 - 24
lisp/ob-latex.el

@@ -72,10 +72,6 @@ This function is called by `org-babel-execute-src-block'."
       (let* ((out-file (cdr (assoc :file params)))
       (let* ((out-file (cdr (assoc :file params)))
 	     (tex-file (org-babel-temp-file "latex-" ".tex"))
 	     (tex-file (org-babel-temp-file "latex-" ".tex"))
 	     (border (cdr (assoc :border params)))
 	     (border (cdr (assoc :border params)))
-	     (imagemagick (cdr (assoc :imagemagick params)))
-	     (im-in-options (cdr (assoc :iminoptions params)))
-	     (im-out-options (cdr (assoc :imoutoptions params)))
-	     (pdfpng (cdr (assoc :pdfpng params)))
 	     (fit (or (cdr (assoc :fit params)) border))
 	     (fit (or (cdr (assoc :fit params)) border))
 	     (height (and fit (cdr (assoc :pdfheight params))))
 	     (height (and fit (cdr (assoc :pdfheight params))))
 	     (width (and fit (cdr (assoc :pdfwidth params))))
 	     (width (and fit (cdr (assoc :pdfwidth params))))
@@ -85,10 +81,10 @@ This function is called by `org-babel-execute-src-block'."
 	      (append (cdr (assoc :packages params))
 	      (append (cdr (assoc :packages params))
 		      org-export-latex-packages-alist)))
 		      org-export-latex-packages-alist)))
         (cond
         (cond
-         ((and (string-match "\\.png$" out-file) (not imagemagick))
+         ((string-match "\\.png$" out-file)
           (org-create-formula-image
           (org-create-formula-image
            body out-file org-format-latex-options in-buffer))
            body out-file org-format-latex-options in-buffer))
-         ((or (string-match "\\.pdf$" out-file) imagemagick)
+         ((string-match "\\.pdf$" out-file)
 	  (require 'org-latex)
 	  (require 'org-latex)
 	  (with-temp-file tex-file
 	  (with-temp-file tex-file
 	    (insert
 	    (insert
@@ -122,29 +118,13 @@ This function is called by `org-babel-execute-src-block'."
 	       (concat "\n\\begin{document}\n" body "\n\\end{document}\n")))
 	       (concat "\n\\begin{document}\n" body "\n\\end{document}\n")))
 	    (org-export-latex-fix-inputenc))
 	    (org-export-latex-fix-inputenc))
           (when (file-exists-p out-file) (delete-file out-file))
           (when (file-exists-p out-file) (delete-file out-file))
-	  (let ((transient-pdf-file (org-babel-latex-tex-to-pdf tex-file)))
-	    (cond
-	     ((string-match "\\.pdf$" out-file)
-	      (rename-file transient-pdf-file out-file))
-	     (imagemagick
-	      (convert-pdf
-	       transient-pdf-file out-file im-in-options im-out-options)
-	      (when (file-exists-p transient-pdf-file)
-		(delete-file transient-pdf-file))))))
+          (rename-file (org-babel-latex-tex-to-pdf tex-file) out-file))
          ((string-match "\\.\\([^\\.]+\\)$" out-file)
          ((string-match "\\.\\([^\\.]+\\)$" out-file)
-          (error "can not create %s files, please specify a .png or .pdf file or try the :imagemagick header arguement"
+          (error "can not create %s files, please specify a .png or .pdf file"
 		 (match-string 1 out-file))))
 		 (match-string 1 out-file))))
         nil) ;; signal that output has already been written to file
         nil) ;; signal that output has already been written to file
     body))
     body))
 
 
-
-(defun convert-pdf (pdffile out-file im-in-options im-out-options)
-  "Generate a file from a pdf file using imagemagick."
-  (let ((cmd (concat "convert " im-in-options " " pdffile " "
-		     im-out-options " " out-file)))
-    (message (concat "Converting pdffile file " cmd  "..."))
-    (shell-command cmd)))
-
 (defun org-babel-latex-tex-to-pdf (file)
 (defun org-babel-latex-tex-to-pdf (file)
   "Generate a pdf file according to the contents FILE.
   "Generate a pdf file according to the contents FILE.
 Extracted from `org-export-as-pdf' in org-latex.el."
 Extracted from `org-export-as-pdf' in org-latex.el."

+ 45 - 20
lisp/org-table.el

@@ -176,7 +176,7 @@ this line."
   :tag "Org Table Calculation"
   :tag "Org Table Calculation"
   :group 'org-table)
   :group 'org-table)
 
 
-(defcustom org-table-use-standard-references t
+(defcustom org-table-use-standard-references 'from
   "Should org-mode work with table references like B3 instead of @3$2?
   "Should org-mode work with table references like B3 instead of @3$2?
 Possible values are:
 Possible values are:
 nil     never use them
 nil     never use them
@@ -1133,7 +1133,7 @@ is always the old value."
 	   (eql (org-table-expand-lhs-ranges
 	   (eql (org-table-expand-lhs-ranges
 		 (mapcar
 		 (mapcar
 		  (lambda (e)
 		  (lambda (e)
-		    (cons (org-table-formula-handle-@L (car e)) (cdr e)))
+		    (cons (org-table-formula-handle-lastrc (car e)) (cdr e)))
 		  (org-table-get-stored-formulas))))
 		  (org-table-get-stored-formulas))))
 	   (dline (org-table-current-dline))
 	   (dline (org-table-current-dline))
 	   (ref (format "@%d$%d" dline col))
 	   (ref (format "@%d$%d" dline col))
@@ -1975,6 +1975,10 @@ When NAMED is non-nil, look for a named equation."
 	    "\n")))
 	    "\n")))
 
 
 (defsubst org-table-formula-make-cmp-string (a)
 (defsubst org-table-formula-make-cmp-string (a)
+  (when (string-match "\\`$>" a)
+    ;; Fake a high number to make sure this is sorted at the end.
+    (setq a (org-table-formula-handle-lastrc a))
+    (setq a (format "$%d" (+ 10000 (string-to-number (substring a 1))))))
   (when (string-match "^\\(@\\([0-9]+\\)\\)?\\(\\$?\\([0-9]+\\)\\)?\\(\\$?[a-zA-Z0-9]+\\)?" a)
   (when (string-match "^\\(@\\([0-9]+\\)\\)?\\(\\$?\\([0-9]+\\)\\)?\\(\\$?[a-zA-Z0-9]+\\)?" a)
     (concat
     (concat
      (if (match-end 2) (format "@%05d" (string-to-number (match-string 2 a))) "")
      (if (match-end 2) (format "@%05d" (string-to-number (match-string 2 a))) "")
@@ -1994,12 +1998,14 @@ When NAMED is non-nil, look for a named equation."
     (save-excursion
     (save-excursion
       (goto-char (org-table-end))
       (goto-char (org-table-end))
       (when (looking-at "\\([ \t]*\n\\)*[ \t]*#\\+TBLFM: *\\(.*\\)")
       (when (looking-at "\\([ \t]*\n\\)*[ \t]*#\\+TBLFM: *\\(.*\\)")
-	(setq strings (org-split-string (match-string 2) " *:: *"))
+	(setq strings (org-split-string (org-match-string-no-properties 2)
+					" *:: *"))
 	(while (setq string (pop strings))
 	(while (setq string (pop strings))
-	  (when (string-match "\\`\\(@[-+LI0-9.$@]+\\|@?[0-9]+\\|\\$\\([a-zA-Z0-9]+\\)\\) *= *\\(.*[^ \t]\\)" string)
+	  (when (string-match "\\`\\(@[-+I>0-9.$@]+\\|@?[0-9]+\\|\\$\\([a-zA-Z0-9]+\\|>\\(?:[-+][0-9]+\\)?\\)\\) *= *\\(.*[^ \t]\\)" string)
 	    (setq scol (if (match-end 2)
 	    (setq scol (if (match-end 2)
 			   (match-string 2 string)
 			   (match-string 2 string)
 			 (match-string 1 string))
 			 (match-string 1 string))
+		  scol (if (= (string-to-char scol) ?>) (concat "$" scol) scol)
 		  eq (match-string 3 string)
 		  eq (match-string 3 string)
 		  eq-alist (cons (cons scol eq) eq-alist))
 		  eq-alist (cons (cons scol eq) eq-alist))
 	    (if (member scol seen)
 	    (if (member scol seen)
@@ -2388,9 +2394,10 @@ not overwrite the stored one."
 		 t t form)))
 		 t t form)))
 	(setq form0 form)
 	(setq form0 form)
 	;; Insert the references to fields in same row
 	;; Insert the references to fields in same row
-	(while (string-match "\\$\\([0-9]+\\)" form)
-	  (setq n (string-to-number (match-string 1 form))
-		x (nth (1- (if (= n 0) n0 n)) fields))
+	(while (string-match "\\$\\(\\([-+]\\)?[0-9]+\\)" form)
+	  (setq n (+ (string-to-number (match-string 1 form))
+		     (if (match-end 2) n0 0))
+		x (nth (1- (if (= n 0) n0 (max n 1))) fields))
 	  (unless x (error "Invalid field specifier \"%s\""
 	  (unless x (error "Invalid field specifier \"%s\""
 			   (match-string 0 form)))
 			   (match-string 0 form)))
 	  (setq form (replace-match
 	  (setq form (replace-match
@@ -2632,19 +2639,29 @@ known that the table will be realigned a little later anyway."
     (org-table-get-specials)
     (org-table-get-specials)
     (let* ((eqlist (sort (org-table-get-stored-formulas)
     (let* ((eqlist (sort (org-table-get-stored-formulas)
 			 (lambda (a b) (string< (car a) (car b)))))
 			 (lambda (a b) (string< (car a) (car b)))))
+	   (eqlist1 (copy-sequence eqlist))
 	   (inhibit-redisplay (not debug-on-error))
 	   (inhibit-redisplay (not debug-on-error))
 	   (line-re org-table-dataline-regexp)
 	   (line-re org-table-dataline-regexp)
 	   (thisline (org-current-line))
 	   (thisline (org-current-line))
 	   (thiscol (org-table-current-column))
 	   (thiscol (org-table-current-column))
-	   seen-fields
+	   seen-fields lhs1
 	   beg end entry eqlnum eqlname eqlname1 eql (cnt 0) eq a name name1)
 	   beg end entry eqlnum eqlname eqlname1 eql (cnt 0) eq a name name1)
       ;; Insert constants in all formulas
       ;; Insert constants in all formulas
       (setq eqlist
       (setq eqlist
 	    (mapcar (lambda (x)
 	    (mapcar (lambda (x)
+		      (when (string-match "\\`$>" (car x))
+			(setq lhs1 (car x))
+			(setq x (cons (substring
+				       (org-table-formula-handle-lastrc
+					(car x)) 1)
+				      (cdr x)))
+			(if (assoc (car x) eqlist1)
+			    (error "\"%s=\" formula tries to overwrite existing formula for column %s"
+				   lhs1 (car x))))
 		      (cons
 		      (cons
-		       (org-table-formula-handle-@L (car x))
+		       (org-table-formula-handle-lastrc (car x))
 		       (org-table-formula-substitute-names
 		       (org-table-formula-substitute-names
-			(org-table-formula-handle-@L (cdr x)))))
+			(org-table-formula-handle-lastrc (cdr x)))))
 		    eqlist))
 		    eqlist))
       ;; Split the equation list
       ;; Split the equation list
       (while (setq eq (pop eqlist))
       (while (setq eq (pop eqlist))
@@ -2702,6 +2719,7 @@ known that the table will be realigned a little later anyway."
 	  (org-table-goto-column (nth 2 a))
 	  (org-table-goto-column (nth 2 a))
 	  (push (append a (list (cdr eq))) eqlname1)
 	  (push (append a (list (cdr eq))) eqlname1)
 	  (org-table-put-field-property :org-untouchable t)))
 	  (org-table-put-field-property :org-untouchable t)))
+      (setq eqlname1 (nreverse eqlname1))
       
       
       ;; Now evaluate the column formulas, but skip fields covered by
       ;; Now evaluate the column formulas, but skip fields covered by
       ;; field formulas
       ;; field formulas
@@ -2742,7 +2760,9 @@ known that the table will be realigned a little later anyway."
 	  (and all (message "Re-applying formulas...done"))))))
 	  (and all (message "Re-applying formulas...done"))))))
 
 
 (defun org-table-iterate (&optional arg)
 (defun org-table-iterate (&optional arg)
-  "Recalculate the table until it does not change anymore."
+  "Recalculate the table until it does not change anymore.
+The maximun number of iterations is 10, but you can chose a different value
+with the prefix ARG."
   (interactive "P")
   (interactive "P")
   (let ((imax (if arg (prefix-numeric-value arg) 10))
   (let ((imax (if arg (prefix-numeric-value arg) 10))
 	(i 0)
 	(i 0)
@@ -2824,14 +2844,18 @@ them to individual field equations for each field."
 				       :orig-eqn e (caar res)))))))
 				       :orig-eqn e (caar res)))))))
     (nreverse res)))
     (nreverse res)))
 
 
-(defun org-table-formula-handle-@L (s)
-  "Replace @L with the last row data row of the table."
-  (while (string-match "@L\\(-[0-9]+\\)?" s)
+(defun org-table-formula-handle-lastrc (s)
+  "Replace @> / $> with the last row/column of the table."
+  (while (string-match "\\([@$]\\)>\\(-[0-9]+\\)?" s)
     (setq s (replace-match
     (setq s (replace-match
-	     (format "@%d" (+ (length org-table-dlines) -1
-			      (if (match-end 1)
-				  (string-to-number (match-string 1 s))
-				0)))
+	     (format "%s%d"
+		     (match-string 1 s)
+		     (+ (if (equal (match-string 1 s) "@")
+			    (1- (length org-table-dlines))
+			  org-table-current-ncol)
+			(if (match-end 2)
+			    (string-to-number (match-string 2 s))
+			  0)))
 	     t t s)))
 	     t t s)))
   s)
   s)
 
 
@@ -2955,6 +2979,7 @@ Parameters get priority."
     (setq startline (org-current-line))
     (setq startline (org-current-line))
     (while (setq entry (pop eql))
     (while (setq entry (pop eql))
       (setq type (cond
       (setq type (cond
+		  ((string-match "\\`$>" (car entry)) 'column)
 		  ((equal (string-to-char (car entry)) ?@) 'field)
 		  ((equal (string-to-char (car entry)) ?@) 'field)
 		  ((string-match "^[0-9]" (car entry)) 'column)
 		  ((string-match "^[0-9]" (car entry)) 'column)
 		  (t 'named)))
 		  (t 'named)))
@@ -2963,7 +2988,7 @@ Parameters get priority."
 	(insert (org-add-props (cdr title) nil 'face font-lock-comment-face))
 	(insert (org-add-props (cdr title) nil 'face font-lock-comment-face))
 	(setq titles (remove title titles)))
 	(setq titles (remove title titles)))
       (if (equal key (car entry)) (setq startline (org-current-line)))
       (if (equal key (car entry)) (setq startline (org-current-line)))
-      (setq s (concat (if (equal (string-to-char (car entry)) ?@) "" "$")
+      (setq s (concat (if (member (string-to-char (car entry)) '(?@ ?$)) "" "$")
 		      (car entry) " = " (cdr entry) "\n"))
 		      (car entry) " = " (cdr entry) "\n"))
       (remove-text-properties 0 (length s) '(face nil) s)
       (remove-text-properties 0 (length s) '(face nil) s)
       (insert s))
       (insert s))
@@ -3178,7 +3203,7 @@ With prefix ARG, apply the new formulas to the table."
   (let ((pos org-pos) (sel-win org-selected-window) eql var form)
   (let ((pos org-pos) (sel-win org-selected-window) eql var form)
     (goto-char (point-min))
     (goto-char (point-min))
     (while (re-search-forward
     (while (re-search-forward
-	    "^\\(@[-+IL0-9.$@]+\\|@?[0-9]+\\|\\$\\([a-zA-Z0-9]+\\)\\) *= *\\(.*\\(\n[ \t]+.*$\\)*\\)"
+	    "^\\(@[-+I>0-9.$@]+\\|@?[0-9]+\\|\\$\\([a-zA-Z0-9]+\\|>[-+0-9]*\\)\\) *= *\\(.*\\(\n[ \t]+.*$\\)*\\)"
 	    nil t)
 	    nil t)
       (setq var (if (match-end 2) (match-string 2) (match-string 1))
       (setq var (if (match-end 2) (match-string 2) (match-string 1))
 	    form (match-string 3))
 	    form (match-string 3))