[LyX/master] Add support for parfill(skip) (#12949)
Juergen Spitzmueller
spitz at lyx.org
Sun Aug 2 10:22:25 UTC 2026
commit d497dde1e06809c6caa3b2bb4af647082bfa480a
Author: Juergen Spitzmueller <spitz at lyx.org>
Date: Sun Aug 2 12:21:50 2026 +0200
Add support for parfill(skip) (#12949)
File format change
---
development/FORMAT | 7 ++
lib/doc/Customization.lyx | 243 ++++++++++++++++++++++++++++++++++++
lib/doc/de/Customization.lyx | 181 +++++++++++++++++++++++++++
lib/layouts/scrclass.inc | 3 +
lib/lyx2lyx/lyx_2_6.py | 38 +++++-
src/BufferParams.cpp | 138 +++++++++++++++++++-
src/BufferParams.h | 22 ++++
src/TextClass.cpp | 19 +++
src/TextClass.h | 12 ++
src/frontends/qt/GuiDocument.cpp | 49 ++++++++
src/frontends/qt/GuiDocument.h | 1 +
src/frontends/qt/LengthCombo.cpp | 5 +-
src/frontends/qt/ui/TextLayoutUi.ui | 79 ++++++++++--
src/support/Length.cpp | 2 +
src/support/Length.h | 1 +
src/support/lengthcommon.cpp | 4 +-
src/version.h | 4 +-
17 files changed, 791 insertions(+), 17 deletions(-)
diff --git a/development/FORMAT b/development/FORMAT
index 0e9e95f012..21bad579ed 100644
--- a/development/FORMAT
+++ b/development/FORMAT
@@ -7,6 +7,13 @@ changes happened in particular if possible. A good example would be
-----------------------
+2026-08-02 Jürgen Spitzmüller <spitz at lyx.org>
+ * Format incremented to 656: Support for parfillskip
+ New buffer param \parfillskip "<type>" "<glue length>"
+ where <type> is either of "default", "none", "thirdline",
+ "quarterline" or "custom", and <glue length> is only used
+ in the custom case (otherwise an empty string).
+
2026-07-30 Koji Yokota <yokota at lyx.org>
* Format incremented to 655:
Support ARGB colors. \color now takes 32bit hexnames instead of 16bit
diff --git a/lib/doc/Customization.lyx b/lib/doc/Customization.lyx
index 6d66f45aa2..c4e396b38f 100644
--- a/lib/doc/Customization.lyx
+++ b/lib/doc/Customization.lyx
@@ -12593,6 +12593,243 @@ parskip=half
parskip
\emph default
package.
+\change_inserted -712698321 1785664297
+
+\end_layout
+
+\begin_layout Description
+
+\change_inserted -712698321 1785665160
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785664317
+ParfillskipNone
+\end_layout
+
+\end_inset
+
+ [
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785664297
+string
+\end_layout
+
+\end_inset
+
+] If the class has an option to set
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785665160
+parfillskip
+\change_unchanged
+
+\end_layout
+
+\end_inset
+
+ to zero,
+ specify it here (e.g.,
+
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785664387
+parfullskip=none
+\end_layout
+
+\end_inset
+
+).
+ This then outputs the option rather than using the
+\emph on
+parskip
+\emph default
+ package.
+ If the option is combined with the parskip option (as in KOMA classes),
+ you can use the
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785664524
+$$PSOPT
+\change_unchanged
+
+\end_layout
+
+\end_inset
+
+ placeholder (e.g.,
+
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785664534
+$$PSOPT-
+\change_unchanged
+
+\end_layout
+
+\end_inset
+
+ in KOMA results in
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785664542
+parskip=full-
+\change_unchanged
+
+\end_layout
+
+\end_inset
+
+ together with
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785664507
+ParskipFull parskip=full
+\end_layout
+
+\end_inset
+
+).
+\change_unchanged
+
+\end_layout
+
+\begin_layout Description
+
+\change_inserted -712698321 1785665172
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785664326
+ParfillskipQuarter
+\end_layout
+
+\end_inset
+
+ [
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785664297
+string
+\end_layout
+
+\end_inset
+
+] Similar than
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785664574
+ParfillskipNone
+\end_layout
+
+\end_inset
+
+,
+ but for
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785665172
+parfillskip
+\change_unchanged
+
+\end_layout
+
+\end_inset
+
+ of a quarter of the line.
+\end_layout
+
+\begin_layout Description
+
+\change_inserted -712698321 1785665179
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785664337
+ParfillskipThird
+\end_layout
+
+\end_inset
+
+ [
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785664331
+string
+\end_layout
+
+\end_inset
+
+] Similar than
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785664602
+ParfillskipNone
+\end_layout
+
+\end_inset
+
+,
+ but for
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785665179
+parfillskip
+\change_unchanged
+
+\end_layout
+
+\end_inset
+
+ of a third of the line.
+\change_unchanged
+
\end_layout
\begin_layout Description
@@ -24355,6 +24592,8 @@ status collapsed
\change_inserted -712698321 1783145646
IsInherited
+\change_unchanged
+
\end_layout
\end_inset
@@ -24369,6 +24608,8 @@ status collapsed
\emph on
0
+\change_unchanged
+
\end_layout
\end_inset
@@ -24385,6 +24626,8 @@ status collapsed
\change_inserted -712698321 1783145638
1
+\change_unchanged
+
\end_layout
\end_inset
diff --git a/lib/doc/de/Customization.lyx b/lib/doc/de/Customization.lyx
index 748c8b27b2..5efed2f20e 100644
--- a/lib/doc/de/Customization.lyx
+++ b/lib/doc/de/Customization.lyx
@@ -11055,6 +11055,187 @@ parskip
diese Option verwendet.
\end_layout
+\begin_layout Description
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+ParfillskipNone
+\end_layout
+
+\end_inset
+
+ [
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+string
+\end_layout
+
+\end_inset
+
+] Falls die Dokumentklasse eine Option zum Setzen des Werts von
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+parfillskip
+\end_layout
+
+\end_inset
+
+ auf Null,
+ geben Sie diese hier an (bspw.
+
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+parfullskip=none
+\end_layout
+
+\end_inset
+
+).
+ Dann wird statt des Pakets
+\emph on
+parskip
+\emph default
+ diese Option verwendet.
+ Falls die Option mit der Parskip-Option kombiniert ist (wie in den KOMA-Klassen),
+ können Sie den Platzhalter
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+$$PSOPT
+\end_layout
+
+\end_inset
+
+ verwenden (bspw.
+ resultiert
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+$$PSOPT-
+\end_layout
+
+\end_inset
+
+ in KOMA zusammen
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+ParskipFull parskip=full
+\end_layout
+
+\end_inset
+
+ in
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+parskip=full-
+\end_layout
+
+\end_inset
+
+ ).
+\end_layout
+
+\begin_layout Description
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+ParfillskipQuarter
+\end_layout
+
+\end_inset
+
+ [
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+string
+\end_layout
+
+\end_inset
+
+] Ähnlich wie
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+ParfillskipNone
+\end_layout
+
+\end_inset
+
+,
+ aber für
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+parfillskip
+\end_layout
+
+\end_inset
+
+ mit einem Viertel der Zeile.
+\end_layout
+
+\begin_layout Description
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+ParfillskipThird
+\end_layout
+
+\end_inset
+
+ [
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+string
+\end_layout
+
+\end_inset
+
+] Ähnlich wie
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+ParfillskipNone
+\end_layout
+
+\end_inset
+
+,
+ aber für
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+parfillskip
+\end_layout
+
+\end_inset
+
+ mit einem Drittel der Zeile.
+\end_layout
+
\begin_layout Standard
Der Abschnitt
\begin_inset Flex Code
diff --git a/lib/layouts/scrclass.inc b/lib/layouts/scrclass.inc
index 6d989d390f..ff6f322347 100644
--- a/lib/layouts/scrclass.inc
+++ b/lib/layouts/scrclass.inc
@@ -23,6 +23,9 @@ ClassOptions
PageSizeFormat paper=$$s
ParskipHalf parskip=half
ParskipFull parskip=full
+ ParfillskipNone $$PSOPT-
+ ParfillskipQuarter $$PSOPT*
+ ParfillskipThird $$PSOPT+
End
Style Standard
diff --git a/lib/lyx2lyx/lyx_2_6.py b/lib/lyx2lyx/lyx_2_6.py
index 68969a9191..5eed5cbe05 100644
--- a/lib/lyx2lyx/lyx_2_6.py
+++ b/lib/lyx2lyx/lyx_2_6.py
@@ -26,7 +26,6 @@ import unicodedata
# get_ert,
# hex2ratio,
# insert_to_preamble,
-# latex_length,
# length_in_bp,
# lyx2latex,
# lyx2verbatim,
@@ -37,6 +36,7 @@ import unicodedata
# str2bool
from lyx2lyx_tools import (
add_to_preamble,
+ latex_length,
put_cmd_in_ert
)
@@ -1525,6 +1525,7 @@ def revert_mintedlangs(document):
lps_res.append(l)
document.body[k] = "lstparams \"%s\"" % ",".join(lps_res)
+
def revert_hex32colors(document):
"""Revert 32bit ARGB hex colors to 16bit RGB"""
i = 0
@@ -1568,6 +1569,37 @@ def revert_hex32colors(document):
document.body[i] = "\\color %s" % ' '.join(hex16colors)
+def revert_parfillskip(document):
+ """Revert parfillskip setting to preamble code"""
+ i = find_token(document.header, "\\parfillskip", 0)
+ if i == -1:
+ return
+
+ # We need to use this regex since split() does not handle quote protection
+ parfillskip = [p for p in re.split("( |\\\".*?\\\"|'.*?')", document.header[i]) if p.strip()]
+ if len(parfillskip) == 0:
+ return
+
+ pfs_type = parfillskip[1].strip('"')
+ pfs_value = parfillskip[2].strip('"')
+
+ del document.header[i]
+
+ if pfs_type == "default":
+ return
+ preamble = ""
+ if pfs_type == "none":
+ preamble = "\\setlength\\parfillskip{\\z@ plus 1fil}"
+ elif pfs_type == "thirdline":
+ preamble = "\\setlength\\parfillskip{.3333\\linewidth plus 1fil}"
+ elif pfs_type == "quarterline":
+ preamble = "\\setlength\\parfillskip{.25\\linewidth plus 1fil}"
+ elif pfs_type == "custom":
+ preamble = "\\setlength\\parfillskip{%s}" % latex_length(pfs_value)[1]
+
+ if preamble != "":
+ add_to_preamble(document, preamble)
+
##
# Conversion hub
#
@@ -1585,11 +1617,13 @@ convert = [
[652, [convert_removed_numeric]],
[653, []],
[654, []],
- [655, []]
+ [655, []],
+ [656, []]
]
revert = [
+ [655, [revert_parfillskip]],
[654, [revert_hex32colors]],
[653, [revert_mintedlangs]],
[652, [revert_specialfonts]],
diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp
index 8714dddb4a..206a231481 100644
--- a/src/BufferParams.cpp
+++ b/src/BufferParams.cpp
@@ -75,6 +75,11 @@ static char const * const string_paragraph_separation[] = {
};
+static char const * const string_parfill_skip[] = {
+ "default", "none", "thirdline", "quarterline", "custom", ""
+};
+
+
static char const * const string_quotes_style[] = {
"english", "swedish", "german", "polish", "swiss", "danish", "plain",
"british", "swedishg", "french", "frenchin", "russian", "cjk", "cjkangle",
@@ -140,6 +145,30 @@ ParSepTranslator const & parseptranslator()
}
+// ParfillsKIP
+typedef Translator<string, BufferParams::ParfillSkip> ParfillSkipTranslator;
+
+
+ParfillSkipTranslator const init_parfillskiptranslator()
+{
+ ParfillSkipTranslator translator
+ (string_parfill_skip[0], BufferParams::ParfillSkipDefault);
+ translator.addPair(string_parfill_skip[1], BufferParams::ParfillSkipNone);
+ translator.addPair(string_parfill_skip[2], BufferParams::ParfillSkipThirdLine);
+ translator.addPair(string_parfill_skip[3], BufferParams::ParfillSkipQuarterLine);
+ translator.addPair(string_parfill_skip[4], BufferParams::ParfillSkipCustom);
+ return translator;
+}
+
+
+ParfillSkipTranslator const & parfillskiptranslator()
+{
+ static ParfillSkipTranslator const translator =
+ init_parfillskiptranslator();
+ return translator;
+}
+
+
// Quotes style
typedef Translator<string, QuoteStyle> QuotesStyleTranslator;
@@ -353,6 +382,7 @@ public:
IndicesList indiceslist;
Spacing spacing;
Length parindent;
+ GlueLength parfillskip;
Length mathindent;
/** This is the amount of space used for paragraph_separation "skip",
* and for detached paragraphs in "indented" documents.
@@ -404,6 +434,7 @@ BufferParams::BufferParams()
cite_engine_type_ = ENGINE_TYPE_DEFAULT;
makeDocumentClass();
paragraph_separation = ParagraphIndentSeparation;
+ parfill_skip = ParfillSkipDefault;
is_math_indent = false;
math_numbering_side = DEFAULT;
quotes_style = QuoteStyle::English;
@@ -736,6 +767,41 @@ void BufferParams::setParIndent(Length const & indent)
}
+GlueLength const & BufferParams::getParfillSkip() const
+{
+ return pimpl_->parfillskip;
+}
+
+
+string const BufferParams::getParfillSkipString() const
+{
+ string res;
+ switch (parfill_skip) {
+ case ParfillSkipDefault:
+ break;
+ case ParfillSkipNone:
+ res = "\\z@ plus 1fil";
+ break;
+ case ParfillSkipThirdLine:
+ res = ".3333\\linewidth plus 1fil";
+ break;
+ case ParfillSkipQuarterLine:
+ res = ".25\\linewidth plus 1fil";
+ break;
+ case ParfillSkipCustom:
+ res = getParfillSkip().asLatexString();
+ break;
+ }
+ return res;
+}
+
+
+void BufferParams::setParFillSkip(GlueLength const & skip)
+{
+ pimpl_->parfillskip = skip;
+}
+
+
VSpace const & BufferParams::getDefSkip() const
{
return pimpl_->defskip;
@@ -1181,6 +1247,18 @@ string BufferParams::readToken(Lexer & lex, string const & token,
pimpl_->defskip = VSpace(VSpace::MEDSKIP);
break;
}
+ if (token == "\\parfillskip") {
+ string type;
+ lex >> type;
+ string val;
+ lex >> val;
+ parfill_skip = parfillskiptranslator().find(type);
+ if (parfill_skip == ParfillSkipCustom)
+ setParFillSkip(GlueLength(val));
+ else
+ setParFillSkip(GlueLength());
+ break;
+ }
if (token == "\\is_math_indent") {
lex >> is_math_indent;
break;
@@ -1993,6 +2071,7 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const
<< (getParIndent().empty() ? "default" : getParIndent().asString());
else
os << "\n\\defskip " << getDefSkip().asLyXCommand();
+ os << "\n\\parfillskip \"" << string_parfill_skip[parfill_skip] << "\" \"" << getParfillSkip().asString() << "\"";
os << "\n\\is_math_indent " << is_math_indent;
if (is_math_indent)
os << "\n\\math_indentation "
@@ -2366,11 +2445,49 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
break;
}
+ bool parfillskip_classopt = false;
if (paragraph_separation) {
+ string psopt;
if (!tclass.halfparskip().empty() && getDefSkip().kind() == VSpace::HALFLINE)
- clsoptions << tclass.halfparskip() << ",";
+ psopt = tclass.halfparskip();
if (!tclass.fullparskip().empty() && getDefSkip().kind() == VSpace::FULLLINE)
- clsoptions << tclass.fullparskip() << ",";
+ psopt = tclass.fullparskip();
+ switch (parfill_skip) {
+ case ParfillSkipNone: {
+ if (contains(tclass.noneparfillskip(), "$$PSOPT")) {
+ psopt = subst(tclass.noneparfillskip(), "$$PSOPT", psopt);
+ parfillskip_classopt = true;
+ } else if (!tclass.noneparfillskip().empty()) {
+ clsoptions << tclass.noneparfillskip() << ",";
+ parfillskip_classopt = true;
+ }
+ break;
+ }
+ case ParfillSkipThirdLine: {
+ if (contains(tclass.thirdparfillskip(), "$$PSOPT")) {
+ psopt = subst(tclass.thirdparfillskip(), "$$PSOPT", psopt);
+ parfillskip_classopt = true;
+ } else if (!tclass.thirdparfillskip().empty()) {
+ clsoptions << tclass.thirdparfillskip() << ",";
+ parfillskip_classopt = true;
+ }
+ break;
+ }
+ case ParfillSkipQuarterLine: {
+ if (contains(tclass.quarterparfillskip(), "$$PSOPT")) {
+ psopt = subst(tclass.quarterparfillskip(), "$$PSOPT", psopt);
+ parfillskip_classopt = true;
+ } else if (!tclass.quarterparfillskip().empty()) {
+ clsoptions << tclass.quarterparfillskip() << ",";
+ parfillskip_classopt = true;
+ }
+ break;
+ }
+ case ParfillSkipDefault:
+ case ParfillSkipCustom:
+ break;
+ }
+ clsoptions << psopt << ",";
}
// language should be a parameter to \documentclass
@@ -2748,6 +2865,10 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
// explicitly reset default (might have been changed
// in a class or package)
os << "\\parskip=.5\\baselineskip plus 2pt\\relax\n";
+ // parfillskip
+ if (parfill_skip != ParfillSkipDefault)
+ os << "\\setlength{\\parfillskip}{" << getParfillSkipString() << "}\n";
+
} else if (!by_class_option) {
// load parskip package with required options
string psopts;
@@ -2758,6 +2879,16 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
else
psopts = "skip=" + psopt;
}
+ string const parfill = getParfillSkipString();
+ if (!parfill.empty()) {
+ if (!psopts.empty())
+ psopts += ",";
+ if (contains(parfill, ' '))
+ // glue length has spaces: embrace
+ psopts += "parfill={" + parfill + "}";
+ else
+ psopts += "parfill=" + parfill;
+ }
string const xpsopts = getPackageOptions("parskip");
if (!xpsopts.empty()) {
if (!psopts.empty())
@@ -2777,6 +2908,9 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
<< from_utf8(getParIndent().asLatexString())
<< "}\n";
}
+ // parfillskip
+ if (!parfillskip_classopt && parfill_skip != ParfillSkipDefault)
+ os << "\\setlength{\\parfillskip}{" << getParfillSkipString() << "}\n";
}
if (is_math_indent) {
diff --git a/src/BufferParams.h b/src/BufferParams.h
index 1da3f1cdc7..5a1a67341a 100644
--- a/src/BufferParams.h
+++ b/src/BufferParams.h
@@ -45,6 +45,7 @@ class DocumentClass;
class Encoding;
class Font;
class Format;
+class GlueLength;
class IndicesList;
class Language;
class LaTeXFeatures;
@@ -75,6 +76,19 @@ public:
ParagraphSkipSeparation
};
///
+ enum ParfillSkip {
+ ///
+ ParfillSkipDefault,
+ ///
+ ParfillSkipNone,
+ ///
+ ParfillSkipThirdLine,
+ ///
+ ParfillSkipQuarterLine,
+ ///
+ ParfillSkipCustom
+ };
+ ///
BufferParams();
/// get l10n translated to the buffers language
@@ -111,6 +125,10 @@ public:
VSpace const & getDefSkip() const;
///
void setDefSkip(VSpace const & vs);
+ ///
+ GlueLength const & getParfillSkip() const;
+ ///
+ void setParFillSkip(GlueLength const & skip);
///
Length const & getMathIndent() const;
@@ -137,6 +155,8 @@ public:
*/
ParagraphSeparation paragraph_separation;
///
+ ParfillSkip parfill_skip;
+ ///
QuoteStyle quotes_style;
///
bool dynamic_quotes;
@@ -739,6 +759,8 @@ private:
std::string const getBibtexCommand(std::string const & cmd,
bool const warn) const;
///
+ std::string const getParfillSkipString() const;
+ ///
DocumentClassPtr doc_class_;
///
LayoutModuleList layout_modules_;
diff --git a/src/TextClass.cpp b/src/TextClass.cpp
index 87c50d7546..38107c75ec 100644
--- a/src/TextClass.cpp
+++ b/src/TextClass.cpp
@@ -137,6 +137,7 @@ TextClass::TextClass()
opt_pagesize_("default|a4|a5|b5|letter|legal|executive"),
opt_pagestyle_("empty|plain|headings|fancy"), fontsize_format_("$$spt"), pagesize_("default"),
pagesize_format_("$$spaper"), pagestyle_("default"), parskip_full_(""), parskip_half_(""),
+ parfillskip_none_(""), parfillskip_quarter_(""), parfillskip_third_(""),
tablestyle_("default"), docbookroot_("article"), docbookforceabstract_(false),
columns_(1), sides_(OneSide), secnumdepth_(3), tocdepth_(3), outputType_(LATEX),
outputFormat_("latex"), has_output_format_(false), defaultfont_(sane_font),
@@ -1091,6 +1092,9 @@ void TextClass::readClassOptions(Lexer & lexrc)
CO_PAGESIZE,
CO_PAGESIZE_FORMAT,
CO_PAGESTYLE,
+ CO_PARFILLSKIP_NONE,
+ CO_PARFILLSKIP_QUARTER,
+ CO_PARFILLSKIP_THIRD,
CO_PARSKIP_FULL,
CO_PARSKIP_HALF,
CO_OTHER,
@@ -1105,6 +1109,9 @@ void TextClass::readClassOptions(Lexer & lexrc)
{"pagesize", CO_PAGESIZE },
{"pagesizeformat", CO_PAGESIZE_FORMAT },
{"pagestyle", CO_PAGESTYLE },
+ {"parfillskipnone", CO_PARFILLSKIP_NONE },
+ {"parfillskipquarter", CO_PARFILLSKIP_QUARTER },
+ {"parfillskipthird", CO_PARFILLSKIP_THIRD },
{"parskipfull", CO_PARSKIP_FULL },
{"parskiphalf", CO_PARSKIP_HALF }
};
@@ -1149,6 +1156,18 @@ void TextClass::readClassOptions(Lexer & lexrc)
lexrc.next();
parskip_half_ = rtrim(lexrc.getString());
break;
+ case CO_PARFILLSKIP_NONE:
+ lexrc.next();
+ parfillskip_none_ = rtrim(lexrc.getString());
+ break;
+ case CO_PARFILLSKIP_QUARTER:
+ lexrc.next();
+ parfillskip_quarter_ = rtrim(lexrc.getString());
+ break;
+ case CO_PARFILLSKIP_THIRD:
+ lexrc.next();
+ parfillskip_third_ = rtrim(lexrc.getString());
+ break;
case CO_OTHER:
lexrc.next();
if (options_.empty())
diff --git a/src/TextClass.h b/src/TextClass.h
index 9840a77237..f7673b10d8 100644
--- a/src/TextClass.h
+++ b/src/TextClass.h
@@ -292,6 +292,12 @@ protected:
std::string parskip_full_;
/// Option for half parskip
std::string parskip_half_;
+ /// Option for zero parfillskip
+ std::string parfillskip_none_;
+ /// Option for 1/4 parfillskip
+ std::string parfillskip_quarter_;
+ /// Option for 1/3 parfillskip
+ std::string parfillskip_third_;
///
std::string tablestyle_;
///
@@ -494,6 +500,12 @@ public:
///
std::string const & halfparskip() const { return parskip_half_; }
///
+ std::string const & noneparfillskip() const { return parfillskip_none_; }
+ ///
+ std::string const & quarterparfillskip() const { return parfillskip_quarter_; }
+ ///
+ std::string const & thirdparfillskip() const { return parfillskip_third_; }
+ ///
std::string const & pagestyle() const { return pagestyle_; }
///
std::string const & tablestyle() const { return tablestyle_; }
diff --git a/src/frontends/qt/GuiDocument.cpp b/src/frontends/qt/GuiDocument.cpp
index aac142cbb2..eae5f727ca 100644
--- a/src/frontends/qt/GuiDocument.cpp
+++ b/src/frontends/qt/GuiDocument.cpp
@@ -885,6 +885,15 @@ GuiDocument::GuiDocument(GuiView & lv)
connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
this, SLOT(change_adaptor()));
+ connect(textLayoutModule->parfillskipCO, SIGNAL(activated(int)),
+ this, SLOT(setParfillSkip(int)));
+ connect(textLayoutModule->parfillskipCO, SIGNAL(activated(int)),
+ this, SLOT(change_adaptor()));
+ connect(textLayoutModule->parfillskipLE, SIGNAL(textChanged(const QString &)),
+ this, SLOT(change_adaptor()));
+ connect(textLayoutModule->parfillskipLengthCO, SIGNAL(activated(int)),
+ this, SLOT(change_adaptor()));
+
connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
this, SLOT(enableIndent(bool)));
connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
@@ -918,6 +927,15 @@ GuiDocument::GuiDocument(GuiView & lv)
textLayoutModule->skipCO->addItem(qt_("Medium Skip"), VSpace::MEDSKIP);
textLayoutModule->skipCO->addItem(qt_("Big Skip"), VSpace::BIGSKIP);
textLayoutModule->skipCO->addItem(qt_("Custom"), VSpace::LENGTH);
+
+ textLayoutModule->parfillskipCO->addItem(qt_("Default"), BufferParams::ParfillSkipDefault);
+ textLayoutModule->parfillskipCO->addItem(qt_("None[[Parfillskip]]"), BufferParams::ParfillSkipNone);
+ textLayoutModule->parfillskipCO->addItem(qt_("1/4 of Line"), BufferParams::ParfillSkipQuarterLine);
+ textLayoutModule->parfillskipCO->addItem(qt_("1/3 of Line"), BufferParams::ParfillSkipThirdLine);
+ textLayoutModule->parfillskipCO->addItem(qt_("Custom"), BufferParams::ParfillSkipCustom);
+ // parfillskip accepts glue length
+ textLayoutModule->parfillskipLE->setValidator(glueLengthValidator(textLayoutModule->parfillskipLE));
+
textLayoutModule->lspacingCO->insertItem(
Spacing::Single, qt_("Single"));
textLayoutModule->lspacingCO->insertItem(
@@ -931,6 +949,8 @@ GuiDocument::GuiDocument(GuiView & lv)
bc().addCheckedLineEditPanel(textLayoutModule->indentLE, docPS, N_("Text Layout"));
bc().addCheckedLineEdit(textLayoutModule->skipLE, textLayoutModule->skipRB);
bc().addCheckedLineEditPanel(textLayoutModule->skipLE, docPS, N_("Text Layout"));
+ bc().addCheckedLineEdit(textLayoutModule->parfillskipLE, textLayoutModule->parfillskipLA);
+ bc().addCheckedLineEditPanel(textLayoutModule->parfillskipLE, docPS, N_("Text Layout"));
textLayoutModule->tableStyleCO->addItem(qt_("Default"), toqstr("default"));
getTableStyles();
@@ -2319,6 +2339,19 @@ void GuiDocument::setSkip(int item)
}
+void GuiDocument::setParfillSkip(int item)
+{
+ BufferParams::ParfillSkip kind =
+ BufferParams::ParfillSkip(textLayoutModule->parfillskipCO->itemData(item).toInt());
+ bool const enable = (kind == BufferParams::ParfillSkipCustom);
+ textLayoutModule->parfillskipLE->setEnabled(enable);
+ textLayoutModule->parfillskipLengthCO->setEnabled(enable);
+ // needed to catch empty custom case
+ bc().refresh();
+ isValid();
+}
+
+
void GuiDocument::enableSkip(bool skip)
{
textLayoutModule->indentLE->setEnabled(!skip);
@@ -4426,6 +4459,16 @@ void GuiDocument::applyView()
break;
}
}
+ bp_.parfill_skip = BufferParams::ParfillSkip(textLayoutModule->parfillskipCO->itemData(
+ textLayoutModule->parfillskipCO->currentIndex()).toInt());
+ if (bp_.parfill_skip == BufferParams::ParfillSkipCustom) {
+ GlueLength parfillskip(widgetsToLength(textLayoutModule->parfillskipLE,
+ textLayoutModule->parfillskipLengthCO));
+ bp_.setParFillSkip(parfillskip);
+ } else
+ // default
+ bp_.setParFillSkip(GlueLength());
+
bp_.tablestyle = fromqstr(textLayoutModule->tableStyleCO->itemData(
textLayoutModule->tableStyleCO->currentIndex()).toString());
@@ -5062,6 +5105,12 @@ void GuiDocument::paramsToDialog()
setSkip(textLayoutModule->skipCO->currentIndex());
}
+ textLayoutModule->parfillskipCO->setCurrentIndex(textLayoutModule->parfillskipCO->findData(bp_.parfill_skip));
+
+ lengthToWidgets(textLayoutModule->parfillskipLE,
+ textLayoutModule->parfillskipLengthCO,
+ bp_.getParfillSkip().asString(), default_unit);
+
textLayoutModule->twoColumnCB->setChecked(
bp_.columns == 2);
textLayoutModule->justCO->setCurrentIndex(textLayoutModule->justCO->findData(toqstr(bp_.justification)));
diff --git a/src/frontends/qt/GuiDocument.h b/src/frontends/qt/GuiDocument.h
index 41290a3a74..b5cc1cf05f 100644
--- a/src/frontends/qt/GuiDocument.h
+++ b/src/frontends/qt/GuiDocument.h
@@ -140,6 +140,7 @@ private Q_SLOTS:
void enableIndent(bool);
void setSkip(int);
void enableSkip(bool);
+ void setParfillSkip(int);
void allowMathIndent();
void enableMathIndent(int);
void browseLayout();
diff --git a/src/frontends/qt/LengthCombo.cpp b/src/frontends/qt/LengthCombo.cpp
index 1ab6d7df24..851e2fc286 100644
--- a/src/frontends/qt/LengthCombo.cpp
+++ b/src/frontends/qt/LengthCombo.cpp
@@ -28,9 +28,10 @@ LengthCombo::LengthCombo(QWidget * parent)
: QComboBox(parent)
{
for (int i = 0; i < lyx::num_units; i++) {
- // mu does not make sense usually
+ // mu and fil do not make sense usually
// so it must be added manually, if needed
- if (QLatin1String(lyx::unit_name[i]) == "mu")
+ if (QLatin1String(lyx::unit_name[i]) == "mu"
+ || QLatin1String(lyx::unit_name[i]) == "fil")
continue;
QComboBox::addItem(lyx::qt_(lyx::unit_name_gui[i]),
lyx::toqstr(lyx::unit_name[i]));
diff --git a/src/frontends/qt/ui/TextLayoutUi.ui b/src/frontends/qt/ui/TextLayoutUi.ui
index 3c2195a0b3..f9d92b25d2 100644
--- a/src/frontends/qt/ui/TextLayoutUi.ui
+++ b/src/frontends/qt/ui/TextLayoutUi.ui
@@ -6,14 +6,14 @@
<rect>
<x>0</x>
<y>0</y>
- <width>470</width>
- <height>468</height>
+ <width>495</width>
+ <height>510</height>
</rect>
</property>
<property name="windowTitle">
<string/>
</property>
- <layout class="QGridLayout" name="gridLayout_4">
+ <layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QGroupBox" name="separateGB">
<property name="title">
@@ -198,6 +198,71 @@
</widget>
</item>
<item row="1" column="0">
+ <widget class="QGroupBox" name="parfillGB">
+ <property name="title">
+ <string>Paragraph Fill</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0">
+ <widget class="QLabel" name="parfillskipLA">
+ <property name="text">
+ <string>Ma&ximum last line fill:</string>
+ </property>
+ <property name="buddy">
+ <cstring>parfillskipCO</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="parfillskipCO">
+ <property name="toolTip">
+ <string>Specifiy the minimum amount of free space in the last line of a paragraph</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLineEdit" name="parfillskipLE">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="inputMethodHints">
+ <set>Qt::ImhFormattedNumbersOnly</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="lyx::frontend::LengthCombo" name="parfillskipLengthCO">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="inputMethodHints">
+ <set>Qt::ImhFormattedNumbersOnly|Qt::ImhLatinOnly</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4">
+ <spacer name="spacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>2</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0">
<widget class="QGroupBox" name="spacingGB">
<property name="minimumSize">
<size>
@@ -270,7 +335,7 @@
</layout>
</widget>
</item>
- <item row="2" column="0">
+ <item row="3" column="0">
<widget class="QGroupBox" name="tableStyleGB">
<property name="title">
<string>Table Style</string>
@@ -319,7 +384,7 @@
</layout>
</widget>
</item>
- <item row="3" column="0">
+ <item row="4" column="0">
<widget class="QCheckBox" name="twoColumnCB">
<property name="toolTip">
<string>Format text into two columns</string>
@@ -329,7 +394,7 @@
</property>
</widget>
</item>
- <item row="4" column="0">
+ <item row="5" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="justLA">
@@ -366,7 +431,7 @@
</item>
</layout>
</item>
- <item row="5" column="0">
+ <item row="6" column="0">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
diff --git a/src/support/Length.cpp b/src/support/Length.cpp
index f5c723f543..cdc0049e36 100644
--- a/src/support/Length.cpp
+++ b/src/support/Length.cpp
@@ -142,6 +142,7 @@ string const Length::asHTMLString() const
os << formatFPNumber(val_) << '%';
break;
case SP:
+ case FIL:
case UNIT_NONE:
break;
}
@@ -251,6 +252,7 @@ double Length::inInch(double text_width, double em_width, double margin) const
// but we do not have this information here.
result = val_ * em_width * 1.2 / 100;
break;
+ case FIL:
case Length::UNIT_NONE:
result = 0; // this cannot happen
break;
diff --git a/src/support/Length.h b/src/support/Length.h
index 7863a9cfa5..865f61e791 100644
--- a/src/support/Length.h
+++ b/src/support/Length.h
@@ -44,6 +44,7 @@ public:
DD, ///< Didot point = 1/72 of a French inch, = 0.376mm
EM, ///< Width of capital "M" in current font.
EX, ///< Height of a small "x" for the current font.
+ FIL, ///< Stretchable space, used as glue.
IN, ///< Inch = 25.4mm = 72.27pt = 6.022pc
MM, ///< Millimeter = 2.845pt
MU, ///< Math unit (18mu = 1em) for positioning in math mode
diff --git a/src/support/lengthcommon.cpp b/src/support/lengthcommon.cpp
index 303dbcbc1f..f837f55c63 100644
--- a/src/support/lengthcommon.cpp
+++ b/src/support/lengthcommon.cpp
@@ -28,7 +28,7 @@ namespace lyx {
// the latex units
char const * const unit_name[] = {
- "bp", "cc", "cm", "dd", "em", "ex", "in", "mm", "mu",
+ "bp", "cc", "cm", "dd", "em", "ex", "fil", "in", "mm", "mu",
"pc", "pt", "sp",
"text%", "col%", "page%", "line%",
"theight%", "pheight%", "baselineskip%", "" };
@@ -38,7 +38,7 @@ int const num_units = int(sizeof(unit_name) / sizeof(unit_name[0]) - 1);
// the LyX gui units
char const * const unit_name_gui[] = {
N_("bp"), N_("cc[[unit of measure]]"), N_("cm"), N_("dd"), N_("em"),
- N_("ex"), N_("in[[unit of measure]]"), N_("mm"), N_("mu[[unit of measure]]"), N_("pc"),
+ N_("ex"), N_("Elastic"), N_("in[[unit of measure]]"), N_("mm"), N_("mu[[unit of measure]]"), N_("pc"),
N_("pt"), N_("sp"), N_("Text Width %"),
N_("Column Width %"), N_("Page Width %"), N_("Line Width %"),
N_("Text Height %"), N_("Page Height %"), N_("Line Distance %"), "" };
diff --git a/src/version.h b/src/version.h
index 8a494df25b..cd47b6268d 100644
--- a/src/version.h
+++ b/src/version.h
@@ -32,8 +32,8 @@ 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 655 // koji: ARGB colors
-#define LYX_FORMAT_TEX2LYX 655
+#define LYX_FORMAT_LYX 656 // spitz: parfillskip
+#define LYX_FORMAT_TEX2LYX 656
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
#ifndef _MSC_VER
More information about the lyx-cvs
mailing list