]> git.lyx.org Git - features.git/commitdiff
This patch implements proper ERT behaviour for normal layouts.
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Sat, 6 Nov 2010 15:06:19 +0000 (15:06 +0000)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Sat, 6 Nov 2010 15:06:19 +0000 (15:06 +0000)
In particular, it makes paragraph breaks generate single \n in latex output
when ParbreakIsNewline is true

This means that it is not necessary anymore to use newlines to break lines.
Plain paragraph breaks can be used instead, like is done now in ERT/Listings.
This is mainly aimed at sweave support.

lyx2lyx support courtesy of Richard Heck

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@36163 a592a061-630c-0410-9148-cb99ea01b6c8

17 files changed:
lib/layouts/chess.layout
lib/layouts/db_lyxmacros.inc
lib/layouts/db_stdlayouts.inc
lib/layouts/elsart.layout
lib/layouts/lilypond.module
lib/layouts/linguistics.module
lib/layouts/literate-scrap.inc
lib/layouts/noweb.module
lib/layouts/revtex4.layout
lib/layouts/sweave.module
lib/lyx2lyx/lyx2lyx_tools.py
lib/lyx2lyx/lyx_2_0.py
src/Buffer.cpp
src/Cursor.cpp
src/CutAndPaste.cpp
src/Text.cpp
src/output_latex.cpp

index 78ea2164322995f14e5795f0203b9519a21f6b81..910800074a46b9cbc2a8c0568636a11ee4bffe8e 100644 (file)
@@ -42,6 +42,7 @@ Style Mainline
        LabelString           "Mainline:"
        Newline               0
        PassThru              1
+       ParbreakIsNewline     1
        TopSep                0.0
        ParSep                0.0
        LabelFont
index 4b3f790b1368bc946de6b3359b7b6f0dc30db3c9..8db8e8fa8fbcf50b0872ce088ea40f85410d1b46 100644 (file)
@@ -13,6 +13,7 @@ Style Code
        LatexType             Environment
        LatexName             screen
        PassThru              1
+       ParbreakIsNewline     1
 End
 
 Style LyX-Code
index 45a654f8bca220f109a0c2544eb9787cf33b7f09..533fc57a81c162ef7ad2a8d0623f7518c291a59a 100644 (file)
@@ -12,6 +12,7 @@ Style Literal
        LatexType             Environment
        LatexName             literallayout
        PassThru              1
+       ParbreakIsNewline     1
 End
 
 
index b09230e4afe8dae3986dd28145baf891f40648c8..c48eff77818e3adc15bdefd847b194ec0a67a202 100644 (file)
@@ -149,6 +149,7 @@ Style Author_Email
        LatexType             Command
        InTitle               1
        PassThru              1
+       ParbreakIsNewline     1
        LatexName             ead
        Align                 Center
        Labeltype             Static
@@ -169,6 +170,7 @@ Style Author_URL
        LatexType             Command
        InTitle               1
        PassThru              1
+       ParbreakIsNewline     1
        LatexName             ead
        LatexParam            "[url]"
        Align                 Center
index 45508bab6059225fb1acad343c4a3b4118b1a7c8..a01d68a682a2c83a2825296b7233fff868238536 100644 (file)
@@ -28,5 +28,6 @@ InsetLayout LilyPond
        ForcePlain            true
        FreeSpacing           true
        PassThru              true
+       ParbreakIsNewline     true
        ForceLTR              true
 End
index 80772aabb7bd2df6546c8d821d82dfe9a2bc7266..aadaf927a0babd3131e71b656a8f158824cf46d9 100644 (file)
@@ -75,6 +75,7 @@ InsetLayout Flex:Glosse
        CustomPars            false
        ForcePlain            true
        PassThru              true
+       ParbreakIsNewline     true
        FreeSpacing           true
        ForceLTR              true
        Requires              covington
@@ -103,6 +104,7 @@ InsetLayout Flex:Tri-Glosse
        CustomPars            false
        ForcePlain            true
        PassThru              true
+       ParbreakIsNewline     true
        FreeSpacing           true
        ForceLTR              true
        InToc                 true
index 3b0017de0db7d057df7844e243456d033b6265c6..b51553606ff206480fa20f7f6e2e2426b961a26b 100644 (file)
@@ -13,14 +13,10 @@ Style Scrap
        Margin                First_Dynamic
        LatexType             Paragraph
        LatexName             dummy
-       NewLine               0
        LeftMargin            MMM
-       ParSep                0.4
-       TopSep                0.4
-       BottomSep             0.4
-       ItemSep               0.4
        Align                 Left
        AlignPossible         Block,Left
+       NewLine               0
        FreeSpacing           1
        PassThru              1
        ParbreakIsNewline     1
index cc71c338a89108972c7c43b49339be7db08f9100..aff85627a3c9ce5b42faca61f9215ffb9185e7dd 100644 (file)
@@ -4,14 +4,6 @@
 #DescriptionEnd
 #Category: literate
 
-# Suggested style to write your code:
-# Within same scrap, lines are separated by newlines (Ctrl-Return), use:
-#  ItemSep               0.4
-#    . disavantage: must type ctrl-return every single line
-#    . advantage:   looks better (IMHO)
-#                   resembles more closely the produced paper doc (more WYSIWYG)
-#
-
 Format 30
 OutputType              literate
 
@@ -20,14 +12,10 @@ Style Scrap
        Margin                First_Dynamic
        LatexType             Paragraph
        LatexName             dummy
-       NewLine               0
        LeftMargin            MMM
-       ParSep                0.4
-       TopSep                0.4
-       BottomSep             0.4
-       ItemSep               0.4
        Align                 Left
        AlignPossible         Block,Left
+       NewLine               0
        FreeSpacing           1
        PassThru              1
        ParbreakIsNewline     1
index 15fc8dce809b91c786592a209849054c1a43177e..87e99917cf65bd642c9c4b0f0619ef1bd6f5ef5c 100644 (file)
@@ -171,6 +171,7 @@ End
 Style AltAffiliation
        CopyStyle             Affiliation
        PassThru              1
+       ParbreakIsNewline     1
        LatexName             altaffiliation
        OptionalArgs          1
        LabelString           "AltAffiliation"
@@ -196,6 +197,7 @@ End
 Style Author_Email
        CopyStyle             Affiliation
        PassThru              1
+       ParbreakIsNewline     1
        LatexName             email
        OptionalArgs          1
        LabelString           "Electronic Address:"
@@ -211,6 +213,7 @@ End
 Style Author_URL
        CopyStyle             Author_Email
        PassThru              1
+       ParbreakIsNewline     1
        LatexName             homepage
        OptionalArgs          1
        LabelString           "URL:"
index a6821ac49a92d7a06969ff0827bae6ff745aece6..836ff73e857d5fd3b2d87513c879876a32af4e36 100644 (file)
@@ -22,10 +22,6 @@ Style Chunk
        LatexType             Paragraph
        LatexName             dummy
        Margin                static
-       ParSep                0.4
-       TopSep                0.4
-       BottomSep             0.4
-       ItemSep               0.4
        Align                 Left
        AlignPossible         Block, Left, Right, Center
        NewLine               0
@@ -59,7 +55,8 @@ InsetLayout "Sweave Options"
          Size                Small
        EndFont
        MultiPar              false
-       PassThru              true
+       PassThru              1
+       ParbreakIsNewline     1
        FreeSpacing           true
        ForceLTR              true
 End
@@ -79,7 +76,8 @@ InsetLayout "S/R expression"
          Size                Small
        EndFont
        MultiPar              false
-       PassThru              true
+       PassThru              1
+       ParbreakIsNewline     1
        FreeSpacing           true
        ForceLTR              true
 End
@@ -99,7 +97,8 @@ InsetLayout "Sweave Input File"
          Size                Small
        EndFont
        MultiPar              false
-       PassThru              true
+       PassThru              1
+       ParbreakIsNewline     1
        FreeSpacing           true
        ForceLTR              true
 End
index 426e11d9693909f84ee93e6f2322c6dc2197cf99..bff48085960ebe16c6cd65a3805f6501d385a1a4 100644 (file)
@@ -65,7 +65,7 @@ from unicode_symbols import unicode_reps
 
 
 # This will accept either a list of lines or a single line.
-# It is bad practice to pass something with embedded newlines, 
+# It is bad practice to pass something with embedded newlines,
 # though we will handle that.
 def add_to_preamble(document, text):
     " Add text to the preamble if it is not already there. "
index 8f60458d0ff35af016b5a7b29be3c0f3d5d89c7b..624bad934744fdb6f9958ee4a346fbe2b2677e7a 100644 (file)
@@ -1952,6 +1952,142 @@ def convert_bibtex_clearpage(document):
     j = k + len(subst)
 
 
+def check_passthru(document):
+  tc = document.textclass
+  ok = (tc == "literate-article" or tc == "literate-book" or tc == "literate-report")
+  if not ok:
+    mods = document.get_module_list()
+    for mod in mods:
+      if mod == "sweave" or mod == "noweb":
+        ok = True
+        break
+  return ok
+
+
+def convert_passthru(document):
+    " http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg161298.html "
+    if not check_passthru:
+      return
+    
+    rx = re.compile("\\\\begin_layout \s*(\w+)")
+    beg = 0
+    for lay in ["Chunk", "Scrap"]:
+      while True:
+        beg = find_token(document.body, "\\begin_layout " + lay, beg)
+        if beg == -1:
+          break
+        end = find_end_of_layout(document.body, beg)
+        if end == -1:
+          document.warning("Can't find end of layout at line " + str(beg))
+          beg += 1
+          continue
+        # we are now going to replace newline insets within this layout
+        # by new instances of this layout. so we have repeated layouts
+        # instead of newlines.
+        ns = beg
+        while True:
+          ns = find_token(document.body, "\\begin_inset Newline newline", ns, end)
+          if ns == -1:
+            break
+          ne = find_end_of_inset(document.body, ns)
+          if ne == -1 or ne > end:
+            document.warning("Can't find end of inset at line " + str(nb))
+            ns += 1
+            continue
+          if document.body[ne + 1] == "":
+            ne += 1
+          subst = ["\\end_layout", "", "\\begin_layout " + lay]
+          document.body[ns:ne + 1] = subst
+          # now we need to adjust end, in particular, but might as well
+          # do ns properly, too
+          newlines = (ne - ns) - len(subst)
+          ns += newlines + 2
+          end += newlines + 1
+        # ok, we now want to find out if the next layout is the
+        # same as this one. if so, we will insert an extra copy of it
+        didit = False
+        next = find_token(document.body, "\\begin_layout", end)
+        if next != -1:
+          m = rx.match(document.body[next])
+          if m:
+            nextlay = m.group(1)
+            if nextlay == lay:
+              subst = ["\\begin_layout " + lay, "", "\\end_layout", ""]
+              document.body[next:next] = subst
+              didit = True
+        beg = end + 1
+        if didit:
+          beg += 4 # for the extra layout
+    
+
+def revert_passthru(document):
+    " http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg161298.html "
+    if not check_passthru:
+      return
+    rx = re.compile("\\\\begin_layout \s*(\w+)")
+    beg = 0
+    for lay in ["Chunk", "Scrap"]:
+      while True:
+        beg = find_token(document.body, "\\begin_layout " + lay, beg)
+        if beg == -1:
+          break
+        end = find_end_of_layout(document.body, beg)
+        if end == -1:
+          document.warning("Can't find end of layout at line " + str(beg))
+          beg += 1
+          continue
+        
+        # we now want to find out if the next layout is the
+        # same as this one. but we will need to do this over and
+        # over again.
+        while True:
+          next = find_token(document.body, "\\begin_layout", end)
+          if next == -1:
+            break
+          m = rx.match(document.body[next])
+          if not m:
+            break
+          nextlay = m.group(1)
+          if nextlay != lay:
+            break
+          # so it is the same layout again. we now want to know if it is empty.
+          # but first let's check and make sure there is no content between the
+          # two layouts. i'm not sure if that can happen or not.
+          for l in range(end + 1, next):
+            document.warning("c'" + document.body[l] + "'")
+            if document.body[l] != "":
+              document.warning("Found content between adjacent " + lay + " layouts!")
+              break
+          nextend = find_end_of_layout(document.body, next)
+          if nextend == -1:
+            document.warning("Can't find end of layout at line " + str(next))
+            break
+          empty = True
+          for l in range(next + 1, nextend):
+            document.warning("e'" + document.body[l] + "'")
+            if document.body[l] != "":
+              empty = False
+              break
+          if empty:
+            # empty layouts just get removed
+            # should we check if it's before yet another such layout?
+            del document.body[next : nextend + 1]
+            # and we do not want to check again. we know the next layout
+            # should be another Chunk and should be left as is.
+            break
+          else:
+            # if it's not empty, then we want to insert a newline in place
+            # of the layout switch
+            subst = ["\\begin_inset Newline newline", "\\end_inset", ""]
+            document.body[end : next + 1] = subst
+            # and now we have to find the end of the new, larger layout
+            newend = find_end_of_layout(document.body, beg)
+            if newend == -1:
+              document.warning("Can't find end of new layout at line " + str(beg))
+              break
+            end = newend
+        beg = end + 1
+
 ##
 # Conversion hub
 #
@@ -2016,10 +2152,12 @@ convert = [[346, []],
            [402, [convert_bibtex_clearpage]],
            [403, [convert_flexnames]],
            [404, [convert_prettyref]],
-           [405, []]
+           [405, []],
+           [406, [convert_passthru]]
 ]
 
-revert =  [[404, []],
+revert =  [[405, [revert_passthru]],
+           [404, []],
            [403, [revert_refstyle]],
            [402, [revert_flexnames]],
            [401, []],
index 2d2ede3c447455cc373099a33aafdc5588d1e3ee..bf8e496d510d555f8d35f1253b173e37364bf729 100644 (file)
@@ -128,7 +128,7 @@ namespace {
 
 // Do not remove the comment below, so we get merge conflict in
 // independent branches. Instead add your own.
-int const LYX_FORMAT = 405; // vfr: author hash
+int const LYX_FORMAT = 406; // rgh: passthru changes
 
 typedef map<string, bool> DepClean;
 typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;
index f6d10cbc972ab2ca43f0180943e645f791c933c3..c2b6d7298934432adb7cf3fcc59346a2b08023a8 100644 (file)
@@ -26,6 +26,7 @@
 #include "FuncCode.h"
 #include "FuncRequest.h"
 #include "Language.h"
+#include "Layout.h"
 #include "LyXAction.h"
 #include "LyXRC.h"
 #include "Paragraph.h"
@@ -2016,15 +2017,18 @@ void Cursor::errorMessage(docstring const & msg) const
 }
 
 
-static docstring parbreak(InsetCode code)
+namespace {
+docstring parbreak(Cursor const * cur)
 {
        odocstringstream os;
        os << '\n';
-       // only add blank line if we're not in an ERT or Listings inset
-       if (code != ERT_CODE && code != LISTINGS_CODE)
+       // only add blank line if we're not in a ParbreakIsNewline situation
+       if (!cur->inset().getLayout().parbreakIsNewline() 
+           && !cur->paragraph().layout().parbreak_is_newline)
                os << '\n';
        return os.str();
 }
+}
 
 
 docstring Cursor::selectionAsString(bool with_label) const
@@ -2060,13 +2064,13 @@ docstring Cursor::selectionAsString(bool with_label) const
        // First paragraph in selection
        docstring result = pars[startpit].
                asString(startpos, pars[startpit].size(), label)
-               + parbreak(inset().lyxCode());
+               + parbreak(this);
 
        // The paragraphs in between (if any)
        for (pit_type pit = startpit + 1; pit != endpit; ++pit) {
                Paragraph const & par = pars[pit];
                result += par.asString(0, par.size(), label)
-                       + parbreak(inset().lyxCode());
+                       + parbreak(this);
        }
 
        // Last paragraph in selection
index 18993152f341e664fb098e3651f9584fcb22ccdf..9bed935d38eff7ec348cbb6ae179293b26bad45e 100644 (file)
@@ -124,10 +124,9 @@ pasteSelectionHelper(Cursor & cur, ParagraphList const & parlist,
        // Now remove all out of the pars which is NOT allowed in the
        // new environment and set also another font if that is required.
 
-       // Convert newline to paragraph break in ERT inset.
-       // This should not be here!
-       InsetCode const code = target_inset->lyxCode();
-       if (code == ERT_CODE || code == LISTINGS_CODE) {
+       // Convert newline to paragraph break in ParbreakIsNewline
+       if (target_inset->getLayout().parbreakIsNewline()
+           || pars[pit].layout().parbreak_is_newline) {
                for (size_t i = 0; i != insertion.size(); ++i) {
                        for (pos_type j = 0; j != insertion[i].size(); ++j) {
                                if (insertion[i].isNewline(j)) {
index f6f75d90453f631b5c1a459566bf87ea210e9657..63cf1734b9b88551bc5d1301e63b41c75e7d375e 100644 (file)
@@ -599,7 +599,6 @@ static void breakParagraph(Text & text, pit_type par_offset, pos_type pos,
        // end of a paragraph
        tmp->setPlainOrDefaultLayout(bparams.documentClass());
 
-       // layout stays the same with latex-environments
        if (keep_layout) {
                tmp->setLayout(par.layout());
                tmp->setLabelWidthString(par.params().labelWidthString());
@@ -665,7 +664,6 @@ static void breakParagraph(Text & text, pit_type par_offset, pos_type pos,
                par.setPlainOrDefaultLayout(bparams.documentClass());
        }
 
-       // layout stays the same with latex-environments
        if (keep_layout) {
                par.setLayout(tmp->layout());
                par.setLabelWidthString(tmp->params().labelWidthString());
@@ -701,9 +699,10 @@ void Text::breakParagraph(Cursor & cur, bool inverse_logic)
                cpar.eraseChar(cur.pos(), cur.buffer()->params().trackChanges);
 
        // What should the layout for the new paragraph be?
-       bool keep_layout = inverse_logic ? 
-               !layout.isEnvironment() 
-               : layout.isEnvironment();
+       bool keep_layout = layout.isEnvironment() 
+               || (layout.isParagraph() && layout.parbreak_is_newline);
+       if (inverse_logic)
+               keep_layout = !keep_layout;
 
        // We need to remember this before we break the paragraph, because
        // that invalidates the layout variable
index 391ccfaee13f9b233c890b09533c0d411298f97d..ea4d035367b173ddb0498b291e3e3dba099a5f35 100644 (file)
@@ -374,14 +374,18 @@ ParagraphList::const_iterator TeXOnePar(Buffer const & buf,
                open_encoding_ = none;
        }
 
-       if (runparams.pass_thru) {
+       if (text.inset().getLayout().isPassThru()) {
                int const dist = distance(paragraphs.begin(), pit);
                Font const outerfont = text.outerFont(dist);
 
-               // No newline if only one paragraph in this lyxtext
+               // No newline before first paragraph in this lyxtext
                if (dist > 0) {
                        os << '\n';
                        texrow.newline();
+                       if (!text.inset().getLayout().parbreakIsNewline()) {
+                               os << '\n';
+                               texrow.newline();
+                       }
                }
 
                pit->latex(bparams, outerfont, os, texrow,
@@ -389,6 +393,28 @@ ParagraphList::const_iterator TeXOnePar(Buffer const & buf,
                return nextpit;
        }
 
+       if (style.pass_thru) {
+               int const dist = distance(paragraphs.begin(), pit);
+               Font const outerfont = text.outerFont(dist);
+               pit->latex(bparams, outerfont, os, texrow,
+                          runparams, start_pos, end_pos);
+               os << '\n';
+               texrow.newline();
+               if (!style.parbreak_is_newline) {
+                       os << '\n';
+                       texrow.newline();
+               } else if (nextpit != paragraphs.end()) {
+                       Layout const nextstyle = text.inset().forcePlainLayout() ?
+                               bparams.documentClass().plainLayout() : nextpit->layout();
+                       if (nextstyle.name() != style.name()) {
+                               os << '\n';
+                               texrow.newline();
+                       }
+               }
+
+               return nextpit;
+       }
+
        // This paragraph's language
        Language const * const par_language = pit->getParLanguage(bparams);
        // The document's language