use package parskip to separate paragraphs with vertical space (#4796)

File format change
This commit is contained in:
Juergen Spitzmueller 2020-06-28 17:20:18 +02:00
parent 3ebedf66dd
commit b0c102cfb4
10 changed files with 271 additions and 77 deletions

View File

@ -405,6 +405,7 @@
\TestPackage{nicefrac} \TestPackage{nicefrac}
\TestPackage{nomencl} \TestPackage{nomencl}
\TestPackage{paralist} \TestPackage{paralist}
\TestPackage{parskip}
\TestPackage{pdfcolmk} \TestPackage{pdfcolmk}
\TestPackage{pdflscape} \TestPackage{pdflscape}
\TestPackage{polyglossia} \TestPackage{polyglossia}

View File

@ -1,5 +1,5 @@
#LyX 2.4 created this file. For more info see https://www.lyx.org/ #LyX 2.4 created this file. For more info see https://www.lyx.org/
\lyxformat 594 \lyxformat 595
\begin_document \begin_document
\begin_header \begin_header
\save_transient_properties true \save_transient_properties true
@ -5683,6 +5683,61 @@ longtable
\family default \family default
is needed by \SpecialChar LyX is needed by \SpecialChar LyX
to output multi-page tables. to output multi-page tables.
\change_inserted -712698321 1593341214
\end_layout
\begin_layout Subsection
\change_deleted -712698321 1593341218
longtable
\change_inserted -712698321 1593341222
parskip
\change_unchanged
\end_layout
\begin_layout Description
Found:
\begin_inset Info
type "package"
arg "parskip"
\end_inset
\end_layout
\begin_layout Description
CTAN:
\family typewriter
macros/latex/
\change_deleted -712698321 1593341294
required/tools
\change_inserted -712698321 1593341297
contrib/parskip
\change_unchanged
/
\end_layout
\begin_layout Description
Notes: The package
\change_deleted -712698321 1593341266
\family sans
longtable
\change_inserted -712698321 1593341267
parskip
\change_unchanged
\family default
is needed by \SpecialChar LyX
to
\change_deleted -712698321 1593341302
output multi-page tables
\change_inserted -712698321 1593341311
separate paragraphs by vertical space
\change_unchanged
.
\end_layout \end_layout
\begin_layout Subsection \begin_layout Subsection

View File

@ -3776,6 +3776,61 @@ def revert_ams_spaces(document):
add_to_preamble(document, ["\\@ifundefined{thickspace}{\\usepackage{amsmath}}{}"]) add_to_preamble(document, ["\\@ifundefined{thickspace}{\\usepackage{amsmath}}{}"])
return return
def convert_parskip(document):
" Move old parskip settings to preamble "
i = find_token(document.header, "\\paragraph_separation skip", 0)
if i == -1:
return
j = find_token(document.header, "\\defskip", 0)
if j == -1:
document.warning("Malformed LyX document! Missing \\defskip.")
return
val = get_value(document.header, "\\defskip", j)
skipval = "\\medskipamount"
if val == "smallskip" or val == "medskip" or val == "bigskip":
skipval = "\\" + val + "amount"
else:
skipval = val
add_to_preamble(document, ["\\setlength{\\parskip}{" + skipval + "}", "\\setlength{\\parindent}{0pt}"])
document.header[i] = "\\paragraph_separation indent"
document.header[j] = "\\paragraph_indentation default"
def revert_parskip(document):
" Revert new parskip settings to preamble "
i = find_token(document.header, "\\paragraph_separation skip", 0)
if i == -1:
return
j = find_token(document.header, "\\defskip", 0)
if j == -1:
document.warning("Malformed LyX document! Missing \\defskip.")
return
val = get_value(document.header, "\\defskip", j)
skipval = ""
if val == "smallskip" or val == "medskip" or val == "bigskip":
skipval = "[skip=\\" + val + "amount]"
elif val == "fullline":
skipval = "[skip=\\baselineskip]"
elif val != "halfline":
skipval = "[skip={" + val + "}]"
add_to_preamble(document, ["\\usepackage" + skipval + "{parskip}"])
document.header[i] = "\\paragraph_separation indent"
document.header[j] = "\\paragraph_indentation default"
## ##
# Conversion hub # Conversion hub
# #
@ -3832,10 +3887,12 @@ convert = [
[592, []], [592, []],
[593, [convert_counter_maintenance]], [593, [convert_counter_maintenance]],
[594, []], [594, []],
[595, []] [595, []],
[596, [convert_parskip]]
] ]
revert = [[594, [revert_ams_spaces]], revert = [[595, [revert_parskip]],
[594, [revert_ams_spaces]],
[593, [revert_counter_inset]], [593, [revert_counter_inset]],
[592, [revert_counter_maintenance]], [592, [revert_counter_maintenance]],
[591, [revert_colrow_tracking]], [591, [revert_colrow_tracking]],

View File

@ -2003,26 +2003,30 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
if (paragraph_separation) { if (paragraph_separation) {
// when skip separation // when skip separation
string psopt;
switch (getDefSkip().kind()) { switch (getDefSkip().kind()) {
case VSpace::SMALLSKIP: case VSpace::SMALLSKIP:
os << "\\setlength{\\parskip}{\\smallskipamount}\n"; psopt = "[skip=\\smallskipamount]";
break; break;
case VSpace::MEDSKIP: case VSpace::MEDSKIP:
os << "\\setlength{\\parskip}{\\medskipamount}\n"; psopt = "[skip=\\medskipamount]";
break; break;
case VSpace::BIGSKIP: case VSpace::BIGSKIP:
os << "\\setlength{\\parskip}{\\bigskipamount}\n"; psopt = "[skip=\\bigskipamount]";
break;
case VSpace::HALFLINE:
break;
case VSpace::FULLLINE:
psopt = "[skip=\\baselineskip]";
break; break;
case VSpace::LENGTH: case VSpace::LENGTH:
os << "\\setlength{\\parskip}{" psopt = "[skip={" + getDefSkip().length().asLatexString() + "}]";
<< from_utf8(getDefSkip().length().asLatexString())
<< "}\n";
break; break;
default: // should never happen // Then delete it. default:
os << "\\setlength{\\parskip}{\\medskipamount}\n";
break; break;
} }
os << "\\setlength{\\parindent}{0pt}\n"; if (features.isAvailable("parskip"))
os << "\\usepackage" + psopt + "{parskip}\n";
} else { } else {
// when separation by indentation // when separation by indentation
// only output something when a width is given // only output something when a width is given

View File

@ -78,6 +78,10 @@ VSpace::VSpace(string const & data)
kind_ = MEDSKIP; kind_ = MEDSKIP;
else if (prefixIs(input, "bigskip")) else if (prefixIs(input, "bigskip"))
kind_ = BIGSKIP; kind_ = BIGSKIP;
else if (prefixIs(input, "halfline"))
kind_ = HALFLINE;
else if (prefixIs(input, "fullline"))
kind_ = FULLLINE;
else if (prefixIs(input, "vfill")) else if (prefixIs(input, "vfill"))
kind_ = VFILL; kind_ = VFILL;
else if (isValidGlueLength(input, &len_)) else if (isValidGlueLength(input, &len_))
@ -111,12 +115,30 @@ string const VSpace::asLyXCommand() const
{ {
string result; string result;
switch (kind_) { switch (kind_) {
case DEFSKIP: result = "defskip"; break; case DEFSKIP:
case SMALLSKIP: result = "smallskip"; break; result = "defskip";
case MEDSKIP: result = "medskip"; break; break;
case BIGSKIP: result = "bigskip"; break; case SMALLSKIP:
case VFILL: result = "vfill"; break; result = "smallskip";
case LENGTH: result = len_.asString(); break; break;
case MEDSKIP:
result = "medskip";
break;
case BIGSKIP:
result = "bigskip";
break;
case HALFLINE:
result = "halfline";
break;
case FULLLINE:
result = "fullline";
break;
case VFILL:
result = "vfill";
break;
case LENGTH:
result = len_.asString();
break;
} }
if (keep_) if (keep_)
result += '*'; result += '*';
@ -139,6 +161,12 @@ string const VSpace::asLatexCommand(BufferParams const & params) const
case BIGSKIP: case BIGSKIP:
return keep_ ? "\\vspace*{\\bigskipamount}" : "\\bigskip{}"; return keep_ ? "\\vspace*{\\bigskipamount}" : "\\bigskip{}";
case HALFLINE:
return keep_ ? "\\vspace*{.5\\baselineskip}" : "\\vspace{.5\\baselineskip}";
case FULLLINE:
return keep_ ? "\\vspace*{\\baselineskip}" : "\\vspace{\\baselineskip}";
case VFILL: case VFILL:
return keep_ ? "\\vspace*{\\fill}" : "\\vfill{}"; return keep_ ? "\\vspace*{\\fill}" : "\\vfill{}";
@ -170,6 +198,12 @@ docstring const VSpace::asGUIName() const
case BIGSKIP: case BIGSKIP:
result = _("Big skip"); result = _("Big skip");
break; break;
case HALFLINE:
result = _("Half line height");
break;
case FULLLINE:
result = _("Line height");
break;
case VFILL: case VFILL:
result = _("Vertical fill"); result = _("Vertical fill");
break; break;
@ -187,16 +221,31 @@ string VSpace::asHTMLLength() const
{ {
string result; string result;
switch (kind_) { switch (kind_) {
case DEFSKIP: result = "2ex"; break; case DEFSKIP:
case SMALLSKIP: result = "1ex"; break; result = "2ex";
case MEDSKIP: result = "3ex"; break; break;
case BIGSKIP: result = "5ex"; break; case SMALLSKIP:
result = "1ex";
break;
case MEDSKIP:
result = "3ex";
break;
case BIGSKIP:
result = "5ex";
break;
case HALFLINE:
result = "0.6em";
break;
case FULLLINE:
result = "1.2em";
break;
case LENGTH: { case LENGTH: {
Length tmp = len_.len(); Length tmp = len_.len();
if (tmp.value() > 0) if (tmp.value() > 0)
result = tmp.asHTMLString(); result = tmp.asHTMLString();
} }
case VFILL: break; case VFILL:
break;
} }
return result; return result;
} }
@ -227,6 +276,12 @@ int VSpace::inPixels(BufferView const & bv) const
// leave space for the vfill symbol // leave space for the vfill symbol
return 3 * default_height; return 3 * default_height;
case HALFLINE:
return int(default_height / 2);
case FULLLINE:
return default_height;
case LENGTH: case LENGTH:
return bv.inPixels(len_.len()); return bv.inPixels(len_.len());

View File

@ -31,6 +31,8 @@ public:
SMALLSKIP, SMALLSKIP,
MEDSKIP, MEDSKIP,
BIGSKIP, BIGSKIP,
HALFLINE,
FULLLINE,
VFILL, VFILL,
LENGTH ///< user-defined length LENGTH ///< user-defined length
}; };

View File

@ -860,10 +860,12 @@ GuiDocument::GuiDocument(GuiView & lv)
textLayoutModule->indentCO->addItem(qt_("Default")); textLayoutModule->indentCO->addItem(qt_("Default"));
textLayoutModule->indentCO->addItem(qt_("Custom")); textLayoutModule->indentCO->addItem(qt_("Custom"));
textLayoutModule->skipCO->addItem(qt_("SmallSkip")); textLayoutModule->skipCO->addItem(qt_("Half line height"), VSpace::HALFLINE);
textLayoutModule->skipCO->addItem(qt_("MedSkip")); textLayoutModule->skipCO->addItem(qt_("Line height"), VSpace::FULLLINE);
textLayoutModule->skipCO->addItem(qt_("BigSkip")); textLayoutModule->skipCO->addItem(qt_("SmallSkip"), VSpace::SMALLSKIP);
textLayoutModule->skipCO->addItem(qt_("Custom")); textLayoutModule->skipCO->addItem(qt_("MedSkip"), VSpace::MEDSKIP);
textLayoutModule->skipCO->addItem(qt_("BigSkip"), VSpace::BIGSKIP);
textLayoutModule->skipCO->addItem(qt_("Custom"), VSpace::LENGTH);
textLayoutModule->lspacingCO->insertItem( textLayoutModule->lspacingCO->insertItem(
Spacing::Single, qt_("Single")); Spacing::Single, qt_("Single"));
textLayoutModule->lspacingCO->insertItem( textLayoutModule->lspacingCO->insertItem(
@ -2028,7 +2030,9 @@ void GuiDocument::enableIndent(bool indent)
void GuiDocument::setSkip(int item) void GuiDocument::setSkip(int item)
{ {
bool const enable = (item == 3); VSpace::VSpaceKind kind =
VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(item).toInt());
bool const enable = (kind == VSpace::LENGTH);
textLayoutModule->skipLE->setEnabled(enable); textLayoutModule->skipLE->setEnabled(enable);
textLayoutModule->skipLengthCO->setEnabled(enable); textLayoutModule->skipLengthCO->setEnabled(enable);
isValid(); isValid();
@ -3611,18 +3615,17 @@ void GuiDocument::applyView()
} else { } else {
// if paragraphs are separated by a skip // if paragraphs are separated by a skip
bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation; bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
switch (textLayoutModule->skipCO->currentIndex()) { VSpace::VSpaceKind spacekind =
case 0: VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(textLayoutModule->skipCO->currentIndex()).toInt());
bp_.setDefSkip(VSpace(VSpace::SMALLSKIP)); switch (spacekind) {
case VSpace::SMALLSKIP:
case VSpace::MEDSKIP:
case VSpace::BIGSKIP:
case VSpace::HALFLINE:
case VSpace::FULLLINE:
bp_.setDefSkip(VSpace(spacekind));
break; break;
case 1: case VSpace::LENGTH: {
bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
break;
case 2:
bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
break;
case 3:
{
VSpace vs = VSpace( VSpace vs = VSpace(
widgetsToLength(textLayoutModule->skipLE, widgetsToLength(textLayoutModule->skipLE,
textLayoutModule->skipLengthCO) textLayoutModule->skipLengthCO)
@ -4113,32 +4116,15 @@ void GuiDocument::paramsToDialog()
setIndent(indent); setIndent(indent);
} else { } else {
textLayoutModule->skipRB->setChecked(true); textLayoutModule->skipRB->setChecked(true);
int skip = 0; VSpace::VSpaceKind skip = bp_.getDefSkip().kind();
switch (bp_.getDefSkip().kind()) { textLayoutModule->skipCO->setCurrentIndex(textLayoutModule->skipCO->findData(skip));
case VSpace::SMALLSKIP: if (skip == VSpace::LENGTH) {
skip = 0;
break;
case VSpace::MEDSKIP:
skip = 1;
break;
case VSpace::BIGSKIP:
skip = 2;
break;
case VSpace::LENGTH:
{
skip = 3;
string const length = bp_.getDefSkip().asLyXCommand(); string const length = bp_.getDefSkip().asLyXCommand();
lengthToWidgets(textLayoutModule->skipLE, lengthToWidgets(textLayoutModule->skipLE,
textLayoutModule->skipLengthCO, textLayoutModule->skipLengthCO,
length, default_unit); length, default_unit);
break;
} }
default: setSkip(textLayoutModule->skipCO->currentIndex());
skip = 0;
break;
}
textLayoutModule->skipCO->setCurrentIndex(skip);
setSkip(skip);
} }
textLayoutModule->twoColumnCB->setChecked( textLayoutModule->twoColumnCB->setChecked(

View File

@ -84,12 +84,28 @@ static void setWidgetsFromVSpace(VSpace const & space,
{ {
int item = 0; int item = 0;
switch (space.kind()) { switch (space.kind()) {
case VSpace::DEFSKIP: item = 0; break; case VSpace::DEFSKIP:
case VSpace::SMALLSKIP: item = 1; break; item = 0;
case VSpace::MEDSKIP: item = 2; break; break;
case VSpace::BIGSKIP: item = 3; break; case VSpace::SMALLSKIP:
case VSpace::VFILL: item = 4; break; item = 1;
case VSpace::LENGTH: item = 5; break; break;
case VSpace::MEDSKIP:
item = 2;
break;
case VSpace::BIGSKIP:
item = 3;
break;
case VSpace::VFILL:
item = 4;
break;
case VSpace::LENGTH:
item = 5;
break;
case VSpace::HALFLINE:
case VSpace::FULLLINE:
// not supported here yet
break;
} }
spacing->setCurrentIndex(item); spacing->setCurrentIndex(item);
keep->setChecked(space.keep()); keep->setChecked(space.keep());

View File

@ -203,7 +203,7 @@ const char * const known_xetex_packages[] = {"arabxetex", "fixlatvian",
const char * const known_lyx_packages[] = {"amsbsy", "amsmath", "amssymb", const char * const known_lyx_packages[] = {"amsbsy", "amsmath", "amssymb",
"amstext", "amsthm", "array", "babel", "booktabs", "calc", "CJK", "color", "amstext", "amsthm", "array", "babel", "booktabs", "calc", "CJK", "color",
"float", "fontspec", "framed", "graphicx", "hhline", "ifthen", "longtable", "float", "fontspec", "framed", "graphicx", "hhline", "ifthen", "longtable",
"makeidx", "minted", "multirow", "nomencl", "pdfpages", "prettyref", "refstyle", "makeidx", "minted", "multirow", "nomencl", "parskip", "pdfpages", "prettyref", "refstyle",
"rotating", "rotfloat", "splitidx", "setspace", "subscript", "tabularx","textcomp", "tipa", "rotating", "rotfloat", "splitidx", "setspace", "subscript", "tabularx","textcomp", "tipa",
"tipx", "tone", "ulem", "url", "varioref", "verbatim", "wrapfig", "xcolor", "xltabular", "tipx", "tone", "ulem", "url", "varioref", "verbatim", "wrapfig", "xcolor", "xltabular",
"xunicode", 0}; "xunicode", 0};
@ -1644,6 +1644,24 @@ void Preamble::handle_package(Parser &p, string const & name,
delete_opt(options, o); delete_opt(options, o);
} }
else if (name == "parskip" && options.size() < 2 && (opts.empty() || prefixIs(opts, "skip="))) {
if (opts.empty())
h_paragraph_separation = "halfline";
else {
if (opts == "skip=\\smallskipamount")
h_defskip = "smallskip";
else if (opts == "skip=\\medskipamount")
h_defskip = "medskip";
else if (opts == "skip=\\bigskipamount")
h_defskip = "bigskip";
else if (opts == "skip=\\baselineskip")
h_defskip = "fullline";
else
h_defskip = "opts";
h_paragraph_separation = "skip";
}
}
else if (is_known(name, known_lyx_packages) && options.empty()) { else if (is_known(name, known_lyx_packages) && options.empty()) {
if (name == "splitidx") if (name == "splitidx")
h_use_indices = "true"; h_use_indices = "true";
@ -1653,6 +1671,7 @@ void Preamble::handle_package(Parser &p, string const & name,
h_use_refstyle = true; h_use_refstyle = true;
else if (name == "prettyref") else if (name == "prettyref")
h_use_refstyle = false; h_use_refstyle = false;
if (!in_lyx_preamble) { if (!in_lyx_preamble) {
h_preamble << package_beg_sep << name h_preamble << package_beg_sep << name
<< package_mid_sep << "\\usepackage{" << package_mid_sep << "\\usepackage{"
@ -2781,18 +2800,17 @@ void Preamble::parse(Parser & p, string const & forceclass,
string const name = p.verbatim_item(); string const name = p.verbatim_item();
string const content = p.verbatim_item(); string const content = p.verbatim_item();
// the paragraphs are only not indented when \parindent is set to zero // the paragraphs are only not indented when \parindent is set to zero
if (name == "\\parindent" && content != "") { if (name == "\\parindent" && content != "")
if (content[0] == '0')
h_paragraph_separation = "skip";
else
h_paragraph_indentation = translate_len(content); h_paragraph_indentation = translate_len(content);
} else if (name == "\\parskip") { else if (name == "\\parskip" && isPackageUsed("parskip")) {
if (content == "\\smallskipamount") if (content == "\\smallskipamount")
h_defskip = "smallskip"; h_defskip = "smallskip";
else if (content == "\\medskipamount") else if (content == "\\medskipamount")
h_defskip = "medskip"; h_defskip = "medskip";
else if (content == "\\bigskipamount") else if (content == "\\bigskipamount")
h_defskip = "bigskip"; h_defskip = "bigskip";
else if (content == "\\baselineskip")
h_defskip = "fullline";
else else
h_defskip = translate_len(content); h_defskip = translate_len(content);
} else if (name == "\\mathindent") { } else if (name == "\\mathindent") {

View File

@ -32,8 +32,8 @@ extern char const * const lyx_version_info;
// Do not remove the comment below, so we get merge conflict in // Do not remove the comment below, so we get merge conflict in
// independent branches. Instead add your own. // independent branches. Instead add your own.
#define LYX_FORMAT_LYX 595 // spitz: medspace and thickspace #define LYX_FORMAT_LYX 596 // spitz: parskip
#define LYX_FORMAT_TEX2LYX 595 #define LYX_FORMAT_TEX2LYX 596
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX #if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
#ifndef _MSC_VER #ifndef _MSC_VER