Eric Abrahamsen <e...@ericabrahamsen.net> writes:

> Suvayu Ali <fatkasuvayu+li...@gmail.com> writes:
>
>> On Thu, Nov 21, 2013 at 08:11:50AM +0700, Eric Abrahamsen wrote:
>>> Suvayu Ali <fatkasuvayu+li...@gmail.com> writes:
>>> 
>>> > On Wed, Nov 20, 2013 at 03:20:02PM -0600, Russell Adams wrote:
>>> >> On Wed, Nov 20, 2013 at 09:15:43PM +0000, Luke Crook wrote:
>>> >> >
>>> >> > That works.  But that means I need both #+HTML: and #+Latex: for the 
>>> >> > same
>>> >> > thing. \newpage should convert as appropriate depending on the export.
>>> >> >
>>> >> > So, \newpage should translate to the HTML equivalent on HTML export, 
>>> >> > and the
>>> >> > Latex equivalent on Latex export.
>>> >> >
>>> >> > It only works correctly on Latex export
>>> >> 
>>> >> \newpage is a Latex command, and so you need the #+Latex: prefix if
>>> >> you're exporting to multiple formats. That will prevent it from
>>> >> happening.
>>> >
>>> > To add a historical comment, eventhough Org claims to be backend
>>> > neutral, it treats LaTeX preferencially in practice.  e.g. many common
>>> > LaTeX commands/macros are "understood" by Org.
>>> >
>>> > Just follow what Russel said, put them both where you need a pagebreak.
>>> > Try this:
>>> >
>>> > #+MACRO: pagebreak @@latex:\newpage@@ @@html:<div 
>>> > style="page-break-before: always">&nbsp;</div>@@
>>> >
>>> > {{{pagebreak}}}
>>> >
>>> > Hope this helps,
>>> 
>>> Emacs already has the concept of the page-delimiter (defaults to ^L),
>>> for page-related commands. I once floated the idea of making a
>>> page-break a full org element, that could be handled differently by
>>> different backends. I think I made it sound too complicated, though.
>>> Anyway, that's still a possibility.
>>
>> This sounds like good idea.
>
> Let me see if I can dig up my original patch. Plebiscite!

Here's a fairly simple first stab, with page breaks made into an
element, and a sample handling in the LaTeX backend. I've hardcoded ^L
and the page-delimiter regexp that finds it, not sure it's worth
providing an org-page-delimiter shadow. For now, use C-q C-l to insert
the control character.

If this passes muster I can go through the other backends and add
page-break handling where it makes sense. If not, I'll just keep it on
my local branch!

E

>From 377f447623756c5bf07302d99004678e2bfba135 Mon Sep 17 00:00:00 2001
From: Eric Abrahamsen <e...@ericabrahamsen.net>
Date: Fri, 22 Nov 2013 14:41:28 +0700
Subject: [PATCH] Preliminary page break proposal

---
 lisp/org-element.el | 50 +++++++++++++++++++++++++++++++++++++++++++-------
 lisp/ox-latex.el    | 16 ++++++++++++++++
 2 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/lisp/org-element.el b/lisp/org-element.el
index 57e26ff..3e2affb 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -48,10 +48,10 @@
 ;; Other element types are: `babel-call', `clock', `comment',
 ;; `comment-block', `diary-sexp', `example-block', `export-block',
 ;; `fixed-width', `horizontal-rule', `keyword', `latex-environment',
-;; `node-property', `paragraph', `planning', `quote-section',
-;; `src-block', `table', `table-row' and `verse-block'.  Among them,
-;; `paragraph' and `verse-block' types can contain Org objects and
-;; plain text.
+;; `node-property', `page-break', `paragraph', `planning',
+;; `quote-section', `src-block', `table', `table-row' and
+;; `verse-block'.  Among them, `paragraph' and `verse-block' types can
+;; contain Org objects and plain text.
 ;;
 ;; Objects are related to document's contents.  Some of them are
 ;; recursive.  Associated types are of the following: `bold', `code',
@@ -174,8 +174,8 @@ is not sufficient to know if point is at a paragraph ending.  See
   '(babel-call center-block clock comment comment-block diary-sexp drawer
 	       dynamic-block example-block export-block fixed-width
 	       footnote-definition headline horizontal-rule inlinetask item
-	       keyword latex-environment node-property paragraph plain-list
-	       planning property-drawer quote-block quote-section section
+	       keyword latex-environment node-property page-break paragraph
+	       plain-list planning property-drawer quote-block quote-section section
 	       special-block src-block table table-row verse-block)
   "Complete list of element types.")
 
@@ -204,7 +204,7 @@ regexp matching one object can also match the other object.")
 
 (defconst org-element-all-objects
   '(bold code entity export-snippet footnote-reference inline-babel-call
-	 inline-src-block italic line-break latex-fragment link macro
+	 inline-src-block italic line-break latex-fragment link macro page-break
 	 radio-target statistics-cookie strike-through subscript superscript
 	 table-cell target timestamp underline verbatim)
   "Complete list of object types.")
@@ -2051,6 +2051,40 @@ CONTENTS is nil."
 	  (org-element-property :value node-property)))
 
 
+;;;; Page Break
+
+(defun org-element-page-break-parser (limit affiliated)
+  "Parse a page break.
+
+LIMIT bounds the search.  AFFILIATED is a list of which CAR is
+the buffer position at the beginning of the first affiliated
+keyword and CDR is a plist of affiliated keywords along with
+their value.
+
+Return a list whose CAR is `page-break' and CDR is a plist
+containing `:begin', `:end', `:post-blank' and `:post-affiliated'
+keywords.
+"
+  (save-excursion
+    (let ((begin (car affiliated))
+	  (post-affiliated (point))
+	  (post-pb (progn (forward-line) (point)))
+	  (end (progn (skip-chars-forward " \r\t\n" limit)
+		      (if (eobp) (point) (line-beginning-position)))))
+      (list 'page-break
+	    (nconc
+	     (list :begin begin
+		   :end end
+		   :post-blank (count-lines post-pb end)
+		   :post-affiliated post-affiliated)
+	     (cdr affiliated))))))
+
+(defun org-element-page-break-interpreter (page-break contents)
+  "Interpret PAGE-BREAK element as Org syntax.
+CONTENTS is nil."
+  "")
+
+
 ;;;; Paragraph
 
 (defun org-element-paragraph-parser (limit affiliated)
@@ -3845,6 +3879,8 @@ element it has to parse."
 	     ;; Horizontal Rule.
 	     ((looking-at "[ \t]*-\\{5,\\}[ \t]*$")
 	      (org-element-horizontal-rule-parser limit affiliated))
+	     ((looking-at page-delimiter)
+	      (org-element-page-break-parser limit affiliated))
 	     ;; Diary Sexp.
 	     ((looking-at "%%(")
 	      (org-element-diary-sexp-parser limit affiliated))
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 3faeb53..2cf26b1 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -67,6 +67,7 @@
     (link . org-latex-link)
     (node-property . org-latex-node-property)
     (paragraph . org-latex-paragraph)
+    (page-break . org-latex-page-break)
     (plain-list . org-latex-plain-list)
     (plain-text . org-latex-plain-text)
     (planning . org-latex-planning)
@@ -379,6 +380,13 @@ which format headlines like for Org version prior to 8.0."
   :type 'string)
 
 
+;;;; Page Breaks
+
+(defcustom org-latex-default-page-break "\\newpage"
+  "Default page break type."
+  :group 'org-export-latex
+  :type 'string)
+
 ;;;; Timestamps
 
 (defcustom org-latex-active-timestamp-format "\\textit{%s}"
@@ -1865,6 +1873,14 @@ the plist used as a communication channel."
   contents)
 
 
+;;;; Page Break
+
+(defun org-latex-page-break (page-break contents info)
+  "Transcode a PAGE-BREAK 3element from Org to LaTeX.
+CONTENTS is nil.  INFO is the plist used as a communication
+channel."
+  org-latex-default-page-break)
+
 ;;;; Plain List
 
 (defun org-latex-plain-list (plain-list contents info)
-- 
1.8.4.2

Reply via email to