commit b1a6edcd77bdbf0efc7585828efc5f3c9618084a
Author: Juergen Spitzmueller <[email protected]>
Date: Thu May 15 12:20:53 2025 +0200
Implement MultiPar to layouts (#10590)
---
lib/doc/Customization.lyx | 59 +++++++++++++++++++++++++++++++++++++++++++-
lib/doc/de/Customization.lyx | 59 +++++++++++++++++++++++++++++++++++++++++++-
lib/scripts/layout2layout.py | 5 +++-
src/Layout.cpp | 8 +++++-
src/Layout.h | 4 +++
src/Paragraph.cpp | 4 +--
src/output_latex.cpp | 52 ++++++++++++++++++++++++++++++--------
7 files changed, 175 insertions(+), 16 deletions(-)
diff --git a/lib/doc/Customization.lyx b/lib/doc/Customization.lyx
index 5e45337483..1edd3fba10 100644
--- a/lib/doc/Customization.lyx
+++ b/lib/doc/Customization.lyx
@@ -1,5 +1,5 @@
#LyX 2.5 created this file. For more info see https://www.lyx.org/
-\lyxformat 638
+\lyxformat 640
\begin_document
\begin_header
\save_transient_properties true
@@ -15347,6 +15347,57 @@ Right_Address_Box
\end_layout
\end_deeper
+\begin_layout Description
+
+\change_inserted -712698321 1747303660
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1747303589
+MultiPar
+\end_layout
+
+\end_inset
+
+ [
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1747303589
+
+\emph on
+0
+\end_layout
+
+\end_inset
+
+,
+\begin_inset space \thinspace{}
+\end_inset
+
+
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1747303589
+1
+\end_layout
+
+\end_inset
+
+] Whether multiple paragraphs are permitted in this layout.
+ This only applies to command layouts.
+ If true,
+ multiple paragraphs are put within the same command (rather than starting new
commands for each paragraph).
+ Default is false.
+\end_layout
+
\begin_layout Description
\begin_inset Flex Code
status collapsed
@@ -16941,6 +16992,8 @@ status collapsed
\change_inserted -712698321 1745643926
TheoremCrossRefName
+\change_unchanged
+
\end_layout
\end_inset
@@ -16973,6 +17026,8 @@ status collapsed
\change_inserted -712698321 1745645504
TheoremCrossRefPluralName
+\change_unchanged
+
\end_layout
\end_inset
@@ -16985,6 +17040,8 @@ status collapsed
\change_inserted -712698321 1745644987
TheoremCrossRefName
+\change_unchanged
+
\end_layout
\end_inset
diff --git a/lib/doc/de/Customization.lyx b/lib/doc/de/Customization.lyx
index 1044fb14dc..2d29921d33 100644
--- a/lib/doc/de/Customization.lyx
+++ b/lib/doc/de/Customization.lyx
@@ -1,5 +1,5 @@
#LyX 2.5 created this file. For more info see https://www.lyx.org/
-\lyxformat 638
+\lyxformat 640
\begin_document
\begin_header
\save_transient_properties true
@@ -13843,6 +13843,63 @@ Right_Address_Box
\begin_inset Flex Code
status collapsed
+\begin_layout Plain Layout
+MultiPar
+\end_layout
+
+\end_inset
+
+ [
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\emph on
+0
+\end_layout
+
+\end_inset
+
+,
+\begin_inset space \thinspace{}
+\end_inset
+
+
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+1
+\end_layout
+
+\end_inset
+
+] Legt fest,
+ ob innerhalb dieses Layouts mehrere Absätze erlaubt sind.
+ Dies betrifft nur Layouts des Typs
+\begin_inset Quotes gld
+\end_inset
+
+
+\lang english
+command
+\lang ngerman
+
+\begin_inset Quotes grd
+\end_inset
+
+.
+ Falls dies aktiviert ist,
+ werden mehrere Absätze als Argument ein und desselben Befehls ausgegeben
(statt dass für jeden Absatz ein neuer Befehl ausgegeben wird).
+ Voreinstellung:
+ deaktiviert.
+\end_layout
+
+\begin_layout Description
+\begin_inset Flex Code
+status collapsed
+
\begin_layout Plain Layout
NeedProtect
\end_layout
diff --git a/lib/scripts/layout2layout.py b/lib/scripts/layout2layout.py
index 176fd2643e..b3485e820e 100644
--- a/lib/scripts/layout2layout.py
+++ b/lib/scripts/layout2layout.py
@@ -364,6 +364,9 @@ currentFormat = 108
# "TheoremCounter", "TheoremParentCounter", "TheoremStyle",
# "TheoremCrossRefName", "TheoremCrossRefPluralName"
+# Incremented to format 109, 15 May 2025 by spitz
+# New Layout tag "MultiPar"
+
# Do not forget to document format change in Customization
# Manual (section "Declaring a new text class").
@@ -598,7 +601,7 @@ def convert(lines, end_format):
i += 1
continue
- if 101 <= format <= 107:
+ if 101 <= format <= 108:
# nothing to do.
i += 1
continue
diff --git a/src/Layout.cpp b/src/Layout.cpp
index 09626bbb22..0c14c79d61 100644
--- a/src/Layout.cpp
+++ b/src/Layout.cpp
@@ -74,6 +74,7 @@ enum LayoutTags {
LT_LATEXTYPE,
LT_LEFTDELIM,
LT_LEFTMARGIN,
+ LT_MULTIPAR,
LT_NEED_CPROTECT,
LT_NEED_MBOXPROTECT,
LT_NEED_PROTECT,
@@ -161,7 +162,7 @@ enum LayoutTags {
/////////////////////
Layout::Layout()
- : add_to_toc_(false), is_toc_caption_(true)
+ : add_to_toc_(false), multi_par_(false), is_toc_caption_(true)
{
unknown_ = false;
margintype = MARGIN_STATIC;
@@ -324,6 +325,7 @@ bool Layout::readIgnoreForcelocal(Lexer & lex, TextClass
const & tclass,
{ "leftdelim", LT_LEFTDELIM },
{ "leftmargin", LT_LEFTMARGIN },
{ "margin", LT_MARGIN },
+ { "multipar", LT_MULTIPAR },
{ "needcprotect", LT_NEED_CPROTECT },
{ "needmboxprotect", LT_NEED_MBOXPROTECT },
{ "needprotect", LT_NEED_PROTECT },
@@ -679,6 +681,10 @@ bool Layout::readIgnoreForcelocal(Lexer & lex, TextClass
const & tclass,
lex >> newline_allowed;
break;
+ case LT_MULTIPAR:
+ lex >> multi_par_;
+ break;
+
case LT_ALIGN:
readAlign(lex);
break;
diff --git a/src/Layout.h b/src/Layout.h
index 4722866b54..af179f6533 100644
--- a/src/Layout.h
+++ b/src/Layout.h
@@ -298,6 +298,8 @@ public:
/// are handled as one group?
bool isParagraphGroup() const { return par_group_; }
///
+ bool isMultiparCommand() const { return isCommand() && multi_par_; }
+ ///
bool labelIsInline() const {
return labeltype == LABEL_STATIC
|| labeltype == LABEL_SENSITIVE
@@ -686,6 +688,8 @@ private:
///
bool add_to_toc_;
///
+ bool multi_par_;
+ ///
std::string toc_type_;
///
bool is_toc_caption_;
diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp
index 234ce3fb4b..b897c03951 100644
--- a/src/Paragraph.cpp
+++ b/src/Paragraph.cpp
@@ -2755,7 +2755,7 @@ void Paragraph::latex(BufferParams const & bparams,
if (empty()) {
// For InTitle commands, we have already opened a group
// in output_latex::TeXOnePar.
- if (style.isCommand() && !style.intitle) {
+ if (style.isCommand() && !style.intitle &&
!style.isMultiparCommand()) {
os << '{';
++column;
}
@@ -2795,7 +2795,7 @@ void Paragraph::latex(BufferParams const & bparams,
}
// For InTitle commands, we have already opened a group
// in output_latex::TeXOnePar.
- if (style.isCommand() && !style.intitle) {
+ if (style.isCommand() && !style.intitle &&
!style.isMultiparCommand()) {
os << '{';
++column;
}
diff --git a/src/output_latex.cpp b/src/output_latex.cpp
index 9fdc901727..b804cf4f2f 100644
--- a/src/output_latex.cpp
+++ b/src/output_latex.cpp
@@ -305,6 +305,23 @@ static TeXEnvironmentData prepareEnvironment(Buffer const
& buf,
"listpreamble:");
}
}
+
+ if (style.isMultiparCommand() && !style.latexname().empty()) {
+ if (!runparams.no_cprotect &&
pit->needsCProtection(runparams.moving_arg)) {
+ if (contains(runparams.active_chars, '^'))
+ // cprotect relies on ^ being on catcode 7
+ os << "\\begingroup\\catcode`\\^=7";
+ os << "\\cprotect";
+ }
+ os << "\\" << from_ascii(style.latexname());
+ // Command arguments
+ if (!style.latexargs().empty()) {
+ OutputParams rp = runparams;
+ rp.local_font = &pit->getFirstFontSettings(bparams);
+ latexArgInsets(paragraphs, pit, os, rp,
style.latexargs());
+ }
+ os << from_ascii(style.latexparam()) << "{%";
+ }
data.style = &style;
// in multilingual environments, the CJK tags have to be nested properly
@@ -340,8 +357,9 @@ static void finishEnvironment(otexstream & os, OutputParams
const & runparams,
state->open_encoding_ = none;
}
- if (data.style->isEnvironment()) {
- os << breakln;
+ if (data.style->isEnvironment() || data.style->isMultiparCommand()) {
+ if (data.style->isEnvironment())
+ os << breakln;
bool const using_begin_end =
runparams.use_polyglossia ||
!lyxrc.language_command_end.empty();
@@ -365,8 +383,12 @@ static void finishEnvironment(otexstream & os,
OutputParams const & runparams,
os << '\n';
state->nest_level_ -= 1;
string const & name = data.style->latexname();
- if (!name.empty())
- os << "\\end{" << from_ascii(name) << "}\n";
+ if (!name.empty()) {
+ if (data.style->isEnvironment())
+ os << "\\end{" << from_ascii(name) << "}\n";
+ else
+ os << "}\n";
+ }
state->prev_env_language_ = data.par_language;
if (runparams.encoding != data.prev_encoding) {
runparams.encoding = data.prev_encoding;
@@ -738,6 +760,8 @@ namespace {
void parStartCommand(Paragraph const & par, otexstream & os,
OutputParams const & runparams, Layout const & style)
{
+ if (style.isMultiparCommand())
+ return;
switch (style.latextype) {
case LATEX_COMMAND:
if (!runparams.no_cprotect &&
par.needsCProtection(runparams.moving_arg)) {
@@ -1232,7 +1256,8 @@ void TeXOnePar(Buffer const & buf,
par.parEndChange(),
runparams);
os <<
bparams.encoding().latexString(docstring(1, 0x00b6)).first << "}";
}
- os << '}';
+ if (!style.isMultiparCommand())
+ os << '}';
if (!style.postcommandargs().empty())
latexArgInsets(par, os, runparams,
style.postcommandargs(), "post:");
if (!runparams.post_macro.empty()) {
@@ -1403,7 +1428,8 @@ void TeXOnePar(Buffer const & buf,
// InTitle commands need to be closed after the language has been
closed.
if (intitle_command) {
- os << '}';
+ if (!style.isMultiparCommand())
+ os << '}';
if (!style.postcommandargs().empty())
latexArgInsets(par, os, runparams,
style.postcommandargs(), "post:");
if (!runparams.post_macro.empty()) {
@@ -1429,7 +1455,12 @@ void TeXOnePar(Buffer const & buf,
os << bparams.encoding().latexString(docstring(1,
0x00b6)).first << "}";
}
- if (pending_newline) {
+ // with multipar layouts, do not output new line for last par in group
+ bool last_multipar_command = false;
+ if (nextpar && par.layout().isMultiparCommand()
+ && nextpar->layout().latexname() != par.layout().latexname())
+ last_multipar_command = true;
+ if (pending_newline && !last_multipar_command) {
if (unskip_newline)
// prevent unwanted whitespace
os << '%';
@@ -1514,7 +1545,7 @@ void TeXOnePar(Buffer const & buf,
// we don't need a newline for the last paragraph!!!
// Note from JMarc: we will re-add a \n explicitly in
// TeXEnvironment, because it is needed in this case
- if (nextpar && !os.afterParbreak() && !last_was_separator) {
+ if (nextpar && !os.afterParbreak() && !last_was_separator &&
!last_multipar_command) {
if (!text.inset().getLayout().parbreakIgnored() && !merged_par)
// Make sure to start a new line
os << breakln;
@@ -1725,8 +1756,9 @@ void latexParagraphs(Buffer const & buf,
}
}
- if (!layout.isEnvironment() &&
par->params().leftIndent().zero()) {
- // This is a standard top level paragraph, TeX it and
continue.
+ if (!layout.isEnvironment() && !layout.isMultiparCommand()
+ && par->params().leftIndent().zero()) {
+ // This is a standard top level single-par paragraph,
TeX it and continue.
TeXOnePar(buf, text, pit, os, runparams, everypar);
continue;
}
--
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs