]> git.lyx.org Git - features.git/commitdiff
Patch to convert Sweave chunk paragraphs to insets (bug #8588). Work
authorRichard Heck <rgheck@lyx.org>
Thu, 30 May 2013 13:12:48 +0000 (09:12 -0400)
committerRichard Heck <rgheck@lyx.org>
Thu, 30 May 2013 14:20:34 +0000 (10:20 -0400)
by Liviu (C++) and Richard (Python).

lib/Makefile.am
lib/layouts/knitr.module
lib/layouts/litinsets.inc [new file with mode: 0644]
lib/layouts/noweb.module
lib/layouts/sweave.module
lib/lyx2lyx/lyx_2_1.py
lib/lyx2lyx/parser_tools.py
src/version.h

index cfdbc94b69332595050d73752bb698b2c5b3f8d4..39340a2d57394f7a32bff0be754460d7abc652c4 100644 (file)
@@ -1932,6 +1932,7 @@ dist_layouts_DATA =\
        layouts/lettre.layout \
        layouts/lilypond.module \
        layouts/linguistics.module \
+       layouts/litinsets.inc \
        layouts/llncs.layout \
        layouts/logicalmkup.module \
        layouts/ltugboat.layout \
index 020397324afbe2ff71995f295efb7567a60206e2..e7ccb342226cae7df1569a21d8e80af904601f49 100644 (file)
@@ -7,35 +7,10 @@
 #Excludes: lilypond | sweave
 
 Format 45
+Input litinsets.inc
 OutputType             literate
 OutputFormat           knitr
 
-Style Chunk
-       Category              Sweave
-       LatexType             Paragraph
-       LatexName             dummy
-       Margin                static
-       Align                 Left
-       AlignPossible         Block, Left, Right, Center
-       TopSep                0.7
-       BottomSep             0.7
-       NewLine               0
-       FreeSpacing           1
-       PassThru              1
-       ParbreakIsNewline     1
-       Spellcheck            0
-       ## What is LabelType used for?
-       LabelType             Static
-       TextFont
-         Color               latex
-         Family              Typewriter
-       EndFont
-End
-
-Style Scrap
-       ObsoletedBy           Chunk
-End
-
 InsetLayout "Flex:Sweave Options"
        LabelString           "Sweave opts"
        LatexType             Command
diff --git a/lib/layouts/litinsets.inc b/lib/layouts/litinsets.inc
new file mode 100644 (file)
index 0000000..4f95019
--- /dev/null
@@ -0,0 +1,41 @@
+# Literate Chunk inset definitions.
+# This defines the Chunk inset used in the literate modules.
+#
+# Author: Liviu Andronic <landronimirc@gmail.com>
+#
+# Note that this file is included in sweave.module,
+# knitr.module and noweb.module.
+
+Format 45
+
+InsetLayout "Flex:Chunk"
+        LabelString           "Chunk"
+        LatexType             none
+        LyXType               Custom
+        RightDelim            <br/>@
+        Decoration            Classic
+       Font
+         Color               latex
+         Family              typewriter
+       EndFont
+       #LabelFont
+         #Color               latex
+         #Size                Small
+       #EndFont
+        MultiPar              true
+       CustomPars            false
+       ForcePlain            true
+        PassThru              1
+        ParbreakIsNewline     1
+       KeepEmpty             true
+        Spellcheck            0
+        FreeSpacing           true
+        ForceLTR              true
+        Argument 1
+                Mandatory     1
+                LabelString   "Options"
+                Tooltip       "Options"
+                LeftDelim     <<
+                RightDelim    >>=<br/>
+        EndArgument
+End
index fc105fd051ac7dc93beb507b98345dad3e763db8..da8e96b8aaedae254101c36eeb6da10d042b2ca0 100644 (file)
@@ -5,30 +5,9 @@
 #Category: literate
 
 Format 45
+Input litinsets.inc
 OutputType              literate
 
 AddToPreamble
        \usepackage{noweb}
 EndPreamble
-
-Style Chunk
-       Margin                First_Dynamic
-       LatexType             Paragraph
-       LatexName             dummy
-       LeftMargin            MMM
-       Align                 Left
-       AlignPossible         Block,Left
-       NewLine               0
-       FreeSpacing           1
-       PassThru              1
-       ParbreakIsNewline     1
-       Spellcheck            0
-       LabelType             Static
-       LabelFont
-         Color               magenta
-       EndFont
-       TextFont
-         Color               latex
-         Family              Typewriter
-       EndFont
-End
index 912642040d0d76cc581591f98dd2f36fe3253b94..dd0e642ef138325a52428aefa3a3f5f8e14cba0a 100644 (file)
@@ -7,6 +7,7 @@
 #Excludes: lilypond
 
 Format 45
+Input litinsets.inc
 OutputType             literate
 OutputFormat           sweave
 
@@ -20,32 +21,6 @@ AddToPreamble
        @
 EndPreamble
 
-Style Chunk
-       Category              Sweave
-       LatexType             Paragraph
-       LatexName             dummy
-       Margin                static
-       Align                 Left
-       AlignPossible         Block, Left, Right, Center
-       TopSep                0.7
-       BottomSep             0.7
-       NewLine               0
-       FreeSpacing           1
-       PassThru              1
-       ParbreakIsNewline     1
-       Spellcheck            0
-       ## What is LabelType used for?
-       LabelType             Static
-       TextFont
-         Color               latex
-         Family              Typewriter
-       EndFont
-End
-
-Style Scrap
-       ObsoletedBy           Chunk
-End
-
 InsetLayout "Flex:Sweave Options"
        LabelString           "Sweave opts"
        LatexType             Command
index 0c38796f6f5161b69fc3c64e0915e6273365f2a5..c95e94b174934589fc75fb4ba7de621b73fe3fe4 100644 (file)
@@ -4229,6 +4229,171 @@ def revert_tibetan(document):
             j = len(document.body)
 
 
+#############
+#
+# Chunk stuff
+#
+#############
+
+# the idea here is that we will have a sequence of chunk paragraphs
+# we want to convert them to paragraphs in a chunk inset
+# the last will be discarded
+# the first should look like: <<FROGS>>=
+# will will discard the delimiters, and put the contents into the
+# optional argument of the inset
+def convert_chunks(document):
+    first_re = re.compile(r'<<(.*)>>=')
+    k = 0
+    while True:
+        # the beginning of this sequence
+        i = k
+        # find start of a block of chunks
+        i = find_token(document.body, "\\begin_layout Chunk", i)
+        if i == -1:
+            return
+        start = i
+        end = -1
+        contents = []
+
+        while True:
+            # process the one we just found
+            j = find_end_of_layout(document.body, i)
+            if j == -1:
+                document.warning("Malformed LyX documents. Can't find end of Chunk layout!")
+                break
+            thischunk = "".join(document.body[i + 1:j])
+            contents.append(thischunk)
+            
+            if thischunk == "@":
+                break
+
+            # look for the next one
+            i = j
+            i = find_token(document.body, "\\begin_layout", i)
+            if i == -1:
+                break
+
+            layout = get_value(document.body, "\\begin_layout", i)
+            #sys.stderr.write(layout+ '\n')
+            if layout != "Chunk":
+                k = i
+                break
+
+        if j == -1:
+            # error, but we can try to continue
+            k = j + 1
+            continue
+
+        end = j + 1
+        k = end
+
+        sys.stderr.write('\n'.join(contents) + '\n\n')
+
+        # the last chunk should simply have an "@" in it
+        # we could check that
+        contents.pop()
+
+        # the first item should look like: <<FROGS>>=
+        # we want the inside
+        optarg = contents[0]
+        optarg.strip()
+        match = first_re.search(optarg)
+        if match:
+            optarg = match.groups()[0]
+            contents.pop(0)
+
+        newstuff = ['\\begin_layout Standard',
+                    '\\begin_inset Flex Chunk',
+                    'status open', '',
+                    '\\begin_layout Plain Layout', '']
+
+        if match:
+            newstuff.extend(
+                ['\\begin_inset Argument 1',
+                 'status open', '',
+                 '\\begin_layout Plain Layout',
+                 optarg,
+                 '\\end_layout', '',
+                 '\\end_inset', ''])
+
+        didone = False
+        for c in contents:
+            if didone:
+                newstuff.extend(['', '\\begin_layout Plain Layout', ''])
+            else:
+                didone = True
+            newstuff.extend([c, '\\end_layout'])
+
+        newstuff.extend(['', '\\end_inset', '', '\\end_layout', ''])
+
+        document.body[start:end] = newstuff
+
+        k += len(newstuff) - (end - start)
+
+
+def revert_chunks(document):
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset Flex Chunk", i)
+        if i == -1:
+            return
+
+        iend = find_end_of_inset(document.body, i)
+        if iend == -1:
+            document.warning("Can't find end of Chunk!")
+            i += 1
+            continue
+
+        # Look for optional argument
+        have_optarg = False
+        ostart = find_token(document.body, "\\begin_inset Argument 1", i, iend)
+        if ostart != -1:
+            oend = find_end_of_inset(document.body, ostart)
+            k = find_token(document.body, "\\begin_layout Plain Layout", ostart, oend)
+            if k == -1:
+                document.warning("Malformed LyX document: Can't find argument contents!")
+            else:
+                m = find_end_of_layout(document.body, k)
+                optarg = "".join(document.body[k+1:m])
+                have_optarg = True
+
+            # We now remove the optional argument, so we have something
+            # uniform on which to work
+            document.body[ostart : oend + 1] = []
+            # iend is now invalid
+            iend = find_end_of_inset(document.body, i)
+
+        retval = get_containing_layout(document.body, i)
+        if not retval:
+            document.warning("Can't find containing layout for Chunk!")
+            i = iend
+            continue
+        (lname, lstart, lend, pstart)  = retval
+        # we now want to work through the various paragraphs, and collect their contents
+        parlist = []
+        k = i
+        while True:
+            k = find_token(document.body, "\\begin_layout Plain Layout", k, lend)
+            if k == -1:
+                break
+            j = find_end_of_layout(document.body, k)
+            if j == -1:
+                document.warning("Can't find end of layout inside chunk!")
+                break
+            parlist.append(document.body[k+1:j])
+            k = j
+        # we now need to wrap all of these paragraphs in chunks
+        newlines = []
+        if have_optarg:
+            newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
+        for stuff in parlist:
+            newlines.extend(["\\begin_layout Chunk"] + stuff + ["\\end_layout", ""])
+        newlines.extend(["\\begin_layout Chunk", "", "@", "\\end_layout", ""])
+        # replace old content with new content
+        document.body[lstart : lend + 1] = newlines
+        i = lstart + len(newlines)
+        
+
 ##
 # Conversion hub
 #
@@ -4294,10 +4459,12 @@ convert = [
            [470, []],
            [471, [convert_cite_engine_type_default]],
            [472, []],
-           [473, []]
+           [473, []],
+           [474, [convert_chunks]],
           ]
 
 revert =  [
+           [473, [revert_chunks]],
            [472, [revert_tibetan]],
            [471, [revert_aa1,revert_aa2]],
            [470, [revert_cite_engine_type_default]],
index 4c5197a534b165bc36c4f88e6f9a1211df774488..c989515e4120156e7f8068e7866f3dd2845a20d8 100644 (file)
@@ -449,9 +449,10 @@ def get_containing_inset(lines, i):
 def get_containing_layout(lines, i):
   ''' 
   Finds out what kind of layout line i is within. Returns a 
-  list containing (i) what follows \begin_layout on the line 
+  list containing what follows \begin_layout on the line 
   on which the layout begins, plus the starting and ending line
-  and the start of the apargraph (after all params).
+  and the start of the paragraph (after all params). I.e, returns:
+    (layoutname, layoutstart, layoutend, startofcontent)
   Returns False on any kind of error.
   '''
   j = i
index 3aa8ce8330edd6595165efa9dea3540b02bc6d91..99c446760e5bb22536043640b013ca0e71cb748e 100644 (file)
@@ -30,7 +30,7 @@ extern char const * const lyx_version_info;
 
 // Do not remove the comment below, so we get merge conflict in
 // independent branches. Instead add your own.
-#define LYX_FORMAT_LYX 473 // uwestoehr: support Tibetan as document language
+#define LYX_FORMAT_LYX 474 // rgh: dummy format change for Chunk switch
 #define LYX_FORMAT_TEX2LYX 473
 
 #if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX