예제 #1
0
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;
}
예제 #2
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;
}
예제 #3
0
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;
}
예제 #4
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;
}
예제 #5
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);
			}
		}
	}
}
예제 #6
0
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;
}
예제 #7
0
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);
		}
	}
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
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;
	}
}
예제 #11
0
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;
}
예제 #12
0
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));
	}
}
예제 #13
0
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.");
}