]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetListings.cpp
Fixup 572b06d6: reduce cache size for breakString
[lyx.git] / src / insets / InsetListings.cpp
index 2f1462a154a6419063ec5da984c76488be6c1897..67a046208542ce222b671301be29e2c78a73379e 100644 (file)
 #include "Buffer.h"
 #include "BufferView.h"
 #include "BufferParams.h"
-#include "Counters.h"
 #include "Cursor.h"
-#include "DispatchResult.h"
 #include "Encoding.h"
 #include "FuncRequest.h"
 #include "FuncStatus.h"
 #include "InsetCaption.h"
+#include "InsetLabel.h"
+#include "InsetLayout.h"
 #include "Language.h"
 #include "LaTeXFeatures.h"
 #include "Lexer.h"
 #include "output_latex.h"
+#include "output_docbook.h"
 #include "output_xhtml.h"
-#include "OutputParams.h"
-#include "TextClass.h"
 #include "TexRow.h"
 #include "texstream.h"
 
@@ -42,8 +41,8 @@
 #include "frontends/alert.h"
 #include "frontends/Application.h"
 
-#include "support/regex.h"
-
+#include <cstring>
+#include <regex>
 #include <sstream>
 
 using namespace std;
@@ -66,7 +65,7 @@ InsetListings::~InsetListings()
 }
 
 
-Inset::RowFlags InsetListings::rowFlags() const
+int InsetListings::rowFlags() const
 {
        return params().isInline() || params().isFloat() ? Inline : Display | AlignLeft;
 }
@@ -314,9 +313,11 @@ void InsetListings::latex(otexstream & os, OutputParams const & runparams) const
                        }
                }
                ++par;
-               // for the inline case, if there are multiple paragraphs
+               // Add new line between paragraphs in displayed listings.
+               // Exception: merged paragraphs in change tracking mode.
+               // Also, for the inline case, if there are multiple paragraphs
                // they are simply joined. Otherwise, expect latex errors.
-               if (par != end && !isInline && !captionline)
+               if (par != end && !isInline && !captionline && !par->parEndChange().deleted())
                        code += "\n";
        }
        if (isInline) {
@@ -480,6 +481,80 @@ docstring InsetListings::xhtml(XMLStream & os, OutputParams const & rp) const
 }
 
 
+void InsetListings::docbook(XMLStream & xs, OutputParams const & rp) const
+{
+       InsetLayout const & il = getLayout();
+       bool isInline = params().isInline();
+
+       if (!isInline && !xs.isLastTagCR())
+               xs << xml::CR();
+
+       // In case of caption, the code must be wrapped, for instance in a figure. Also detect if there is a label.
+       // http://www.sagehill.net/docbookxsl/ProgramListings.html
+       // TODO: parts of this code could be merged with InsetFloat and findLabelInParagraph.
+       InsetCaption const * caption = getCaptionInset();
+       if (caption) {
+               InsetLabel const * label = getLabelInset();
+
+               // Ensure that the label will not be output a second time as an anchor.
+               OutputParams rpNoLabel = rp;
+               if (label)
+                       rpNoLabel.docbook_anchors_to_ignore.emplace(label->screenLabel());
+
+               // Prepare the right set of attributes, including the label.
+               docstring attr = from_ascii("type='listing'");
+               if (label)
+                       attr += " xml:id=\"" + xml::cleanID(label->screenLabel()) + "\"";
+
+               // Finally, generate the wrapper (including the label).
+               xs << xml::StartTag("figure", attr);
+               xs << xml::CR();
+               xs << xml::StartTag("title");
+               xs << XMLStream::ESCAPE_NONE << getCaptionDocBook(rpNoLabel);
+               xs << xml::EndTag("title");
+               xs << xml::CR();
+       }
+
+       // Forge the attributes.
+       std::string attrs;
+       if (!il.docbookattr().empty())
+               attrs += " role=\"" + il.docbookattr() + "\"";
+       std::string const lang = params().getParamValue("language");
+       if (!lang.empty())
+               attrs += " language=\"" + lang + "\"";
+
+       // Determine the tag to use. Use the layout-defined value if outside a paragraph.
+       std::string tag = il.docbooktag();
+       if (isInline)
+               tag = "code";
+
+       // Start the listing.
+       xs << xml::StartTag(tag, attrs);
+       xs.startDivision(false);
+
+       // Deal with the content of the listing.
+       OutputParams newrp = rp;
+       newrp.pass_thru = true;
+       newrp.docbook_make_pars = false;
+       newrp.par_begin = 0;
+       newrp.par_end = text().paragraphs().size();
+       newrp.docbook_in_listing = true;
+
+       docbookParagraphs(text(), buffer(), xs, newrp);
+
+       // Done with the listing.
+       xs.endDivision();
+       xs << xml::EndTag(tag);
+       if (!isInline)
+               xs << xml::CR();
+
+       if (caption) {
+               xs << xml::EndTag("figure");
+               xs << xml::CR();
+       }
+}
+
+
 string InsetListings::contextMenuName() const
 {
        return "context-listings";
@@ -532,10 +607,10 @@ bool InsetListings::getStatus(Cursor & cur, FuncRequest const & cmd,
 docstring const InsetListings::buttonLabel(BufferView const & bv) const
 {
        // FIXME UNICODE
-       if (decoration() == InsetLayout::CLASSIC)
-               return isOpen(bv) ? _("Listing") : getNewLabel(_("Listing"));
-       else
-               return getNewLabel(_("Listing"));
+       docstring const locked = tempfile_ ? docstring(1, 0x1F512) : docstring();
+       if (decoration() == InsetDecoration::CLASSIC)
+               return locked + (isOpen(bv) ? _("Listing") : getNewLabel(_("Listing")));
+       return locked + getNewLabel(_("Listing"));
 }