After all those hours of frustrating coding on tex2lyx, I decided that I would do easy things for a change. As a result, many new insets are supported, among which minipage; see the files text-*.tex for an idea of things that work now

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@7521 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jean-Marc Lasgouttes 2003-08-07 22:59:53 +00:00
parent f5afcca364
commit e5a368b921
4 changed files with 241 additions and 17 deletions

View File

@ -1,3 +1,20 @@
2003-08-08 Jean-Marc Lasgouttes <lasgouttes@lyx.org>
* Makefile.am (EXTRA_DIST):
* test-insets.tex: new file. Describes the insets and special
characters that tex2lyx handles.
* text.C (parse_text): support \vref, \vpageref (only one optional
argument), \prettyref; add support for include inset; when \\ has
optional arguments, use ERT; support also \listoffigures,
\listoftables, and \listof{xxx} for existing float types;
translate lenghts properly for graphics inset.
(parse_environment): add support for minipages
* text.C (translate_len): A simple function to translate a latex
length to something lyx can understand. Not perfect, but rather
best-effort.
2003-08-07 Jean-Marc Lasgouttes <lasgouttes@lyx.org>
* text.C (parse_text): special handling for \item and \bibitem

View File

@ -1,7 +1,7 @@
include $(top_srcdir)/config/common.am
INCLUDES = -I$(srcdir)/../ $(BOOST_INCLUDES)
EXTRA_DIST = test-structure.tex
EXTRA_DIST = test-structure.tex test-insets.tex
#noinst_LTLIBRARIES = libtexparser.la
#

View File

@ -0,0 +1,71 @@
\documentclass{article}
\begin{document}
This document contains all sorts of insets we are supposed to
support.
\section{Things that work}
Let's start with simple things: a label~\label{lab:test} and a
reference~\ref{lab:test}; note that I have tested ``unbreakable
space'' without warning (and worse than that, I just tested english
quotes too...).
Of course there are other kind of references, like page
reference~\pageref{lab:test}, but also equation
reference~\eqref{lab:test} (from amsmath package), or varioref's
equivalents~\vref{lab:test} and~\vpageref{lab:test}, without
forgetting pretty references like~\prettyref{lab:test}.
We can input files too, like this \input{foo}, or with the include
variant \include{foo}
If you prefer verbatim input, you can choose
between~\verbatiminput{foo} or~\verbatiminput*{foo}.
If you like tables of contents, you will be happy to learn that
the following ones are supported:
\tableofcontents
\listoffigures
\listoftables
There is also some basic support for graphics, in the form
\includegraphics{foo.eps}, or the slightly more elaborate
\includegraphics[height=1cm, width=1cm]{foo.eps}.
Lines can have an \hfill in the middle, or be broken by a newline\\
there are even newlines with weird arguments, but these are not
handled by LyX\\*[1cm]
so we try to use ERT in this case.
Then one has those macros with a long name for a short meaning, like
\textasciitilde, \textasciicircum{} or \textbackslash{}, and the characters
that LaTeX wants to espace because they are active, like \_\&\#\$\{\}\%.
And what about special characters like hyphe\-nation mark,
ellipsis\ldots, and end-of-sentence\@. LyX also sports a menu
separator\lyxarrow and a spif\textcompwordmark fy ligature break.
What else? Maybe minipages, like this:
\begin{minipage}{10cm}
Hi there, I am a minipage!
\end{minipage}
There is also an option to align vertically the minipage:
\begin{minipage}[t]{0.3\columnwidth}
Actually, it is also possible to set the height and the inner position
of the minipage, but the LyX GUI does not use or allow to modify this
information. Nevertheless, tex2lyx converts it as faithfully as possible.
\end{minipage}
\section{Things that do not work (yet)}
\vspace*{1cm}
LyX can do vertical spacing, even with the nifty 'keep' option
\bigskip
\end{document}

View File

@ -22,6 +22,7 @@ using std::endl;
using std::map;
using std::ostream;
using std::ostringstream;
using std::istringstream;
using std::string;
using std::vector;
@ -62,7 +63,7 @@ void parse_text_snippet(Parser & p, ostream & os, unsigned flags, bool outer,
namespace {
char const * known_latex_commands[] = { "ref", "cite", "label", "index",
"printindex", "pageref", "url", 0 };
"printindex", "pageref", "url", "vref", "vpageref", "prettyref", "eqref", 0 };
// LaTeX names for quotes
char const * known_quotes[] = { "glqq", "grqq", "quotedblbase",
@ -93,7 +94,41 @@ map<string, string> split_map(string const & s)
return res;
}
// A simple function to translate a latex length to something lyx can
// understand. Not perfect, but rather best-effort.
string translate_len(string const & len)
{
const string::size_type i = len.find_first_not_of(" -01234567890.");
// a normal length
if (i == string::npos || len[i] != '\\')
return len;
istringstream iss(string(len, 0, i));
double val;
iss >> val;
val = val*100;
ostringstream oss;
oss << val;
string const valstring = oss.str();
const string::size_type i2 = len.find(" ", i);
string const unit = string(len, i, i2 - i);
string const endlen = (i2 == string::npos) ? string() : string(len, i2);
if (unit == "\\textwidth")
return valstring + "text%" + endlen;
else if (unit == "\\columnwidth")
return valstring + "col%" + endlen;
else if (unit == "\\paperwidth")
return valstring + "page%" + endlen;
else if (unit == "\\linewidth")
return valstring + "line%" + endlen;
else if (unit == "\\paperheight")
return valstring + "pheight%" + endlen;
else if (unit == "\\textheight")
return valstring + "theight%" + endlen;
else
return len;
}
void begin_inset(ostream & os, string const & name)
{
os << "\n\\begin_inset " << name;
@ -196,12 +231,16 @@ void parse_environment(Parser & p, ostream & os, bool outer,
parse_math(p, os, FLAG_END, MATH_MODE);
os << "\\end{" << name << "}";
end_inset(os);
} else if (name == "tabular") {
}
else if (name == "tabular") {
parent_context.check_layout(os);
begin_inset(os, "Tabular ");
handle_tabular(p, os, parent_context);
end_inset(os);
} else if (parent_context.textclass.floats().typeExist(unstarred_name)) {
}
else if (parent_context.textclass.floats().typeExist(unstarred_name)) {
parent_context.check_layout(os);
begin_inset(os, "Float " + unstarred_name + "\n");
if (p.next_token().asInput() == "[") {
@ -210,11 +249,58 @@ void parse_environment(Parser & p, ostream & os, bool outer,
os << "wide " << tostr(is_starred)
<< "\ncollapsed false\n";
parse_text_in_inset(p, os, FLAG_END, outer, parent_context);
end_inset(os);
} else if (name == "center") {
end_inset(os);
}
else if (name == "minipage") {
parent_context.check_layout(os);
begin_inset(os, "Minipage\n");
string position = "1";
string inner_pos = "0";
string height;
if (p.next_token().asInput() == "[") {
switch(p.getArg('[', ']')[0]) {
case 't': position = "0"; break;
case 'c': position = "1"; break;
case 'b': position = "2"; break;
default:
cerr << "invalid position for minipage"
<< endl;
break;
}
if (p.next_token().asInput() == "[") {
height = translate_len(p.getArg('[', ']'));
if (p.next_token().asInput() == "[") {
switch(p.getArg('[', ']')[0]) {
case 't': inner_pos = "0"; break;
case 'c': inner_pos = "1"; break;
case 'b': inner_pos = "2"; break;
case 's': inner_pos = "3"; break;
default:
cerr << "invalid inner_pos for minipage"
<< endl;
break;
}
}
}
}
os << "position " << position << '\n';
os << "inner_position " << inner_pos << '\n';
os << "height \"" << height << "\"\n";
os << "width \"" << translate_len(p.verbatim_item()) << "\"\n";
os << "collapsed false\n";
parse_text_in_inset(p, os, FLAG_END, outer, parent_context);
end_inset(os);
}
else if (name == "center") {
parse_text(p, os, FLAG_END, outer, parent_context);
// The single '=' is meant here.
} else if ((newlayout = findLayout(parent_context.textclass, name)).get() &&
}
else if ((newlayout = findLayout(parent_context.textclass, name)).get() &&
newlayout->isEnvironment()) {
Context context(true, parent_context.textclass, newlayout,
parent_context.layout);
@ -234,7 +320,9 @@ void parse_environment(Parser & p, ostream & os, bool outer,
parse_text(p, os, FLAG_END, outer, context);
context.check_end_layout(os);
context.check_end_deeper(os);
} else {
}
else {
parent_context.check_layout(os);
handle_ert(os, "\\begin{" + name + "}", parent_context);
parse_text_snippet(p, os, FLAG_END, outer, parent_context);
@ -492,9 +580,11 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
begin_inset(os, "Graphics ");
os << "\n\tfilename " << name << '\n';
if (opts.find("width") != opts.end())
os << "\twidth " << opts["width"] << '\n';
os << "\twidth "
<< translate_len(opts["width"]) << '\n';
if (opts.find("height") != opts.end())
os << "\theight " << opts["height"] << '\n';
os << "\theight "
<< translate_len(opts["height"]) << '\n';
end_inset(os);
}
@ -536,12 +626,36 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
else if (t.cs() == "tableofcontents") {
context.check_layout(os);
begin_inset(os, "LatexCommand ");
os << '\\' << t.cs() << "{}\n";
begin_inset(os, "LatexCommand \\tableofcontents\n");
end_inset(os);
skip_braces(p); // swallow this
}
else if (t.cs() == "listoffigures") {
context.check_layout(os);
begin_inset(os, "FloatList figure\n");
end_inset(os);
skip_braces(p); // swallow this
}
else if (t.cs() == "listoftables") {
context.check_layout(os);
begin_inset(os, "FloatList table\n");
end_inset(os);
skip_braces(p); // swallow this
}
else if (t.cs() == "listof") {
string const name = p.get_token().asString();
if (context.textclass.floats().typeExist(name)) {
context.check_layout(os);
begin_inset(os, "FloatList ");
os << name << "\n";
end_inset(os);
p.get_token(); // swallow second arg
} else
handle_ert(os, "\\listof{" + name + "}", context);
}
else if (t.cs() == "textrm") {
context.check_layout(os);
@ -654,6 +768,12 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
skip_braces(p);
}
else if (t.cs() == "textcompwordmark") {
context.check_layout(os);
os << "\\SpecialChar \\textcompwordmark{}\n";
skip_braces(p);
}
else if (t.cs() == "@" && p.next_token().asInput() == ".") {
context.check_layout(os);
os << "\\SpecialChar \\@.\n";
@ -737,14 +857,30 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
}
else if (t.cs() == "\\") {
context.check_layout(os);
os << "\n\\newline \n";
string const next = p.next_token().asInput();
if (next == "[")
handle_ert(os, "\\\\" + p.getOpt(), context);
else if (next == "*") {
p.get_token();
handle_ert(os, "\\\\*" + p.getOpt(), context);
}
else {
context.check_layout(os);
os << "\n\\newline \n";
}
}
else if (t.cs() == "input") {
else if (t.cs() == "input" || t.cs() == "include"
|| t.cs() == "verbatiminput") {
string name = '\\' + t.cs();
if (t.cs() == "verbatiminput"
&& p.next_token().asInput() == "*")
name += p.get_token().asInput();
context.check_layout(os);
handle_ert(os, "\\input{" + p.verbatim_item() + "}\n",
context);
begin_inset(os, "Include ");
os << name << '{' << p.getArg('{', '}') << "}\n";
os << "preview false\n";
end_inset(os);
}
else if (t.cs() == "fancyhead") {
context.check_layout(os);