One thing I don't like about the listings implementation is that you have to 
insert the caption via the dialog (which is not only unusual, but also 
doesn't let you use the crossrefs dialog etc.).

The attached patch uses the caption and label insets instead. It needs 
testing.

If we'd put this in before the next beta, we wouldn't need to change the file 
format.

Jürgen
Index: lib/layouts/stdcounters.inc
===================================================================
--- lib/layouts/stdcounters.inc	(Revision 18300)
+++ lib/layouts/stdcounters.inc	(Arbeitskopie)
@@ -76,3 +76,7 @@
 Counter
 	Name                 equation
 End
+
+Counter
+	Name                 listing
+End
Index: src/insets/InsetCaption.cpp
===================================================================
--- src/insets/InsetCaption.cpp	(Revision 18300)
+++ src/insets/InsetCaption.cpp	(Arbeitskopie)
@@ -278,6 +278,20 @@
 }
 
 
+int InsetCaption::getArgument(Buffer const & buf, odocstream & os,
+                        OutputParams const & runparams) const
+{
+	return InsetText::latex(buf, os, runparams);
+}
+
+
+int InsetCaption::getOptArg(Buffer const & buf, odocstream & os,
+                        OutputParams const & runparams) const
+{
+	return latexOptArgInsets(buf, paragraphs()[0], os, runparams, 1);
+}
+
+
 void InsetCaption::computeFullLabel(Buffer const & buf) const
 {
 	if (type_.empty())
Index: src/insets/InsetListings.h
===================================================================
--- src/insets/InsetListings.h	(Revision 18300)
+++ src/insets/InsetListings.h	(Arbeitskopie)
@@ -67,6 +67,8 @@
 	///
 	void setButtonLabel();
 	///
+	docstring getCaption(Buffer const &, OutputParams const &) const;
+	///
 	InsetListingsParams params_;
 };
 
Index: src/insets/InsetCaption.h
===================================================================
--- src/insets/InsetCaption.h	(Revision 18300)
+++ src/insets/InsetCaption.h	(Arbeitskopie)
@@ -69,6 +69,12 @@
 	///
 	int docbook(Buffer const & buf, odocstream & os,
 	            OutputParams const & runparams) const;
+	/// return the mandatory argument (LaTeX format) only
+	int getArgument(Buffer const & buf, odocstream & os,
+	          OutputParams const &) const;
+	/// return the optional argument(s) only
+	int getOptArg(Buffer const & buf, odocstream & os,
+	          OutputParams const &) const;
 	///
 	void setCount(int c) { counter_ = c; }
 	///
Index: src/insets/InsetListings.cpp
===================================================================
--- src/insets/InsetListings.cpp	(Revision 18300)
+++ src/insets/InsetListings.cpp	(Arbeitskopie)
@@ -4,6 +4,7 @@
  * Licence details can be found in the file COPYING.
  *
  * \author Bo Peng
+ * \author Jürgen Spitzmüller
  *
  * Full author contact details are available in file CREDITS.
  */
@@ -11,6 +12,7 @@
 #include <config.h>
 
 #include "InsetListings.h"
+#include "InsetCaption.h"
 
 #include "Language.h"
 #include "gettext.h"
@@ -127,8 +129,8 @@
 }
 
 
-int InsetListings::latex(Buffer const &, odocstream & os,
-		    OutputParams const &) const
+int InsetListings::latex(Buffer const & buf, odocstream & os,
+		    OutputParams const & runparams) const
 {
 	string param_string = params().encodedString();
 	// NOTE: I use {} to quote text, which is an experimental feature
@@ -141,10 +143,18 @@
 		else
 			os << "\\lstinline[" << from_ascii(param_string) << "]{";
 	} else {
-		if (param_string.empty())
+		docstring const caption = getCaption(buf, runparams);
+		if (param_string.empty() && caption.empty())
 			os << "\n\\begingroup\n\\inputencoding{latin1}\n\\begin{lstlisting}\n";
-		else
-			os << "\n\\begingroup\n\\inputencoding{latin1}\n\\begin{lstlisting}[" << from_ascii(param_string) << "]\n";
+		else {
+			os << "\n\\begingroup\n\\inputencoding{latin1}\n\\begin{lstlisting}[";
+			if (!caption.empty()) {
+				os << "caption={" << caption << '}';
+				if (!param_string.empty())
+					os << ',';
+			}
+			os << from_ascii(param_string) << "]\n";
+		}
 		lines += 4;
 	}
 	ParagraphList::const_iterator par = paragraphs().begin();
@@ -152,16 +162,19 @@
 
 	while (par != end) {
 		pos_type siz = par->size();
+		bool captionline = false;
 		for (pos_type i = 0; i < siz; ++i) {
-			// ignore all struck out text
-			if (par->isDeleted(i))
+			if (i == 0 && par->isInset(i) && i + 1 == siz)
+				captionline = true;
+			// ignore all struck out text and (caption) insets
+			if (par->isDeleted(i) || par->isInset(i))
 				continue;
 			os.put(par->getChar(i));
 		}
 		++par;
 		// for the inline case, if there are multiple paragraphs
-		// they are simply joined. Otherwise, expect latex errors. 
-		if (par != end && !lstinline) {
+		// they are simply joined. Otherwise, expect latex errors.
+		if (par != end && !lstinline && !captionline) {
 			os << "\n";
 			++lines;
 		}
@@ -210,6 +223,9 @@
 		case LFUN_INSET_DIALOG_UPDATE:
 			status.enabled(true);
 			return true;
+		case LFUN_CAPTION_INSERT:
+			status.enabled(!params().isInline());
+			return true;
 		default:
 			return InsetERT::getStatus(cur, cmd, status);
 	}
@@ -245,6 +261,31 @@
 }
 
 
+docstring InsetListings::getCaption(Buffer const & buf,
+		    OutputParams const & runparams) const
+{
+	if (paragraphs().empty())
+		return docstring();
+
+	ParagraphList::const_iterator pit = paragraphs().begin();
+	for (; pit != paragraphs().end(); ++pit) {
+		InsetList::const_iterator it = pit->insetlist.begin();
+		for (; it != pit->insetlist.end(); ++it) {
+			Inset & inset = *it->inset;
+			if (inset.lyxCode() == Inset::CAPTION_CODE) {
+				odocstringstream ods;
+				InsetCaption * ins =
+					static_cast<InsetCaption *>(it->inset);
+				ins->getOptArg(buf, ods, runparams);
+				ins->getArgument(buf, ods, runparams);
+				return ods.str();
+			}
+		}
+	}
+	return docstring();
+}
+
+
 string const InsetListingsMailer::name_("listings");
 
 InsetListingsMailer::InsetListingsMailer(InsetListings & inset)
Index: src/buffer_funcs.cpp
===================================================================
--- src/buffer_funcs.cpp	(Revision 18300)
+++ src/buffer_funcs.cpp	(Arbeitskopie)
@@ -417,6 +417,8 @@
 			// FIXME: are "table" and "Table" the correct type and label?
 			setCaptionLabels(inset, "table", from_ascii("Table"), counters);
 		}
+		else if (inset.lyxCode() == Inset::LISTINGS_CODE)
+			setCaptionLabels(inset, "listing", from_ascii("Listing"), counters);
 	}
 }
 
Index: src/Text.cpp
===================================================================
--- src/Text.cpp	(Revision 18300)
+++ src/Text.cpp	(Arbeitskopie)
@@ -1835,6 +1835,8 @@
 		name = from_ascii("thm");
 	else if (name == "Foot")
 		name = from_ascii("fn");
+	else if (name == "listing")
+		name = from_ascii("lst");
 		
 	if (!name.empty())
 		text = name.substr(0, 3) + ':' + text;

Reply via email to