]> 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 93daab4a334d88fa8ce45c7c4b6dbd67c75b2ba5..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"
 
@@ -43,8 +41,8 @@
 #include "frontends/alert.h"
 #include "frontends/Application.h"
 
-#include "support/regex.h"
-
+#include <cstring>
+#include <regex>
 #include <sstream>
 
 using namespace std;
@@ -67,7 +65,7 @@ InsetListings::~InsetListings()
 }
 
 
-Inset::RowFlags InsetListings::rowFlags() const
+int InsetListings::rowFlags() const
 {
        return params().isInline() || params().isFloat() ? Inline : Display | AlignLeft;
 }
@@ -315,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) {
@@ -484,28 +484,53 @@ 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();
 
-       if (!xs.isLastTagCR())
+       // 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.
-       string attrs;
+       std::string attrs;
        if (!il.docbookattr().empty())
                attrs += " role=\"" + il.docbookattr() + "\"";
-       string const lang = params().getParamValue("language");
+       std::string const lang = params().getParamValue("language");
        if (!lang.empty())
                attrs += " language=\"" + lang + "\"";
-       xs << xml::StartTag(il.docbooktag(), attrs);
-       xs.startDivision(false);
 
-       // Deal with the caption.
-       docstring caption = getCaptionDocBook(rp);
-       if (!caption.empty()) {
-               xs << xml::StartTag("bridgehead");
-               xs << XMLStream::ESCAPE_NONE;
-               xs << caption;
-               xs << xml::EndTag("bridgehead");
-       }
+       // 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;
@@ -519,8 +544,14 @@ void InsetListings::docbook(XMLStream & xs, OutputParams const & rp) const
 
        // Done with the listing.
        xs.endDivision();
-       xs << xml::EndTag(il.docbooktag());
-       xs << xml::CR();
+       xs << xml::EndTag(tag);
+       if (!isInline)
+               xs << xml::CR();
+
+       if (caption) {
+               xs << xml::EndTag("figure");
+               xs << xml::CR();
+       }
 }
 
 
@@ -576,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"));
 }