- // For some strange reason gcc 3.2 and 3.3 do not accept
- // Buffer buffer(string(), false);
- // This needs to be static to avoid a memory leak. When a Buffer is
- // constructed, it constructs a BufferParams, which in turn constructs
- // a DocumentClass, via new, that is never deleted. If we were to go to
- // some kind of garbage collection there, or a shared_ptr, then this
- // would not be needed.
- static Buffer buffer("", false);
- buffer.setUnnamed(true);
- buffer.paragraphs() = paragraphs;
- buffer.params().setDocumentClass(docclass);
- ostringstream lyx;
- if (buffer.write(lyx))
- theClipboard().put(lyx.str(), plaintext);
- else
- theClipboard().put(string(), plaintext);
+ // This used to need to be static to avoid a memory leak. It no longer needs
+ // to be so, but the alternative is to construct a new one of these (with a
+ // new temporary directory, etc) every time, and then to destroy it. So maybe
+ // it's worth just keeping this one around.
+ static TempFile tempfile("clipboard.internal");
+ tempfile.setAutoRemove(false);
+ // The initialization of staticbuffer is thread-safe. Using a lambda
+ // guarantees that the properties are set only once.
+ static Buffer * staticbuffer = [&](){
+ Buffer * b =
+ theBufferList().newInternalBuffer(tempfile.name().absFileName());
+ b->setUnnamed(true);
+ b->inset().setBuffer(*b);
+ //initialize staticbuffer with b
+ return b;
+ }();
+ // Use a clone for the complicated stuff so that we do not need to clean
+ // up in order to avoid a crash.
+ Buffer * buffer = staticbuffer->cloneBufferOnly();
+ LASSERT(buffer, return 0);
+
+ // This needs doing every time.
+ // Since setDocumentClass() causes deletion of the old document class
+ // we need to reset all layout pointers in paragraphs (otherwise they
+ // would be dangling).
+ ParIterator const end = buffer->par_iterator_end();
+ for (ParIterator it = buffer->par_iterator_begin(); it != end; ++it) {
+ docstring const name = it->layout().name();
+ if (docclass->hasLayout(name))
+ it->setLayout((*docclass)[name]);
+ else
+ it->setPlainOrDefaultLayout(*docclass);
+ }
+ buffer->params().setDocumentClass(docclass);
+
+ // we will use pasteSelectionHelper to copy the paragraphs into the
+ // temporary Buffer, since it does a lot of things to fix them up.
+ DocIterator dit = doc_iterator_begin(buffer, &buffer->inset());
+ ErrorList el;
+ pasteSelectionHelper(dit, paragraphs, docclass, cap::BRANCH_ADD, el);
+
+ return buffer;
+}
+
+
+void putClipboard(ParagraphList const & paragraphs,
+ DocumentClassConstPtr docclass, docstring const & plaintext)
+{
+ Buffer * buffer = copyToTempBuffer(paragraphs, docclass);
+ if (!buffer) // already asserted in copyToTempBuffer()
+ return;
+
+ // We don't want to produce images that are not used. Therefore,
+ // output formulas as MathML. Even if this is not understood by all
+ // applications, the number that can parse it should go up in the future.
+ buffer->params().html_math_output = BufferParams::MathML;
+
+ // Make sure MarkAsExporting is deleted before buffer is
+ {
+ // The Buffer is being used to export. This is necessary so that the
+ // updateMacros call will record the needed information.
+ MarkAsExporting mex(buffer);
+
+ buffer->updateBuffer(Buffer::UpdateMaster, OutputUpdate);
+ buffer->updateMacros();
+ buffer->updateMacroInstances(OutputUpdate);
+
+ // LyX's own format
+ string lyx;
+ ostringstream oslyx;
+ if (buffer->write(oslyx))
+ lyx = oslyx.str();
+
+ // XHTML format
+ odocstringstream oshtml;
+ OutputParams runparams(encodings.fromLyXName("utf8"));
+ // We do not need to produce images, etc.
+ runparams.dryrun = true;
+ // We are not interested in errors (bug 8866)
+ runparams.silent = true;
+ buffer->writeLyXHTMLSource(oshtml, runparams, Buffer::FullSource);
+
+ theClipboard().put(lyx, oshtml.str(), plaintext);
+ }
+