[LyX/master] DocBook: add more flexibility for floats.

Thibaut Cuvelier tcuvelier at lyx.org
Sun Sep 19 21:45:17 UTC 2021


commit 8b6e3d374996cc124a9830c71bc2bb744097a7a2
Author: Thibaut Cuvelier <tcuvelier at lyx.org>
Date:   Mon Sep 20 00:06:20 2021 +0200

    DocBook: add more flexibility for floats.
    
    Intended to fix #12371.
---
 lib/scripts/layout2layout.py |    7 ++-
 src/Floating.cpp             |   96 ++++++++++++++++++++++++++++--------------
 src/Floating.h               |   11 ++++-
 src/TextClass.cpp            |   21 ++++++++-
 4 files changed, 95 insertions(+), 40 deletions(-)

diff --git a/lib/scripts/layout2layout.py b/lib/scripts/layout2layout.py
index eb04f45..e7eb307 100644
--- a/lib/scripts/layout2layout.py
+++ b/lib/scripts/layout2layout.py
@@ -11,7 +11,7 @@
 # This script will update a .layout file to current format
 
 # The latest layout format is also defined in src/TextClass.cpp
-currentFormat = 93
+currentFormat = 94
 
 
 # Incremented to format 4, 6 April 2007, lasgouttes
@@ -316,6 +316,9 @@ currentFormat = 93
 # Incremented to format 93, 13 February 2021 by spitz
 # Add DocBookNoFontInside
 
+# Incremented to format 94, 19 September 2021 by tcuvelier
+# Add DocBookFloatType, DocBookCaption
+
 # Do not forget to document format change in Customization
 # Manual (section "Declaring a new text class").
 
@@ -566,7 +569,7 @@ def convert(lines, end_format):
                 i += 1
             continue
 
-        if 87 <= format <= 93:
+        if 87 <= format <= 94:
             # nothing to do.
             i += 1
             continue
diff --git a/src/Floating.cpp b/src/Floating.cpp
index fa93b97..ecd325f 100644
--- a/src/Floating.cpp
+++ b/src/Floating.cpp
@@ -31,8 +31,9 @@ Floating::Floating(string const & type, string const & placement,
 		   string const & listName, std::string const & listCmd,
 		   string const & refPrefix, std::string const & allowedplacement,
 		   string const & htmlTag, string const & htmlAttrib,
-		   docstring const & htmlStyle,
+		   docstring const & htmlStyle, std::string const & docbookTag,
 		   string const & docbookAttr, string const & docbookTagType,
+           std::string const & docbookFloatType, std::string const & docbookCaption,
            string const & required, bool usesfloat, bool ispredefined,
 		   bool allowswide, bool allowssideways)
 	: floattype_(type), placement_(placement), ext_(ext), within_(within),
@@ -41,26 +42,49 @@ Floating::Floating(string const & type, string const & placement,
 	  usesfloatpkg_(usesfloat), ispredefined_(ispredefined),
 	  allowswide_(allowswide), allowssideways_(allowssideways),
 	  html_tag_(htmlTag), html_attrib_(htmlAttrib), html_style_(htmlStyle),
-	  docbook_attr_(docbookAttr), docbook_tag_type_(docbookTagType)
-{}
-
-
-std::string Floating::docbookFloatType() const
+	  docbook_tag_(docbookTag), docbook_tag_type_(docbookTagType),
+	  docbook_caption_(docbookCaption)
 {
-	// TODO: configure this in the layouts?
-	if (floattype_ == "figure" || floattype_ == "graph" ||
-			floattype_ == "chart" || floattype_ == "scheme")  {
-		return "figure";
-	} else if (floattype_ == "table" || floattype_ == "tableau") {
-		return "table";
-	} else if (floattype_ == "algorithm") {
-		return "algorithm";
-	} else if (floattype_ == "video") {
-		return "video";
-	} else {
-		// If nothing matches, return something that will not be valid.
-		LYXERR0("Unrecognised float type: " + floattype_);
-		return "unknown";
+	// Implement some edge cases for DocBook. Both docbook_float_type_ and docbook_attr_ must be computed
+	// based on the given value of docbookFloatType; docbook_tag_ can still be guessed without correlation.
+
+	// Determine the value of docbook_float_type_.
+	{
+		// These are the allowed values for docbook_float_type_. Both docbook_attr_ and docbook_tag_type_
+		// depend on this list.
+		static std::set<std::string> allowedFloatTypes{"figure", "table", "algorithm", "video", "example"};
+
+		// If some type is predetermined in the layout, use it.
+		if (!docbookFloatType.empty() && allowedFloatTypes.find(docbookFloatType) != allowedFloatTypes.end())
+			docbook_float_type_ = docbookFloatType;
+		// Otherwise, try to guess the type.
+		else if (floattype_ == "figure" || floattype_ == "graph" ||
+		    floattype_ == "chart" || floattype_ == "scheme") {
+			docbook_float_type_ = "figure";
+		} else if (floattype_ == "table" || floattype_ == "tableau") {
+			docbook_float_type_ = "table";
+		} else if (floattype_ == "algorithm") {
+			docbook_float_type_ = "algorithm";
+		} else if (floattype_ == "video") {
+			docbook_float_type_ = "video";
+		} else {
+			// If nothing matches, return something that will not be valid.
+			LYXERR0("Unrecognised float type: " + floattype_);
+			docbook_float_type_ = "unknown";
+		}
+	}
+
+	// Determine the value of docbook_attr_.
+	{
+		std::set<std::string> achemso = {"chart", "graph", "scheme"};
+		bool hasType = docbook_attr_.find("type=") != std::string::npos;
+
+		// For algorithms, a type attribute must be mentioned, if not already present in docbook_attr_.
+		if (docbook_float_type_ == "algorithm" && !hasType)
+			docbook_attr_ += " type='algorithm'";
+		// Specific floats for achemso.
+		else if (docbook_float_type_ == "figure" && achemso.find(floattype_) != achemso.end())
+			docbook_attr_ += " type='" + floattype_ + "'";
 	}
 }
 
@@ -103,25 +127,30 @@ string Floating::defaultCSSClass() const
 }
 
 
+std::string Floating::docbookFloatType() const
+{
+	// All the work is done in the constructor.
+	return docbook_float_type_;
+}
+
+
 string Floating::docbookAttr() const
 {
-	std::set<std::string> achemso = { "chart", "graph", "scheme" };
-	// For algorithms, a type attribute must be mentioned, if not already present in docbook_attr_.
-	if (docbookFloatType() == "algorithm" && docbook_attr_.find("type=") != std::string::npos)
-		return docbook_attr_ + " type='algorithm'";
-	// Specific floats for achemso.
-	else if (docbookFloatType() == "figure" && achemso.find(floattype_) != achemso.end())
-		return docbook_attr_ + " type='" + floattype_ + "'";
-	else
-		return docbook_attr_;
+	return docbook_attr_;
 }
 
 
 string Floating::docbookTag(bool hasTitle) const
 {
-	// TODO: configure this in the layouts?
+	// If there is a preconfigured tag, use it.
+	if (!docbook_tag_.empty())
+		return docbook_tag_;
+
+	// Otherwise, guess it.
 	if (docbookFloatType() == "figure" || docbookFloatType() == "algorithm" || docbookFloatType() == "video") {
 		return hasTitle ? "figure" : "informalfigure";
+	} else if (docbookFloatType() == "example") {
+		return hasTitle ? "example" : "informalexample";
 	} else if (docbookFloatType() == "table") {
 		return hasTitle ? "table" : "informaltable";
 	} else {
@@ -142,8 +171,11 @@ string const & Floating::docbookTagType() const
 
 string const & Floating::docbookCaption() const
 {
-	docbook_caption_ = "";
-	if (floattype_ == "figure" || floattype_ == "algorithm")
+	if (!docbook_caption_.empty())
+		return docbook_caption_;
+
+	if (docbook_float_type_ == "figure" || docbook_float_type_ == "video" ||
+			docbook_float_type_ == "algorithm" || docbook_float_type_ == "example")
 		docbook_caption_ = "title";
 	else if (floattype_ == "table" || floattype_ == "tableau")
 		docbook_caption_ = "caption";
diff --git a/src/Floating.h b/src/Floating.h
index 4672d9a..7461e96 100644
--- a/src/Floating.h
+++ b/src/Floating.h
@@ -37,8 +37,9 @@ public:
 		 std::string const & listName, std::string const & listCmd,
 		 std::string const & refPrefix, std::string const & allowedplacement,
 		 std::string const & htmlTag, std::string const & htmlAttrib,
-		 docstring const & htmlStyle,
-		 std::string const & docbookAttr, std::string const & docbookTagType,
+		 docstring const & htmlStyle, std::string const & docbookTag,
+         std::string const & docbookAttr, std::string const & docbookTagType,
+		 std::string const & docbookFloatType, std::string const & docbookCaption,
 		 std::string const & required, bool usesfloat, bool ispredefined,
 		 bool allowswide, bool allowssideways);
 	///
@@ -135,10 +136,14 @@ private:
 	// has a title or not, an information that is not available in the layouts.
 	/// attribute (mostly, role)
 	mutable std::string docbook_caption_;
-	/// caption tag (mostly, either caption or title)
+	/// float tag
+	std::string docbook_tag_;
+	/// attributes for the float tag
 	std::string docbook_attr_;
 	/// DocBook tag type (block, paragraph, inline)
 	mutable std::string docbook_tag_type_;
+	/// DocBook float type, to override float_type_ (figure, table, algorithm, video)
+	mutable std::string docbook_float_type_;
 };
 
 
diff --git a/src/TextClass.cpp b/src/TextClass.cpp
index 1b72706..9546cee 100644
--- a/src/TextClass.cpp
+++ b/src/TextClass.cpp
@@ -59,7 +59,7 @@ namespace lyx {
 // You should also run the development/tools/updatelayouts.py script,
 // to update the format of all of our layout files.
 //
-int const LAYOUT_FORMAT = 93; // tcuvelier: DocBookNoFontInside
+int const LAYOUT_FORMAT = 94; // tcuvelier: DocBookFloatType, DocBookCaption
 
 
 // Layout format for the current lyx file format. Controls which format is
@@ -1402,8 +1402,10 @@ bool TextClass::readFloat(Lexer & lexrc)
 		FT_HTMLATTR,
 		FT_HTMLTAG,
 		FT_DOCBOOKATTR,
+		FT_DOCBOOKFLOATTYPE,
 		FT_DOCBOOKTAG,
 		FT_DOCBOOKTAGTYPE,
+		FT_DOCBOOKCAPTION,
 		FT_LISTCOMMAND,
 		FT_REFPREFIX,
 		FT_ALLOWED_PLACEMENT,
@@ -1418,6 +1420,8 @@ bool TextClass::readFloat(Lexer & lexrc)
 		{ "allowssideways", FT_ALLOWS_SIDEWAYS },
 		{ "allowswide", FT_ALLOWS_WIDE },
 		{ "docbookattr", FT_DOCBOOKATTR },
+		{ "docbookcaption", FT_DOCBOOKCAPTION },
+		{ "docbookfloattype", FT_DOCBOOKFLOATTYPE },
 		{ "docbooktag", FT_DOCBOOKTAG },
 		{ "docbooktagtype", FT_DOCBOOKTAGTYPE },
 		{ "end", FT_END },
@@ -1445,8 +1449,10 @@ bool TextClass::readFloat(Lexer & lexrc)
 	docstring htmlstyle;
 	string htmltag;
 	string docbookattr;
+	string docbookcaption;
 	string docbooktag;
 	string docbooktagtype;
+	string docbookfloattype;
 	string listname;
 	string listcommand;
 	string name;
@@ -1564,6 +1570,10 @@ bool TextClass::readFloat(Lexer & lexrc)
 			lexrc.next();
 			docbookattr = lexrc.getString();
 			break;
+		case FT_DOCBOOKCAPTION:
+			lexrc.next();
+			docbookcaption = lexrc.getString();
+			break;
 		case FT_DOCBOOKTAG:
 			lexrc.next();
 			docbooktag = lexrc.getString();
@@ -1572,6 +1582,10 @@ bool TextClass::readFloat(Lexer & lexrc)
 			lexrc.next();
 			docbooktagtype = lexrc.getString();
 			break;
+		case FT_DOCBOOKFLOATTYPE:
+			lexrc.next();
+			docbookfloattype = lexrc.getString();
+			break;
 		case FT_END:
 			getout = true;
 			break;
@@ -1602,8 +1616,9 @@ bool TextClass::readFloat(Lexer & lexrc)
 		}
 		Floating fl(type, placement, ext, within, style, name,
 			listname, listcommand, refprefix, allowed_placement,
-			htmltag, htmlattr, htmlstyle, docbookattr,
-			docbooktagtype, required, usesfloat, ispredefined,
+			htmltag, htmlattr, htmlstyle, docbooktag, docbookattr,
+			docbooktagtype, docbookfloattype, docbookcaption,
+			required, usesfloat, ispredefined,
 	        allowswide, allowssideways);
 		floatlist_.newFloat(fl);
 		// each float has its own counter


More information about the lyx-cvs mailing list