]> git.lyx.org Git - features.git/commitdiff
fixes to lyx2lyx's revert_language tool.
authorGünter Milde <milde@lyx.org>
Wed, 29 May 2019 22:07:33 +0000 (00:07 +0200)
committerGünter Milde <milde@lyx.org>
Sat, 1 Jun 2019 22:04:34 +0000 (00:04 +0200)
autotests/export/latex/languages/supported-languages_polyglossia.lyx
autotests/export/lyx2lyx/revert-languages-babel-primary.lyx [new file with mode: 0644]
autotests/export/lyx2lyx/revert-languages-babel.lyx
autotests/export/lyx2lyx/revert-languages-polyglossia-primary.lyx [new file with mode: 0644]
lib/lyx2lyx/lyx2lyx_tools.py

index 8695a1dfde1fe6d01d5001338fd10ba20a6246ab..2c693b1792ae04bfed164c2fea82b9d4b86ecd5a 100644 (file)
@@ -1,14 +1,15 @@
 #LyX 2.4 created this file. For more info see https://www.lyx.org/
-\lyxformat 574
+\lyxformat 575
 \begin_document
 \begin_header
 \save_transient_properties true
 \origin unavailable
 \textclass scrartcl
 \begin_preamble
-\newfontfamily\amharicfont[Script=Ethiopic]{Noto Sans Ethiopic}
-\newfontfamily\thaanafont[Script=Thaana]{Noto Sans Thaana}
+\newfontfamily\amharicfont{NotoSansEthiopic}
+\newfontfamily\churchslavonicfont[Script=Cyrillic]{MonomakhUnicode}
 \newfontfamily\devanagarifont[Script=Devanagari]{Noto Serif Devanagari}
+\newfontfamily\hangulfont[Script=Hangul]{Baekmuk Batang}
 \newfontfamily\kannadafont[Script=Kannada]{Noto Serif Kannada}
 \newfontfamily\khmerfont[Script=Khmer]{Noto Serif Khmer}
 \newfontfamily\laofont[Script=Lao]{Noto Serif Lao}
@@ -17,6 +18,7 @@
 \newfontfamily\syriacfont[Script=Syriac]{FreeSans}
 \newfontfamily\tamilfont[Script=Tamil]{Noto Serif Tamil}
 \newfontfamily\telugufont[Script=Telugu]{Noto Serif Telugu}
+\newfontfamily\thaanafont[Script=Thaana]{Noto Sans Thaana}
 \newfontfamily\tibetanfont[Script=Tibetan]{Noto Sans Tibetan}
 
 
@@ -105,6 +107,8 @@ enumitem
 \justification false
 \use_refstyle 0
 \use_minted 0
+\use_lineno 0
+\lineno_options 
 \branch only-as-document-language
 \selected 0
 \filename_suffix 0
@@ -151,7 +155,7 @@ enumitem
 \color #faf0e6
 \end_branch
 \branch conflict-babel-non-TeX-fonts
-\selected 0
+\selected 1
 \filename_suffix 0
 \color #faf0e6
 \end_branch
@@ -160,6 +164,11 @@ enumitem
 \filename_suffix 0
 \color #faf0e6
 \end_branch
+\branch conflict-luatex
+\selected 1
+\filename_suffix 0
+\color #faf0e6
+\end_branch
 \index Stichwortverzeichnis
 \shortcut idx
 \color #008000
diff --git a/autotests/export/lyx2lyx/revert-languages-babel-primary.lyx b/autotests/export/lyx2lyx/revert-languages-babel-primary.lyx
new file mode 100644 (file)
index 0000000..7f17b9a
--- /dev/null
@@ -0,0 +1,345 @@
+#LyX 2.4 created this file. For more info see https://www.lyx.org/
+\lyxformat 575
+\begin_document
+\begin_header
+\save_transient_properties true
+\origin unavailable
+\textclass article
+\begin_preamble
+\@ifpackageloaded{fontspec}%
+  {\newfontfamily\friulanfont{FreeSans}}%
+  {\usepackage{babel}
+   \addto\extrasfrilulan{\sffamily}}
+\end_preamble
+\use_default_options true
+\maintain_unincluded_children false
+\language friulan
+\language_package default
+\inputencoding utf8
+\fontencoding auto
+\font_roman "lmodern" "default"
+\font_sans "default" "default"
+\font_typewriter "default" "default"
+\font_math "auto" "auto"
+\font_default_family default
+\use_non_tex_fonts false
+\font_sc false
+\font_osf false
+\font_sf_scale 100 100
+\font_tt_scale 100 100
+\use_microtype false
+\use_dash_ligatures true
+\graphics default
+\default_output_format default
+\output_sync 0
+\bibtex_command default
+\index_command default
+\float_placement class
+\float_alignment class
+\paperfontsize default
+\spacing single
+\use_hyperref false
+\papersize default
+\use_geometry false
+\use_package amsmath 1
+\use_package amssymb 1
+\use_package cancel 1
+\use_package esint 1
+\use_package mathdots 1
+\use_package mathtools 1
+\use_package mhchem 1
+\use_package stackrel 1
+\use_package stmaryrd 1
+\use_package undertilde 1
+\cite_engine basic
+\cite_engine_type default
+\biblio_style plain
+\use_bibtopic false
+\use_indices false
+\paperorientation portrait
+\suppress_date false
+\justification true
+\use_refstyle 1
+\use_minted 0
+\use_lineno 0
+\lineno_options \index Index
+\index Index
+\shortcut idx
+\color #008000
+\end_index
+\secnumdepth 3
+\tocdepth 3
+\paragraph_separation indent
+\paragraph_indentation default
+\is_math_indent 0
+\math_numbering_side default
+\quotes_style french
+\dynamic_quotes 0
+\papercolumns 1
+\papersides 1
+\paperpagestyle default
+\tablestyle default
+\tracking_changes false
+\output_changes false
+\html_math_output 0
+\html_css_as_file 0
+\html_be_strict false
+\end_header
+
+\begin_body
+
+\begin_layout Standard
+
+\lang english
+Friulan Document mixing English and Friulan text.
+\end_layout
+
+\begin_layout Standard
+This is a Friulan paragraph.
+\end_layout
+
+\begin_layout Standard
+
+\lang english
+English paragraph with one 
+\lang friulan
+Friulan
+\lang english
+ word.
+\end_layout
+
+\begin_layout Standard
+Friulan paragraph
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+
+\lang english
+English footnote
+\end_layout
+
+\end_inset
+
+ with one 
+\lang english
+English
+\lang friulan
+ word.
+\end_layout
+
+\begin_layout Quote
+This is a Friulan quote.
+\end_layout
+
+\begin_layout Standard
+
+\lang english
+Followed by an English
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+Friulan footnote
+\lang english
+ not recognized by the lyx2lyx emulation.
+\end_layout
+
+\end_inset
+
+ paragraph.
+\end_layout
+
+\begin_layout Enumerate
+
+\lang english
+List with
+\end_layout
+
+\begin_layout Enumerate
+Friulan paragraphs
+\end_layout
+
+\begin_deeper
+\begin_layout Itemize
+
+\lang english
+with nested item list with English item
+\end_layout
+
+\begin_layout Itemize
+and Friulan list item.
+\end_layout
+
+\end_deeper
+\begin_layout Enumerate
+in the middle
+\end_layout
+
+\begin_layout Enumerate
+
+\lang english
+of it.
+\end_layout
+
+\begin_layout Standard
+
+\lang english
+\begin_inset Float table
+placement document
+alignment document
+wide false
+sideways false
+status open
+
+\begin_layout Plain Layout
+
+\lang english
+\begin_inset Caption Standard
+
+\begin_layout Plain Layout
+Friulan text in English caption inset
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+\lang english
+\begin_inset Tabular
+<lyxtabular version="3" rows="2" columns="2">
+<features tabularvalignment="middle">
+<column alignment="center" valignment="top">
+<column alignment="center" valignment="top">
+<row>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\lang english
+table
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+with
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+Friulan
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\lang english
+cells
+\end_layout
+
+\end_inset
+</cell>
+</row>
+</lyxtabular>
+
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\lang english
+Friulan table cells not recognised if the table has outer language English.
+\end_layout
+
+\begin_layout Labeling
+\labelwidthstring 00.00.0000
+
+\lang english
+Lyxlist with
+\end_layout
+
+\begin_layout Labeling
+\labelwidthstring 00.00.0000
+Friulan item
+\end_layout
+
+\begin_layout Labeling
+\labelwidthstring 00.00.0000
+label
+\lang english
+ and
+\end_layout
+
+\begin_layout Labeling
+\labelwidthstring 00.00.0000
+
+\lang english
+also 
+\lang friulan
+content
+\end_layout
+
+\begin_layout Labeling
+\labelwidthstring 00.00.0000
+
+\lang english
+inside it.
+\end_layout
+
+\begin_layout Description
+
+\lang english
+Description with
+\end_layout
+
+\begin_layout Description
+Friulan item
+\end_layout
+
+\begin_layout Description
+label 
+\lang english
+and
+\end_layout
+
+\begin_layout Description
+
+\lang english
+also
+\lang friulan
+ content
+\end_layout
+
+\begin_layout Description
+
+\lang english
+inside it.
+\end_layout
+
+\end_body
+\end_document
index 4d5faa636e7e7a71171975cbff43db4d91dba319..26999cba76032f644c51a62649c9c5d956ceebb9 100644 (file)
@@ -27,7 +27,7 @@
 \font_sf_scale 100 100
 \font_tt_scale 100 100
 \use_microtype false
-\use_dash_ligatures true
+\use_dash_ligatures false
 \graphics default
 \default_output_format default
 \output_sync 0
@@ -88,7 +88,7 @@
 \begin_body
 
 \begin_layout Standard
-Document mixing English and Friulan text.
+English document mixing English and Friulan text.
 \end_layout
 
 \begin_layout Standard
@@ -98,13 +98,33 @@ This is a Friulan paragraph.
 \end_layout
 
 \begin_layout Standard
-Followed by an English paragraph with one 
+English paragraph with one 
 \lang friulan
 Friulan
 \lang english
  word.
 \end_layout
 
+\begin_layout Standard
+
+\lang friulan
+Friulan paragraph
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+English footnote
+\end_layout
+
+\end_inset
+
+ with one 
+\lang english
+English
+\lang friulan
+ word.
+\end_layout
+
 \begin_layout Quote
 
 \lang friulan
@@ -134,9 +154,21 @@ List with
 \begin_layout Enumerate
 
 \lang friulan
-Friulan paragraphs
+Friulan paragraph
+\end_layout
+
+\begin_deeper
+\begin_layout Itemize
+with nested item list with English item
+\end_layout
+
+\begin_layout Itemize
+
+\lang friulan
+and Friulan list item.
 \end_layout
 
+\end_deeper
 \begin_layout Enumerate
 
 \lang friulan
@@ -224,10 +256,6 @@ cells
 \end_inset
 
 
-\end_layout
-
-\begin_layout Plain Layout
-
 \end_layout
 
 \end_inset
@@ -248,14 +276,21 @@ Lyxlist with
 \labelwidthstring 00.00.0000
 
 \lang friulan
-Friulan
+Friulan item
+\end_layout
+
+\begin_layout Labeling
+\labelwidthstring 00.00.0000
+
+\lang friulan
+label
 \lang english
label and
+ and
 \end_layout
 
 \begin_layout Labeling
 \labelwidthstring 00.00.0000
-Friulan 
+also 
 \lang friulan
 content
 \end_layout
@@ -265,5 +300,33 @@ content
 inside it.
 \end_layout
 
+\begin_layout Description
+Description with
+\end_layout
+
+\begin_layout Description
+
+\lang friulan
+Friulan item
+\end_layout
+
+\begin_layout Description
+
+\lang friulan
+label 
+\lang english
+and
+\end_layout
+
+\begin_layout Description
+also
+\lang friulan
+ content
+\end_layout
+
+\begin_layout Description
+inside it.
+\end_layout
+
 \end_body
 \end_document
diff --git a/autotests/export/lyx2lyx/revert-languages-polyglossia-primary.lyx b/autotests/export/lyx2lyx/revert-languages-polyglossia-primary.lyx
new file mode 100644 (file)
index 0000000..5e76117
--- /dev/null
@@ -0,0 +1,345 @@
+#LyX 2.4 created this file. For more info see https://www.lyx.org/
+\lyxformat 575
+\begin_document
+\begin_header
+\save_transient_properties true
+\origin unavailable
+\textclass article
+\begin_preamble
+\@ifpackageloaded{fontspec}%
+  {\newfontfamily\friulanfont{FreeSans}}%
+  {\usepackage{babel}
+   \addto\extrasfrilulan{\sffamily}}
+\end_preamble
+\use_default_options true
+\maintain_unincluded_children false
+\language friulan
+\language_package default
+\inputencoding utf8
+\fontencoding auto
+\font_roman "lmodern" "default"
+\font_sans "default" "default"
+\font_typewriter "default" "default"
+\font_math "auto" "auto"
+\font_default_family default
+\use_non_tex_fonts true
+\font_sc false
+\font_osf false
+\font_sf_scale 100 100
+\font_tt_scale 100 100
+\use_microtype false
+\use_dash_ligatures true
+\graphics default
+\default_output_format default
+\output_sync 0
+\bibtex_command default
+\index_command default
+\float_placement class
+\float_alignment class
+\paperfontsize default
+\spacing single
+\use_hyperref false
+\papersize default
+\use_geometry false
+\use_package amsmath 1
+\use_package amssymb 1
+\use_package cancel 1
+\use_package esint 1
+\use_package mathdots 1
+\use_package mathtools 1
+\use_package mhchem 1
+\use_package stackrel 1
+\use_package stmaryrd 1
+\use_package undertilde 1
+\cite_engine basic
+\cite_engine_type default
+\biblio_style plain
+\use_bibtopic false
+\use_indices false
+\paperorientation portrait
+\suppress_date false
+\justification true
+\use_refstyle 1
+\use_minted 0
+\use_lineno 0
+\lineno_options \index Index
+\index Index
+\shortcut idx
+\color #008000
+\end_index
+\secnumdepth 3
+\tocdepth 3
+\paragraph_separation indent
+\paragraph_indentation default
+\is_math_indent 0
+\math_numbering_side default
+\quotes_style french
+\dynamic_quotes 0
+\papercolumns 1
+\papersides 1
+\paperpagestyle default
+\tablestyle default
+\tracking_changes false
+\output_changes false
+\html_math_output 0
+\html_css_as_file 0
+\html_be_strict false
+\end_header
+
+\begin_body
+
+\begin_layout Standard
+
+\lang english
+Friulan Document mixing English and Friulan text.
+\end_layout
+
+\begin_layout Standard
+This is a Friulan paragraph.
+\end_layout
+
+\begin_layout Standard
+
+\lang english
+English paragraph with one 
+\lang friulan
+Friulan
+\lang english
+ word.
+\end_layout
+
+\begin_layout Standard
+Friulan paragraph
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+
+\lang english
+English footnote
+\end_layout
+
+\end_inset
+
+ with one 
+\lang english
+English
+\lang friulan
+ word.
+\end_layout
+
+\begin_layout Quote
+This is a Friulan quote.
+\end_layout
+
+\begin_layout Standard
+
+\lang english
+Followed by an English
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+Friulan footnote
+\lang english
+ not recognized by the lyx2lyx emulation.
+\end_layout
+
+\end_inset
+
+ paragraph.
+\end_layout
+
+\begin_layout Enumerate
+
+\lang english
+List with
+\end_layout
+
+\begin_layout Enumerate
+Friulan paragraphs
+\end_layout
+
+\begin_deeper
+\begin_layout Itemize
+
+\lang english
+with nested item list with English item
+\end_layout
+
+\begin_layout Itemize
+and Friulan list item.
+\end_layout
+
+\end_deeper
+\begin_layout Enumerate
+in the middle
+\end_layout
+
+\begin_layout Enumerate
+
+\lang english
+of it.
+\end_layout
+
+\begin_layout Standard
+
+\lang english
+\begin_inset Float table
+placement document
+alignment document
+wide false
+sideways false
+status open
+
+\begin_layout Plain Layout
+
+\lang english
+\begin_inset Caption Standard
+
+\begin_layout Plain Layout
+Friulan text in English caption inset
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+\lang english
+\begin_inset Tabular
+<lyxtabular version="3" rows="2" columns="2">
+<features tabularvalignment="middle">
+<column alignment="center" valignment="top">
+<column alignment="center" valignment="top">
+<row>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\lang english
+table
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+with
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+Friulan
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\lang english
+cells
+\end_layout
+
+\end_inset
+</cell>
+</row>
+</lyxtabular>
+
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\lang english
+Friulan table cells not recognised if the table has outer language English.
+\end_layout
+
+\begin_layout Labeling
+\labelwidthstring 00.00.0000
+
+\lang english
+Lyxlist with
+\end_layout
+
+\begin_layout Labeling
+\labelwidthstring 00.00.0000
+Friulan item
+\end_layout
+
+\begin_layout Labeling
+\labelwidthstring 00.00.0000
+label
+\lang english
+ and
+\end_layout
+
+\begin_layout Labeling
+\labelwidthstring 00.00.0000
+
+\lang english
+also 
+\lang friulan
+content
+\end_layout
+
+\begin_layout Labeling
+\labelwidthstring 00.00.0000
+
+\lang english
+inside it.
+\end_layout
+
+\begin_layout Description
+
+\lang english
+Description with
+\end_layout
+
+\begin_layout Description
+Friulan item
+\end_layout
+
+\begin_layout Description
+label 
+\lang english
+and
+\end_layout
+
+\begin_layout Description
+
+\lang english
+also
+\lang friulan
+ content
+\end_layout
+
+\begin_layout Description
+
+\lang english
+inside it.
+\end_layout
+
+\end_body
+\end_document
index fd641385b88d176a349830a4f1b743ce3aa1c700..d59ec15175313010922e3ecd7b8c1d60062a733c 100644 (file)
@@ -90,8 +90,10 @@ revert_language(document, lyxname, babelname="", polyglossianame=""):
   this language package is not supported for the given language.
 '''
 
+from __future__ import print_function
 import re, sys
-from parser_tools import find_token, find_end_of_inset, get_containing_layout, get_value, get_bool_value
+from parser_tools import (find_token, find_end_of_inset, get_containing_layout,
+                          get_containing_inset, get_value, get_bool_value)
 from unicode_symbols import unicode_reps
 
 # This will accept either a list of lines or a single line.
@@ -154,14 +156,14 @@ def put_cmd_in_ert(cmd, is_open=False, as_paragraph=False):
     `is_open` is a boolean setting the inset status to "open",
     `as_paragraph` wraps the ERT inset in a Standard paragraph.
     """
-    
+
     status = {False:"collapsed", True:"open"}
     ert_inset = ["\\begin_inset ERT", "status %s"%status[is_open], "",
                  "\\begin_layout Plain Layout", "",
                  # content here ([5:5])
                  "\\end_layout", "", "\\end_inset"]
 
-    paragraph = ["\\begin_layout Standard", 
+    paragraph = ["\\begin_layout Standard",
                  # content here ([1:1])
                  "", "", "\\end_layout", ""]
     # ensure cmd is an unicode instance and make it "LyX safe".
@@ -171,7 +173,7 @@ def put_cmd_in_ert(cmd, is_open=False, as_paragraph=False):
         cmd = cmd.decode('utf8')
     cmd = cmd.translate(licr_table)
     cmd = cmd.replace("\\", "\n\\backslash\n")
-    
+
     ert_inset[5:5] = cmd.splitlines()
     if not as_paragraph:
         return ert_inset
@@ -634,6 +636,16 @@ def is_document_option(document, option):
 
     return True
 
+singlepar_insets = [s.strip() for s in
+    u"Argument, Caption Above, Caption Below, Caption Bicaption,"
+    u"Caption Centered, Caption FigCaption, Caption Standard, Caption Table,"
+    u"Flex Chemistry, Flex Fixme_Note, Flex Latin, Flex ListOfSlides,"
+    u"Flex Missing_Figure, Flex PDF-Annotation, Flex PDF-Comment-Setup,"
+    u"Flex Reflectbox, Flex S/R expression, Flex Sweave Input File,"
+    u"Flex Sweave Options, Flex Thanks_Reference, Flex URL, Foot InTitle,"
+    u"IPADeco, Index, Info, Phantom, Script".split(',')]
+# print(singlepar_insets)
+
 def revert_language(document, lyxname, babelname="", polyglossianame=""):
     " Revert native language support "
 
@@ -654,85 +666,134 @@ def revert_language(document, lyxname, babelname="", polyglossianame=""):
     with_babel = with_polyglossia == False and babelname != ""
 
     # Are we dealing with a primary or secondary language?
-    primary = False
+    primary = document.language == lyxname
     secondary = False
 
-    orig_doc_language = document.language
     # Main language first
-    if document.language == lyxname:
-        primary = True
+    orig_doc_language = document.language
+    if primary:
+        # Change LyX document language to English (we will tell LaTeX
+        # to use the original language at the end of this function):
         document.language = "english"
         i = find_token(document.header, "\\language %s" % lyxname, 0)
         if i != -1:
             document.header[i] = "\\language english"
-        if with_polyglossia:
-            add_to_preamble(document, ["\\AtBeginDocument{\setotherlanguage{%s}}" % polyglossianame])
-            document.body[2 : 2] = put_cmd_in_ert("\\resetdefaultlanguage{%s}"%polyglossianame,
-                                                  is_open=True, as_paragraph=True)
 
-    # Now secondary languages
+    # Now look for occurences in the body
     i = 0
     while True:
-        i = find_token(document.body, '\\lang', i)
+        i = find_token(document.body, "\\lang", i+1)
         if i == -1:
             break
-        if document.body[i].startswith('\\lang %s' % lyxname):
+        if document.body[i].startswith("\\lang %s" % lyxname):
             secondary = True
-            endlang = get_containing_layout(document.body, i)[2]
-            langswitch = find_token(document.body, '\\lang', i + 1, endlang)
-            as_paragraph = True
-            if langswitch != -1:
-                endlang = langswitch
-                as_paragraph = False
-            if with_polyglossia:
-                add_to_preamble(document, ["\\AtBeginDocument{\setotherlanguage{%s}}" % polyglossianame])
-                document.body[endlang:endlang] = put_cmd_in_ert("\\end{%s}"%polyglossianame,
-                                                                is_open=True,
-                                                                as_paragraph=as_paragraph)
-            elif with_babel:
-                document.body[endlang:endlang] = put_cmd_in_ert("\\end{otherlanguage}",
-                                                                is_open=True,
-                                                                as_paragraph=as_paragraph)
-            del document.body[i]
-            if with_polyglossia:
-                document.body[i:i] = put_cmd_in_ert("\\begin{%s}"%polyglossianame,
-                                                    is_open=True)
-            elif with_babel:
-                document.body[i:i] = put_cmd_in_ert("\\begin{otherlanguage}{%s}" % babelname,
-                                                    is_open=True)
-        elif primary and document.body[i].startswith('\\lang english'):
+            texname = use_polyglossia and polyglossianame or babelname
+        elif primary and document.body[i].startswith("\\lang english"):
             # Since we switched the main language manually, English parts need to be marked
-            endlang = get_containing_layout(document.body, i)[2]
-            langswitch = find_token(document.body, '\\lang', i + 1, endlang)
-            as_paragraph = True
-            if langswitch != -1:
-                endlang = langswitch
-                as_paragraph = False
+            texname = "english"
+        else:
+            continue
+
+        parent = get_containing_layout(document.body, i)
+        i_e = parent[2] # end line no,
+        # print(i, texname, parent, document.body[i+1], file=sys.stderr)
+        
+        # Move leading space to the previous line:
+        if document.body[i+1].startswith(" "):
+            document.body[i+1] = document.body[i+1][1:]
+            document.body.insert(i, " ")
+            continue
+        
+        # Ensure correct handling of list labels
+        if (parent[0] in ["Labeling", "Description"]
+            and not " " in "\n".join(document.body[parent[3]:i])):
+            # line `i+1` is first line of a list item,
+            # part before a space character is the label
+            # TODO: insets or language change before first space character
+            labelline = document.body[i+1].split(' ', 1)
+            if len(labelline) > 1:
+                # Insert a space in the (original) document language
+                # between label and remainder.
+                # print("  Label:", labelline, file=sys.stderr)
+                lines = [labelline[0],
+                    "\\lang %s" % orig_doc_language,
+                    " ",
+                    "\\lang %s" % (primary and "english" or lyxname),
+                    labelline[1]]
+                document.body[i+1:i+2] = lines
+                i_e += 4
+  
+        # Find out where to end the language change.
+        langswitch = i
+        while True:
+            langswitch = find_token(document.body, "\\lang", langswitch+1, i_e)
+            if langswitch == -1:
+                break
+            # print("  ", langswitch, document.body[langswitch], file=sys.stderr)
+            # skip insets
+            i_a = parent[3] # paragraph start line
+            container = get_containing_inset(document.body[i_a:i_e], langswitch-i_a)
+            if container and container[1] < langswitch-i_a and container[2] > langswitch-i_a:
+                # print("  inset", container, file=sys.stderr)
+                continue
+            i_e = langswitch
+            break
+        
+        # use function or environment?
+        singlepar = i_e - i < 3
+        if not singlepar and parent[0] == "Plain Layout":
+            # environment not allowed in some insets
+            container = get_containing_inset(document.body, i)
+            singlepar = container[0] in singlepar_insets
+            
+        # Delete empty language switches:
+        if not "".join(document.body[i+1:i_e]):
+            del document.body[i:i_e]
+            i -= 1
+            continue
+
+        if singlepar:
             if with_polyglossia:
-                parent = get_containing_layout(document.body, i)
-                document.body[endlang:endlang] = put_cmd_in_ert("\\end{english}",
-                                                                is_open=True,
-                                                                as_paragraph=as_paragraph)
+                begin_cmd = "\\text%s{"%texname
             elif with_babel:
-                parent = get_containing_layout(document.body, i)
-                document.body[endlang:endlang] = put_cmd_in_ert("\\end{otherlanguage}",
-                                                                is_open=True,
-                                                                as_paragraph=as_paragraph)
-            del document.body[i]
+                begin_cmd = "\\foreignlanguage{%s}{" % texname
+            end_cmd = "}"
+        else:
             if with_polyglossia:
-                document.body[i:i] = put_cmd_in_ert("\\begin{english}",
-                                                    is_open=True)
+                begin_cmd = "\\begin{%s}"%texname
+                end_cmd = "\\end{%s}"%texname
             elif with_babel:
-                document.body[i:i] = put_cmd_in_ert("\\begin{otherlanguage}{english}",
-                                                    is_open=True)
-        else:
-            i += 1
+                begin_cmd = "\\begin{otherlanguage}{%s}" % texname
+                end_cmd = "\\end{otherlanguage}"
+
+        if (not primary or texname == "english"):
+            document.body[i_e:i_e] = put_cmd_in_ert(end_cmd)
+            document.body[i+1:i+1] = put_cmd_in_ert(begin_cmd)
+        del document.body[i]
+
+    if not (primary or secondary):
+        return
 
-    # With babel, we need to add the language options
-    if with_babel and (primary or secondary):
+    # Make the language known to Babel/Polyglossia and ensure the correct
+    # document language:
+    doc_lang_switch = ""
+    if with_babel:
+        # add as global option
         insert_document_option(document, babelname)
-        if secondary and document.body[10] != "selectlanguage{%s}" % orig_doc_language:
-            # Since the user options are always placed after the babel options,
-            # we need to reset the main language
-            document.body[2:2] = put_cmd_in_ert("\\selectlanguage{%s}" % orig_doc_language,
-                                                is_open=True, as_paragraph=True)
+        # Since user options are appended to the document options,
+        # Babel will treat `babelname` as primary language.
+        if not primary:
+            doc_lang_switch = "\\selectlanguage{%s}" % orig_doc_language
+    if with_polyglossia:
+        # Define language in the user preamble
+        # (don't use \AtBeginDocument, this fails with some languages).
+        add_to_preamble(document, ["\\usepackage{polyglossia}",
+                                   "\\setotherlanguage{%s}" % polyglossianame])
+        if primary:
+            # Changing the main language must be done in the document body.
+            doc_lang_switch = "\\resetdefaultlanguage{%s}" % polyglossianame
+
+    # Reset LaTeX main language if required and not already done
+    if doc_lang_switch and doc_lang_switch not in document.body[8:20] != doc_lang_switch:
+        document.body[2:2] = put_cmd_in_ert(doc_lang_switch,
+                                            is_open=True, as_paragraph=True)