int InsetERT::plaintext(odocstringstream & os, OutputParams const & rp, size_t max_length) const { if (!rp.inIndexEntry) // do not output TeX code return 0; ParagraphList::const_iterator par = paragraphs().begin(); ParagraphList::const_iterator end = paragraphs().end(); while (par != end && os.str().size() <= max_length) { pos_type siz = par->size(); for (pos_type i = 0; i < siz; ++i) { char_type const c = par->getChar(i); // output the active characters switch (c) { case '|': case '!': case '@': os.put(c); break; default: break; } } ++par; } return 0; }
ParagraphList::const_iterator makeCommand(Buffer const & buf, odocstream & os, OutputParams const & runparams, Text const & text, ParagraphList::const_iterator const & pbegin, ParagraphList::const_iterator const & pend) { ParagraphList const & paragraphs = text.paragraphs(); ParagraphList::const_iterator par = pbegin; Layout const & bstyle = par->layout(); //Open outter tag sgml::openTag(buf, os, runparams, *pbegin); os << '\n'; // Label around sectioning number: if (!bstyle.labeltag().empty()) { sgml::openTag(os, bstyle.labeltag()); // We don't care about appendix in DOCBOOK. os << par->expandDocBookLabel(bstyle, buf.params()); sgml::closeTag(os, bstyle.labeltag()); } // Opend inner tag and close inner tags sgml::openTag(os, bstyle.innertag()); par->simpleDocBookOnePar(buf, os, runparams, text.outerFont(distance(paragraphs.begin(), par))); sgml::closeTag(os, bstyle.innertag()); os << '\n'; ++par; while (par != pend) { Layout const & style = par->layout(); ParagraphList::const_iterator send; switch (style.latextype) { case LATEX_COMMAND: { send = searchCommand(par, pend); par = makeCommand(buf, os, runparams, text, par,send); break; } case LATEX_ENVIRONMENT: case LATEX_ITEM_ENVIRONMENT: { send = searchEnvironment(par, pend); par = makeEnvironment(buf, os, runparams, text, par,send); break; } case LATEX_PARAGRAPH: send = searchParagraph(par, pend); par = makeParagraph(buf, os, runparams, text, par,send); break; default: break; } } // Close outter tag sgml::closeTag(os, *pbegin); return pend; }
int InsetText::docbook(odocstream & os, OutputParams const & runparams) const { ParagraphList::const_iterator const beg = paragraphs().begin(); if (!undefined()) sgml::openTag(os, getLayout().latexname(), beg->getID(buffer(), runparams) + getLayout().latexparam()); docbookParagraphs(text_, buffer(), os, runparams); if (!undefined()) sgml::closeTag(os, getLayout().latexname()); return 0; }
InsetCaption const * InsetText::getCaptionInset() const { 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() == CAPTION_CODE) { InsetCaption const * ins = static_cast<InsetCaption const *>(it->inset); return ins; } } } return 0; }
void InsetText::setMacrocontextPositionRecursive(DocIterator const & pos) { text_.setMacrocontextPosition(pos); ParagraphList::const_iterator pit = paragraphs().begin(); ParagraphList::const_iterator pend = paragraphs().end(); for (; pit != pend; ++pit) { InsetList::const_iterator iit = pit->insetList().begin(); InsetList::const_iterator end = pit->insetList().end(); for (; iit != end; ++iit) { if (InsetText * txt = iit->inset->asInsetText()) { DocIterator ppos(pos); ppos.push_back(CursorSlice(*txt)); iit->inset->asInsetText()->setMacrocontextPositionRecursive(ppos); } } } }
int InsetERT::docbook(odocstream & os, OutputParams const &) const { // FIXME can we do the same thing here as for LaTeX? ParagraphList::const_iterator par = paragraphs().begin(); ParagraphList::const_iterator end = paragraphs().end(); int lines = 0; while (par != end) { pos_type siz = par->size(); for (pos_type i = 0; i < siz; ++i) os.put(par->getChar(i)); ++par; if (par != end) { os << "\n"; ++lines; } } return lines; }
void InsetText::addPreview(DocIterator const & text_inset_pos, PreviewLoader & loader) const { ParagraphList::const_iterator pit = paragraphs().begin(); ParagraphList::const_iterator pend = paragraphs().end(); int pidx = 0; DocIterator inset_pos = text_inset_pos; inset_pos.push_back(CursorSlice(*const_cast<InsetText *>(this))); for (; pit != pend; ++pit, ++pidx) { InsetList::const_iterator it = pit->insetList().begin(); InsetList::const_iterator end = pit->insetList().end(); inset_pos.pit() = pidx; for (; it != end; ++it) { inset_pos.pos() = it->pos; it->inset->addPreview(inset_pos, loader); } } }
ParagraphList::const_iterator makeParagraph( Buffer const & buf, odocstream & os, OutputParams const & runparams, Text const & text, ParagraphList::const_iterator const & pbegin, ParagraphList::const_iterator const & pend) { ParagraphList const & paragraphs = text.paragraphs(); for (ParagraphList::const_iterator par = pbegin; par != pend; ++par) { if (par != pbegin) os << '\n'; bool const default_or_plain = (buf.params().documentClass().isDefaultLayout(par->layout()) || buf.params().documentClass().isPlainLayout(par->layout())); if (default_or_plain && par->emptyTag()) { par->simpleDocBookOnePar(buf, os, runparams, text.outerFont(distance(paragraphs.begin(), par))); } else { sgml::openTag(buf, os, runparams, *par); par->simpleDocBookOnePar(buf, os, runparams, text.outerFont(distance(paragraphs.begin(), par))); sgml::closeTag(os, *par); } } return pend; }
ParagraphList::const_iterator searchEnvironment( ParagraphList::const_iterator p, ParagraphList::const_iterator const & pend) { Layout const & bstyle = p->layout(); size_t const depth = p->params().depth(); for (++p; p != pend; ++p) { Layout const & style = p->layout(); if (style.latextype == LATEX_COMMAND) return p; if (style.latextype == LATEX_PARAGRAPH) { if (p->params().depth() > depth) continue; return p; } if (p->params().depth() < depth) return p; if (style.latexname() != bstyle.latexname() && p->params().depth() == depth) return p; } return pend; }
bool InsetText::getStatus(Cursor & cur, FuncRequest const & cmd, FuncStatus & status) const { switch (cmd.action()) { case LFUN_INSET_DISSOLVE: { bool const main_inset = &buffer().inset() == this; bool const target_inset = cmd.argument().empty() || cmd.getArg(0) == insetName(lyxCode()); bool const one_cell = nargs() == 1; if (target_inset) status.setEnabled(!main_inset && one_cell); return target_inset; } case LFUN_ARGUMENT_INSERT: { string const arg = cmd.getArg(0); if (arg.empty()) { status.setEnabled(false); return true; } if (&buffer().inset() == this || !cur.paragraph().layout().args().empty()) return text_.getStatus(cur, cmd, status); Layout::LaTeXArgMap args = getLayout().args(); Layout::LaTeXArgMap::const_iterator const lait = args.find(arg); if (lait != args.end()) { status.setEnabled(true); ParagraphList::const_iterator pit = paragraphs().begin(); for (; pit != paragraphs().end(); ++pit) { InsetList::const_iterator it = pit->insetList().begin(); InsetList::const_iterator end = pit->insetList().end(); for (; it != end; ++it) { if (it->inset->lyxCode() == ARG_CODE) { InsetArgument const * ins = static_cast<InsetArgument const *>(it->inset); if (ins->name() == arg) { // we have this already status.setEnabled(false); return true; } } } } } else status.setEnabled(false); return true; } default: // Dispatch only to text_ if the cursor is inside // the text_. It is not for context menus (bug 5797). bool ret = false; if (cur.text() == &text_) ret = text_.getStatus(cur, cmd, status); if (!ret) ret = Inset::getStatus(cur, cmd, status); return ret; } }
ParagraphList::const_iterator makeEnvironment( Buffer const & buf, odocstream & os, OutputParams const & runparams, Text const & text, ParagraphList::const_iterator const & pbegin, ParagraphList::const_iterator const & pend) { ParagraphList const & paragraphs = text.paragraphs(); ParagraphList::const_iterator par = pbegin; Layout const & defaultstyle = buf.params().documentClass().defaultLayout(); Layout const & bstyle = par->layout(); string item_tag; // Opening outter tag sgml::openTag(buf, os, runparams, *pbegin); os << '\n'; if (bstyle.latextype == LATEX_ENVIRONMENT && bstyle.pass_thru) os << "<![CDATA["; while (par != pend) { Layout const & style = par->layout(); ParagraphList::const_iterator send; string id = par->getID(buf, runparams); string wrapper = ""; pos_type sep = 0; // Opening inner tag switch (bstyle.latextype) { case LATEX_ENVIRONMENT: if (!bstyle.innertag().empty()) { sgml::openTag(os, bstyle.innertag(), id); } break; case LATEX_ITEM_ENVIRONMENT: if (!bstyle.labeltag().empty()) { sgml::openTag(os, bstyle.innertag(), id); sgml::openTag(os, bstyle.labeltag()); sep = par->firstWordDocBook(os, runparams) + 1; sgml::closeTag(os, bstyle.labeltag()); } wrapper = defaultstyle.latexname(); // If a sub list (embedded list) appears next with a // different depth, then there is no need to open // another tag at the current depth. if(par->params().depth() == pbegin->params().depth()) { sgml::openTag(os, bstyle.itemtag()); } break; default: break; } switch (style.latextype) { case LATEX_ENVIRONMENT: case LATEX_ITEM_ENVIRONMENT: { if (par->params().depth() == pbegin->params().depth()) { sgml::openTag(os, wrapper); par->simpleDocBookOnePar(buf, os, runparams, text.outerFont(distance(paragraphs.begin(), par)), sep); sgml::closeTag(os, wrapper); ++par; } else { send = searchEnvironment(par, pend); par = makeEnvironment(buf, os, runparams, text, par,send); } break; } case LATEX_PARAGRAPH: send = searchParagraph(par, pend); par = makeParagraph(buf, os, runparams, text, par,send); break; case LATEX_LIST_ENVIRONMENT: case LATEX_BIB_ENVIRONMENT: case LATEX_COMMAND: // FIXME This means that we are just skipping any paragraph that // isn't implemented above, and this includes lists. ++par; break; } // Closing inner tag switch (bstyle.latextype) { case LATEX_ENVIRONMENT: if (!bstyle.innertag().empty()) { sgml::closeTag(os, bstyle.innertag()); os << '\n'; } break; case LATEX_ITEM_ENVIRONMENT: // If a sub list (embedded list) appears next, then // there is no need to close the current tag. // par should have already been incremented to the next // element. So we can compare the depth of the next // element with pbegin. // We need to be careful, that we don't dereference par // when par == pend but at the same time that the // current tag is closed. if((par != pend && par->params().depth() == pbegin->params().depth()) || par == pend) { sgml::closeTag(os, bstyle.itemtag()); } if (!bstyle.labeltag().empty()) sgml::closeTag(os, bstyle.innertag()); break; default: break; } } if (bstyle.latextype == LATEX_ENVIRONMENT && bstyle.pass_thru) os << "]]>"; // Closing outter tag sgml::closeTag(os, *pbegin); return pend; }
void InsetListings::latex(otexstream & os, OutputParams const & runparams) const { string param_string = params().params(); // NOTE: I use {} to quote text, which is an experimental feature // of the listings package (see page 25 of the manual) bool const isInline = params().isInline(); // get the paragraphs. We can not output them directly to given odocstream // because we can not yet determine the delimiter character of \lstinline docstring code; docstring uncodable; ParagraphList::const_iterator par = paragraphs().begin(); ParagraphList::const_iterator end = paragraphs().end(); bool encoding_switched = false; Encoding const * const save_enc = runparams.encoding; if (!runparams.isFullUnicode() && !runparams.encoding->hasFixedWidth()) { // We need to switch to a singlebyte encoding, since the // listings package cannot deal with multi-byte-encoded // glyphs (not needed with full-unicode aware backends // such as XeTeX). Language const * const outer_language = (runparams.local_font != 0) ? runparams.local_font->language() : buffer().params().language; // We try if there's a singlebyte encoding for the current // language; if not, fall back to latin1. Encoding const * const lstenc = (outer_language->encoding()->hasFixedWidth()) ? outer_language->encoding() : encodings.fromLyXName("iso8859-1"); switchEncoding(os.os(), buffer().params(), runparams, *lstenc, true); runparams.encoding = lstenc; encoding_switched = true; } while (par != end) { pos_type siz = par->size(); bool captionline = false; for (pos_type i = 0; i < siz; ++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; char_type c = par->getChar(i); // we can only output characters covered by the current // encoding! try { if (runparams.encoding->encodable(c)) code += c; else if (runparams.dryrun) { code += "<" + _("LyX Warning: ") + _("uncodable character") + " '"; code += docstring(1, c); code += "'>"; } else uncodable += c; } catch (EncodingException & /* e */) { if (runparams.dryrun) { code += "<" + _("LyX Warning: ") + _("uncodable character") + " '"; code += docstring(1, c); code += "'>"; } else uncodable += c; } } ++par; // for the inline case, if there are multiple paragraphs // they are simply joined. Otherwise, expect latex errors. if (par != end && !isInline && !captionline) code += "\n"; } if (isInline) { char const * delimiter = lstinline_delimiters; for (; delimiter != '\0'; ++delimiter) if (!contains(code, *delimiter)) break; // This code piece contains all possible special character? !!! // Replace ! with a warning message and use ! as delimiter. if (*delimiter == '\0') { docstring delim_error = "<" + _("LyX Warning: ") + _("no more lstline delimiters available") + ">"; code = subst(code, from_ascii("!"), delim_error); delimiter = lstinline_delimiters; if (!runparams.dryrun) { // FIXME: warning should be passed to the error dialog frontend::Alert::warning(_("Running out of delimiters"), _("For inline program listings, one character must be reserved\n" "as a delimiter. One of the listings, however, uses all available\n" "characters, so none is left for delimiting purposes.\n" "For the time being, I have replaced '!' by a warning, but you\n" "must investigate!")); } } if (param_string.empty()) os << "\\lstinline" << *delimiter; else os << "\\lstinline[" << from_utf8(param_string) << "]" << *delimiter; os << code << *delimiter; } else { OutputParams rp = runparams; rp.moving_arg = true; docstring const caption = getCaption(rp); if (param_string.empty() && caption.empty()) os << breakln << "\\begin{lstlisting}\n"; else { os << breakln << "\\begin{lstlisting}["; if (!caption.empty()) { os << "caption={" << caption << '}'; if (!param_string.empty()) os << ','; } os << from_utf8(param_string) << "]\n"; } os << code << breakln << "\\end{lstlisting}\n"; } if (encoding_switched){ // Switch back switchEncoding(os.os(), buffer().params(), runparams, *save_enc, true); runparams.encoding = save_enc; } if (!uncodable.empty()) { // issue a warning about omitted characters // FIXME: should be passed to the error dialog frontend::Alert::warning(_("Uncodable characters in listings inset"), bformat(_("The following characters in one of the program listings are\n" "not representable in the current encoding and have been omitted:\n%1$s."), uncodable)); } }
void TeXEnvironment(Buffer const & buf, Text const & text, OutputParams const & runparams, pit_type & pit, otexstream & os) { ParagraphList const & paragraphs = text.paragraphs(); ParagraphList::const_iterator par = paragraphs.constIterator(pit); LYXERR(Debug::LATEX, "TeXEnvironment for paragraph " << pit); Layout const & current_layout = par->layout(); depth_type const current_depth = par->params().depth(); Length const & current_left_indent = par->params().leftIndent(); // This is for debugging purpose at the end. pit_type const par_begin = pit; for (; pit < runparams.par_end; ++pit) { ParagraphList::const_iterator par = paragraphs.constIterator(pit); // check first if this is an higher depth paragraph. bool go_out = (par->params().depth() < current_depth); if (par->params().depth() == current_depth) { // This environment is finished. go_out |= (par->layout() != current_layout); go_out |= (par->params().leftIndent() != current_left_indent); } if (go_out) { // nothing to do here, restore pit and go out. pit--; break; } if (par->layout() == current_layout && par->params().depth() == current_depth && par->params().leftIndent() == current_left_indent) { // We are still in the same environment so TeXOnePar and continue; TeXOnePar(buf, text, pit, os, runparams); continue; } // We are now in a deeper environment. // Either par->layout() != current_layout // Or par->params().depth() > current_depth // Or par->params().leftIndent() != current_left_indent) if (par->layout().isParagraph()) { // FIXME (Lgb): How to handle this? //&& !suffixIs(os, "\n\n") // (ARRae) There should be at least one '\n' already but we need there to // be two for Standard paragraphs that are depth-increment'ed to be // output correctly. However, tables can also be paragraphs so // don't adjust them. // FIXME (Lgb): Will it ever harm to have one '\n' too // many? i.e. that we sometimes will have // three in a row. os << '\n'; } // FIXME This test should not be necessary. // We should perhaps issue an error if it is. bool const force_plain_layout = text.inset().forcePlainLayout(); Layout const & style = force_plain_layout ? buf.params().documentClass().plainLayout() : par->layout(); if (!style.isEnvironment()) { // This is a standard paragraph, no need to call TeXEnvironment. TeXOnePar(buf, text, pit, os, runparams); continue; } // This is a new environment. TeXEnvironmentData const data = prepareEnvironment(buf, text, par, os, runparams); // Recursive call to TeXEnvironment! TeXEnvironment(buf, text, runparams, pit, os); finishEnvironment(os, runparams, data); } if (pit != runparams.par_end) LYXERR(Debug::LATEX, "TeXEnvironment for paragraph " << par_begin << " done."); }