[LyX/master] use package parskip to separate paragraphs with vertical space (#4796)

Juergen Spitzmueller spitz at lyx.org
Sun Jun 28 14:58:21 UTC 2020


commit b0c102cfb40985f46283e4fab0870ec5e2900699
Author: Juergen Spitzmueller <spitz at lyx.org>
Date:   Sun Jun 28 17:20:18 2020 +0200

    use package parskip to separate paragraphs with vertical space (#4796)
    
    File format change
---
 lib/chkconfig.ltx                |    1 +
 lib/doc/LaTeXConfig.lyx          |   57 +++++++++++++++++++++++++++-
 lib/lyx2lyx/lyx_2_4.py           |   63 +++++++++++++++++++++++++++++-
 src/BufferParams.cpp             |   22 ++++++----
 src/VSpace.cpp                   |   77 ++++++++++++++++++++++++++++++++-----
 src/VSpace.h                     |    2 +
 src/frontends/qt/GuiDocument.cpp |   62 ++++++++++++-------------------
 src/frontends/qt/GuiVSpace.cpp   |   28 +++++++++++---
 src/tex2lyx/Preamble.cpp         |   32 ++++++++++++---
 src/version.h                    |    4 +-
 10 files changed, 271 insertions(+), 77 deletions(-)

diff --git a/lib/chkconfig.ltx b/lib/chkconfig.ltx
index 4d647c6..9a15abc 100644
--- a/lib/chkconfig.ltx
+++ b/lib/chkconfig.ltx
@@ -405,6 +405,7 @@
 \TestPackage{nicefrac}
 \TestPackage{nomencl}
 \TestPackage{paralist}
+\TestPackage{parskip}
 \TestPackage{pdfcolmk}
 \TestPackage{pdflscape}
 \TestPackage{polyglossia}
diff --git a/lib/doc/LaTeXConfig.lyx b/lib/doc/LaTeXConfig.lyx
index 6e69bfd..bfaad60 100644
--- a/lib/doc/LaTeXConfig.lyx
+++ b/lib/doc/LaTeXConfig.lyx
@@ -1,5 +1,5 @@
 #LyX 2.4 created this file. For more info see https://www.lyx.org/
-\lyxformat 594
+\lyxformat 595
 \begin_document
 \begin_header
 \save_transient_properties true
@@ -5683,6 +5683,61 @@ longtable
 \family default
  is needed by \SpecialChar LyX
  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
 
 \begin_layout Subsection
diff --git a/lib/lyx2lyx/lyx_2_4.py b/lib/lyx2lyx/lyx_2_4.py
index f778b4a..4e2533c 100644
--- a/lib/lyx2lyx/lyx_2_4.py
+++ b/lib/lyx2lyx/lyx_2_4.py
@@ -3775,7 +3775,62 @@ def revert_ams_spaces(document):
         if i == -1:
             add_to_preamble(document, ["\\@ifundefined{thickspace}{\\usepackage{amsmath}}{}"])
             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
 #
@@ -3832,10 +3887,12 @@ convert = [
            [592, []],
            [593, [convert_counter_maintenance]],
            [594, []],
-           [595, []]
+           [595, []],
+           [596, [convert_parskip]]
           ]
 
-revert =  [[594, [revert_ams_spaces]],
+revert =  [[595, [revert_parskip]],
+           [594, [revert_ams_spaces]],
            [593, [revert_counter_inset]],
            [592, [revert_counter_maintenance]],
            [591, [revert_colrow_tracking]],
diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp
index 9f6a3fb..776c5c9 100644
--- a/src/BufferParams.cpp
+++ b/src/BufferParams.cpp
@@ -2003,26 +2003,30 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
 
 	if (paragraph_separation) {
 		// when skip separation
+		string psopt;
 		switch (getDefSkip().kind()) {
 		case VSpace::SMALLSKIP:
-			os << "\\setlength{\\parskip}{\\smallskipamount}\n";
+			psopt = "[skip=\\smallskipamount]";
 			break;
 		case VSpace::MEDSKIP:
-			os << "\\setlength{\\parskip}{\\medskipamount}\n";
+			psopt = "[skip=\\medskipamount]";
 			break;
 		case VSpace::BIGSKIP:
-			os << "\\setlength{\\parskip}{\\bigskipamount}\n";
+			psopt = "[skip=\\bigskipamount]";
+			break;
+		case VSpace::HALFLINE:
+			break;
+		case VSpace::FULLLINE:
+			psopt = "[skip=\\baselineskip]";
 			break;
 		case VSpace::LENGTH:
-			os << "\\setlength{\\parskip}{"
-			   << from_utf8(getDefSkip().length().asLatexString())
-			   << "}\n";
+			psopt = "[skip={" + getDefSkip().length().asLatexString() + "}]";
 			break;
-		default: // should never happen // Then delete it.
-			os << "\\setlength{\\parskip}{\\medskipamount}\n";
+		default:
 			break;
 		}
-		os << "\\setlength{\\parindent}{0pt}\n";
+		if (features.isAvailable("parskip"))
+			os << "\\usepackage" + psopt + "{parskip}\n";
 	} else {
 		// when separation by indentation
 		// only output something when a width is given
diff --git a/src/VSpace.cpp b/src/VSpace.cpp
index 971ac96..a2d4a3d 100644
--- a/src/VSpace.cpp
+++ b/src/VSpace.cpp
@@ -78,6 +78,10 @@ VSpace::VSpace(string const & data)
 		kind_ = MEDSKIP;
 	else if (prefixIs(input, "bigskip"))
 		kind_ = BIGSKIP;
+	else if (prefixIs(input, "halfline"))
+		kind_ = HALFLINE;
+	else if (prefixIs(input, "fullline"))
+		kind_ = FULLLINE;
 	else if (prefixIs(input, "vfill"))
 		kind_ = VFILL;
 	else if (isValidGlueLength(input, &len_))
@@ -111,12 +115,30 @@ string const VSpace::asLyXCommand() const
 {
 	string result;
 	switch (kind_) {
-	case DEFSKIP:   result = "defskip";      break;
-	case SMALLSKIP: result = "smallskip";    break;
-	case MEDSKIP:   result = "medskip";      break;
-	case BIGSKIP:   result = "bigskip";      break;
-	case VFILL:     result = "vfill";        break;
-	case LENGTH:    result = len_.asString(); break;
+	case DEFSKIP:
+		result = "defskip";
+		break;
+	case SMALLSKIP:
+		result = "smallskip";
+		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_)
 		result += '*';
@@ -138,6 +160,12 @@ string const VSpace::asLatexCommand(BufferParams const & params) const
 
 	case 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:
 		return keep_ ? "\\vspace*{\\fill}" : "\\vfill{}";
@@ -170,6 +198,12 @@ docstring const VSpace::asGUIName() const
 	case BIGSKIP:
 		result = _("Big skip");
 		break;
+	case HALFLINE:
+		result = _("Half line height");
+		break;
+	case FULLLINE:
+		result = _("Line height");
+		break;
 	case VFILL:
 		result = _("Vertical fill");
 		break;
@@ -187,16 +221,31 @@ string VSpace::asHTMLLength() const
 {
 	string result;
 	switch (kind_) {
-		case DEFSKIP:   result = "2ex"; break;
-		case SMALLSKIP: result = "1ex"; break;
-		case MEDSKIP:   result = "3ex"; break;
-		case BIGSKIP:   result = "5ex"; break;
+		case DEFSKIP:
+			result = "2ex";
+			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: {
 			Length tmp = len_.len();
 			if (tmp.value() > 0)
 				result = tmp.asHTMLString();
 		}
-		case VFILL:     break;
+		case VFILL:
+			break;
 	}
 	return result;
 }
@@ -227,6 +276,12 @@ int VSpace::inPixels(BufferView const & bv) const
 		// leave space for the vfill symbol
 		return 3 * default_height;
 
+	case HALFLINE:
+		return int(default_height / 2);
+
+	case FULLLINE:
+		return default_height;
+
 	case LENGTH:
 		return bv.inPixels(len_.len());
 
diff --git a/src/VSpace.h b/src/VSpace.h
index 0d154d6..2bce154 100644
--- a/src/VSpace.h
+++ b/src/VSpace.h
@@ -31,6 +31,8 @@ public:
 		SMALLSKIP,
 		MEDSKIP,
 		BIGSKIP,
+		HALFLINE,
+		FULLLINE,
 		VFILL,
 		LENGTH ///< user-defined length
 	};
diff --git a/src/frontends/qt/GuiDocument.cpp b/src/frontends/qt/GuiDocument.cpp
index bcf33c0..9d8de56 100644
--- a/src/frontends/qt/GuiDocument.cpp
+++ b/src/frontends/qt/GuiDocument.cpp
@@ -860,10 +860,12 @@ GuiDocument::GuiDocument(GuiView & lv)
 
 	textLayoutModule->indentCO->addItem(qt_("Default"));
 	textLayoutModule->indentCO->addItem(qt_("Custom"));
-	textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
-	textLayoutModule->skipCO->addItem(qt_("MedSkip"));
-	textLayoutModule->skipCO->addItem(qt_("BigSkip"));
-	textLayoutModule->skipCO->addItem(qt_("Custom"));
+	textLayoutModule->skipCO->addItem(qt_("Half line height"), VSpace::HALFLINE);
+	textLayoutModule->skipCO->addItem(qt_("Line height"), VSpace::FULLLINE);
+	textLayoutModule->skipCO->addItem(qt_("SmallSkip"), VSpace::SMALLSKIP);
+	textLayoutModule->skipCO->addItem(qt_("MedSkip"), VSpace::MEDSKIP);
+	textLayoutModule->skipCO->addItem(qt_("BigSkip"), VSpace::BIGSKIP);
+	textLayoutModule->skipCO->addItem(qt_("Custom"), VSpace::LENGTH);
 	textLayoutModule->lspacingCO->insertItem(
 		Spacing::Single, qt_("Single"));
 	textLayoutModule->lspacingCO->insertItem(
@@ -2028,7 +2030,9 @@ void GuiDocument::enableIndent(bool indent)
 
 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->skipLengthCO->setEnabled(enable);
 	isValid();
@@ -3611,25 +3615,24 @@ void GuiDocument::applyView()
 	} else {
 		// if paragraphs are separated by a skip
 		bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
-		switch (textLayoutModule->skipCO->currentIndex()) {
-		case 0:
-			bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
-			break;
-		case 1:
-			bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
-			break;
-		case 2:
-			bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
+		VSpace::VSpaceKind spacekind =
+			VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(textLayoutModule->skipCO->currentIndex()).toInt());
+		switch (spacekind) {
+		case VSpace::SMALLSKIP:
+		case VSpace::MEDSKIP:
+		case VSpace::BIGSKIP:
+		case VSpace::HALFLINE:
+		case VSpace::FULLLINE:
+			bp_.setDefSkip(VSpace(spacekind));
 			break;
-		case 3:
-			{
+		case VSpace::LENGTH: {
 			VSpace vs = VSpace(
 				widgetsToLength(textLayoutModule->skipLE,
 				textLayoutModule->skipLengthCO)
 				);
 			bp_.setDefSkip(vs);
 			break;
-			}
+		}
 		default:
 			// this should never happen
 			bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
@@ -4113,32 +4116,15 @@ void GuiDocument::paramsToDialog()
 		setIndent(indent);
 	} else {
 		textLayoutModule->skipRB->setChecked(true);
-		int skip = 0;
-		switch (bp_.getDefSkip().kind()) {
-		case VSpace::SMALLSKIP:
-			skip = 0;
-			break;
-		case VSpace::MEDSKIP:
-			skip = 1;
-			break;
-		case VSpace::BIGSKIP:
-			skip = 2;
-			break;
-		case VSpace::LENGTH:
-			{
-			skip = 3;
+		VSpace::VSpaceKind skip = bp_.getDefSkip().kind();
+		textLayoutModule->skipCO->setCurrentIndex(textLayoutModule->skipCO->findData(skip));
+		if (skip == VSpace::LENGTH) {
 			string const length = bp_.getDefSkip().asLyXCommand();
 			lengthToWidgets(textLayoutModule->skipLE,
 				textLayoutModule->skipLengthCO,
 				length, default_unit);
-			break;
-			}
-		default:
-			skip = 0;
-			break;
 		}
-		textLayoutModule->skipCO->setCurrentIndex(skip);
-		setSkip(skip);
+		setSkip(textLayoutModule->skipCO->currentIndex());
 	}
 
 	textLayoutModule->twoColumnCB->setChecked(
diff --git a/src/frontends/qt/GuiVSpace.cpp b/src/frontends/qt/GuiVSpace.cpp
index 6eec958..cbd0265 100644
--- a/src/frontends/qt/GuiVSpace.cpp
+++ b/src/frontends/qt/GuiVSpace.cpp
@@ -84,12 +84,28 @@ static void setWidgetsFromVSpace(VSpace const & space,
 {
 	int item = 0;
 	switch (space.kind()) {
-		case VSpace::DEFSKIP:   item = 0; break;
-		case VSpace::SMALLSKIP: item = 1; 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::DEFSKIP:
+			item = 0;
+			break;
+		case VSpace::SMALLSKIP:
+			item = 1;
+			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);
 	keep->setChecked(space.keep());
diff --git a/src/tex2lyx/Preamble.cpp b/src/tex2lyx/Preamble.cpp
index 875b61a..187a0da 100644
--- a/src/tex2lyx/Preamble.cpp
+++ b/src/tex2lyx/Preamble.cpp
@@ -203,7 +203,7 @@ const char * const known_xetex_packages[] = {"arabxetex", "fixlatvian",
 const char * const known_lyx_packages[] = {"amsbsy", "amsmath", "amssymb",
 "amstext", "amsthm", "array", "babel", "booktabs", "calc", "CJK", "color",
 "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",
 "tipx", "tone", "ulem", "url", "varioref", "verbatim", "wrapfig", "xcolor", "xltabular",
 "xunicode", 0};
@@ -1644,6 +1644,24 @@ void Preamble::handle_package(Parser &p, string const & name,
 		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()) {
 		if (name == "splitidx")
 			h_use_indices = "true";
@@ -1653,6 +1671,7 @@ void Preamble::handle_package(Parser &p, string const & name,
 			h_use_refstyle = true;
 		else if (name == "prettyref")
 			h_use_refstyle = false;
+
 		if (!in_lyx_preamble) {
 			h_preamble << package_beg_sep << name
 			           << package_mid_sep << "\\usepackage{"
@@ -2781,18 +2800,17 @@ void Preamble::parse(Parser & p, string const & forceclass,
 			string const name = p.verbatim_item();
 			string const content = p.verbatim_item();
 			// the paragraphs are only not indented when \parindent is set to zero
-			if (name == "\\parindent" && content != "") {
-				if (content[0] == '0')
-					h_paragraph_separation = "skip";
-				else
-					h_paragraph_indentation = translate_len(content);
-			} else if (name == "\\parskip") {
+			if (name == "\\parindent" && content != "")
+				h_paragraph_indentation = translate_len(content);
+			else if (name == "\\parskip" && isPackageUsed("parskip")) {
 				if (content == "\\smallskipamount")
 					h_defskip = "smallskip";
 				else if (content == "\\medskipamount")
 					h_defskip = "medskip";
 				else if (content == "\\bigskipamount")
 					h_defskip = "bigskip";
+				else if (content == "\\baselineskip")
+					h_defskip = "fullline";
 				else
 					h_defskip = translate_len(content);
 			} else if (name == "\\mathindent") {
diff --git a/src/version.h b/src/version.h
index fd40047..b8d30fd 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 595 // spitz: medspace and thickspace
-#define LYX_FORMAT_TEX2LYX 595
+#define LYX_FORMAT_LYX 596 // spitz: parskip
+#define LYX_FORMAT_TEX2LYX 596
 
 #if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
 #ifndef _MSC_VER


More information about the lyx-cvs mailing list