Exemplo n.º 1
0
void InsetText::latex(otexstream & os, OutputParams const & runparams) const
{
	// This implements the standard way of handling the LaTeX
	// output of a text inset, either a command or an
	// environment. Standard collapsable insets should not
	// redefine this, non-standard ones may call this.
	InsetLayout const & il = getLayout();
	if (!il.latexname().empty()) {
		if (il.latextype() == InsetLayout::COMMAND) {
			// FIXME UNICODE
			if (runparams.moving_arg)
				os << "\\protect";
			os << '\\' << from_utf8(il.latexname());
			if (!il.latexparam().empty())
				os << from_utf8(il.latexparam());
			os << '{';
		} else if (il.latextype() == InsetLayout::ENVIRONMENT) {
			if (il.isDisplay())
			    os << breakln;
			else
			    os << safebreakln;
			if (runparams.lastid != -1)
				os.texrow().start(runparams.lastid,
						  runparams.lastpos);
			os << "\\begin{" << from_utf8(il.latexname()) << "}\n";
			if (!il.latexparam().empty())
				os << from_utf8(il.latexparam());
		}
	}
	OutputParams rp = runparams;
	if (il.isPassThru())
		rp.pass_thru = true;
	if (il.isNeedProtect())
		rp.moving_arg = true;
	rp.par_begin = 0;
	rp.par_end = paragraphs().size();

	// Output the contents of the inset
	latexParagraphs(buffer(), text_, os, rp);
	runparams.encoding = rp.encoding;

	if (!il.latexname().empty()) {
		if (il.latextype() == InsetLayout::COMMAND) {
			os << "}";
		} else if (il.latextype() == InsetLayout::ENVIRONMENT) {
			// A comment environment doesn't need a % before \n\end
			if (il.isDisplay() || runparams.inComment)
			    os << breakln;
			else
			    os << safebreakln;
			os << "\\end{" << from_utf8(il.latexname()) << "}\n";
			if (!il.isDisplay())
				os.protectSpace(true);
		}
	}
}
Exemplo n.º 2
0
void InsetFormulaMacro::latex(otexstream & os,
			      OutputParams const & runparams) const
{
	//lyxerr << "InsetFormulaMacro::latex" << endl;
	WriteStream wi(os.os(), runparams.moving_arg, true,
		       runparams.dryrun ? WriteStream::wsDryrun: WriteStream::wsDefault,
		       runparams.encoding);
	wi.canBreakLine(os.canBreakLine());
	tmpl()->write(wi);
	os.canBreakLine(wi.canBreakLine());
	os.texrow().newlines(wi.line());
}
Exemplo n.º 3
0
void InsetCaption::getArgument(otexstream & os,
			OutputParams const & runparams) const
{
	InsetLayout const & il = getLayout();

	if (!il.leftdelim().empty())
		os << il.leftdelim();

	OutputParams rp = runparams;
	if (isPassThru())
		rp.pass_thru = true;
	if (il.isNeedProtect())
		rp.moving_arg = true;
	if (il.isNeedMBoxProtect())
		++rp.inulemcmd;
	rp.par_begin = 0;
	rp.par_end = paragraphs().size();

	// Output the contents of the inset
	if (!paragraphs().empty())
		os.texrow().forceStart(paragraphs()[0].id(), 0);
	latexParagraphs(buffer(), text(), os, rp);
	runparams.encoding = rp.encoding;

	if (!il.rightdelim().empty())
		os << il.rightdelim();
}
Exemplo n.º 4
0
/// Writes ending block of LaTeX needed to close use of this font
// Returns number of chars written
// This one corresponds to latexWriteStartChanges(). (Asger)
int Font::latexWriteEndChanges(otexstream & os, BufferParams const & bparams,
				  OutputParams const & runparams,
				  Font const & base,
				  Font const & next,
				  bool const & closeLanguage) const
{
	int count = 0;
	bool env = false;

	// reduce the current font to changes against the base
	// font (of the layout). We use a temporary for this to
	// avoid changing this font instance, as that would break
	FontInfo f = bits_;
	f.reduce(base.bits_);

	if (f.family() != INHERIT_FAMILY) {
		os << '}';
		++count;
		env = true; // Size change need not bother about closing env.
	}
	if (f.series() != INHERIT_SERIES) {
		os << '}';
		++count;
		env = true; // Size change need not bother about closing env.
	}
	if (f.shape() != INHERIT_SHAPE) {
		os << '}';
		++count;
		env = true; // Size change need not bother about closing env.
	}
	if (f.color() != Color_inherit && f.color() != Color_ignore) {
		os << '}';
		++count;
		env = true; // Size change need not bother about closing env.
	}
	if (f.emph() == FONT_ON) {
		os << '}';
		++count;
		env = true; // Size change need not bother about closing env.
	}
	if (f.noun() == FONT_ON) {
		os << '}';
		++count;
		env = true; // Size change need not bother about closing env.
	}
	if (f.size() != FONT_SIZE_INHERIT) {
		// We only have to close if only size changed
		if (!env) {
			os << '}';
			++count;
		}
	}
	if (f.underbar() == FONT_ON) {
		os << '}';
		++count;
		runparams.inulemcmd = false;
	}
	if (f.strikeout() == FONT_ON) {
		os << '}';
		++count;
		runparams.inulemcmd = false;
	}
	if (f.uuline() == FONT_ON) {
		os << '}';
		++count;
		runparams.inulemcmd = false;
	}
	if (f.uwave() == FONT_ON) {
		os << '}';
		++count;
		runparams.inulemcmd = false;
	}

	// If the current language is Hebrew, Arabic, or Farsi
	// the numbers are written Left-to-Right. ArabTeX package
	// reorders the number automatically but the packages used
	// for Hebrew and Farsi (Arabi) do not.
	if (bits_.number() == FONT_ON && next.fontInfo().number() != FONT_ON
		&& (language()->lang() == "hebrew"
			|| language()->lang() == "farsi"
			|| language()->lang() == "arabic_arabi")) {
		os << "\\endL}";
		count += 6;
	}

	if (open_encoding_) {
		// We need to close the encoding even if it does not change
		// to do correct environment nesting
		Encoding const * const ascii = encodings.fromLyXName("ascii");
		pair<bool, int> const c = switchEncoding(os.os(), bparams,
				runparams, *ascii);
		LATTEST(c.first);
		count += c.second;
		runparams.encoding = ascii;
		open_encoding_ = false;
	}

	if (closeLanguage
	    && language() != base.language() && language() != next.language()
	    && language()->encoding()->package() != Encoding::CJK) {
		os << '}';
		++count;
	}

	return count;
}
Exemplo n.º 5
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));
	}
}
Exemplo n.º 6
0
void InsetText::latex(otexstream & os, OutputParams const & runparams) const
{
	// This implements the standard way of handling the LaTeX
	// output of a text inset, either a command or an
	// environment. Standard collapsible insets should not
	// redefine this, non-standard ones may call this.
	InsetLayout const & il = getLayout();
	if (il.forceOwnlines())
		os << breakln;
	if (!il.latexname().empty()) {
		if (il.latextype() == InsetLayout::COMMAND) {
			// FIXME UNICODE
			// FIXME \protect should only be used for fragile
			//    commands, but we do not provide this information yet.
			if (hasCProtectContent(runparams.moving_arg))
				os << "\\cprotect";
			else if (runparams.moving_arg)
				os << "\\protect";
			os << '\\' << from_utf8(il.latexname());
			if (!il.latexargs().empty())
				getArgs(os, runparams);
			if (!il.latexparam().empty())
				os << from_utf8(il.latexparam());
			os << '{';
		} else if (il.latextype() == InsetLayout::ENVIRONMENT) {
			if (il.isDisplay())
				os << breakln;
			else
				os << safebreakln;
			if (runparams.lastid != -1)
				os.texrow().start(runparams.lastid,
						  runparams.lastpos);
			os << "\\begin{" << from_utf8(il.latexname()) << "}";
			if (!il.latexargs().empty())
				getArgs(os, runparams);
			if (!il.latexparam().empty())
				os << from_utf8(il.latexparam());
			os << '\n';
		}
	} else {
		if (!il.latexargs().empty())
			getArgs(os, runparams);
		if (!il.latexparam().empty())
			os << from_utf8(il.latexparam());
	}

	if (!il.leftdelim().empty())
		os << il.leftdelim();

	OutputParams rp = runparams;
	if (isPassThru())
		rp.pass_thru = true;
	if (il.isNeedProtect())
		rp.moving_arg = true;
	if (il.isNeedMBoxProtect())
		++rp.inulemcmd;
	if (!il.passThruChars().empty())
		rp.pass_thru_chars += il.passThruChars();
	if (!il.newlineCmd().empty())
		rp.newlinecmd = il.newlineCmd();
	rp.par_begin = 0;
	rp.par_end = paragraphs().size();

	// Output the contents of the inset
	latexParagraphs(buffer(), text_, os, rp);
	runparams.encoding = rp.encoding;
	// Pass the post_macros upstream
	runparams.post_macro = rp.post_macro;

	if (!il.rightdelim().empty())
		os << il.rightdelim();

	if (!il.latexname().empty()) {
		if (il.latextype() == InsetLayout::COMMAND) {
			os << "}";
			if (!il.postcommandargs().empty())
				getArgs(os, runparams, true);
		} else if (il.latextype() == InsetLayout::ENVIRONMENT) {
			// A comment environment doesn't need a % before \n\end
			if (il.isDisplay() || runparams.inComment)
				os << breakln;
			else
				os << safebreakln;
			os << "\\end{" << from_utf8(il.latexname()) << "}" << breakln;
			if (!il.isDisplay())
				os.protectSpace(true);
		}
	}
	if (il.forceOwnlines())
		os << breakln;
}