mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-09-19 22:40:26 +00:00
Improve tex2lyx roundtrip of test-insets.tex:
- Replace special verbatim commands by standard LaTeX, since it would be extremely difficult to make tex2lyx understand them) - Comment duplicated \bibliography{xampl}, since LaTeX cannot handle two \bibliography calls - Fix a regression with spaces after commands, introduced in r36943 - Parse \multicolumn with space/comments between two arguments correctly - Parse optional arguments correctly if there are space or comments between the command and the argument - Remove duplicate "LyX" phrase handling (I overlooked that in r37052) - Add new commands created with \let to the list of known commands. This is needed to parse the arguments correctly git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@37064 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
a3a7c046be
commit
812c27d793
@ -629,7 +629,16 @@ $$
|
|||||||
\textcircled{translate}
|
\textcircled{translate}
|
||||||
\textcolor[]{,,}{translate}
|
\textcolor[]{,,}{translate}
|
||||||
%\textcolor{}{}
|
%\textcolor{}{}
|
||||||
\textnormal{translate}
|
\textbf{translate} % hardcoded, but needed nevertheless for \let\xyz\textbf
|
||||||
|
\textnormal{translate} % hardcoded, but needed nevertheless for \let\xyz\textnormal
|
||||||
|
\textmd{translate} % hardcoded, but needed nevertheless for \let\xyz\textmd
|
||||||
|
\textit{translate} % hardcoded, but needed nevertheless for \let\xyz\textit
|
||||||
|
\textrm{translate} % hardcoded, but needed nevertheless for \let\xyz\textrm
|
||||||
|
\textsc{translate} % hardcoded, but needed nevertheless for \let\xyz\textsc
|
||||||
|
\textsf{translate} % hardcoded, but needed nevertheless for \let\xyz\textsf
|
||||||
|
\textsl{translate} % hardcoded, but needed nevertheless for \let\xyz\textsl
|
||||||
|
\texttt{translate} % hardcoded, but needed nevertheless for \let\xyz\texttt
|
||||||
|
\textup{translate} % hardcoded, but needed nevertheless for \let\xyz\textup
|
||||||
\textfraction
|
\textfraction
|
||||||
\thanks{translate}
|
\thanks{translate}
|
||||||
\thicklines
|
\thicklines
|
||||||
|
@ -293,6 +293,38 @@ char Parser::getChar()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Parser::hasOpt()
|
||||||
|
{
|
||||||
|
// An optional argument can occur in any of the following forms:
|
||||||
|
// - \foo[bar]
|
||||||
|
// - \foo [bar]
|
||||||
|
// - \foo
|
||||||
|
// [bar]
|
||||||
|
// - \foo %comment
|
||||||
|
// [bar]
|
||||||
|
|
||||||
|
// remember current position
|
||||||
|
unsigned int oldpos = pos_;
|
||||||
|
// skip spaces and comments
|
||||||
|
while (good()) {
|
||||||
|
get_token();
|
||||||
|
if (isParagraph()) {
|
||||||
|
putback();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (curr_token().cat() == catSpace ||
|
||||||
|
curr_token().cat() == catNewline ||
|
||||||
|
curr_token().cat() == catComment)
|
||||||
|
continue;
|
||||||
|
putback();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bool const retval = (next_token().asInput() == "[");
|
||||||
|
pos_ = oldpos;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Parser::Arg Parser::getFullArg(char left, char right)
|
Parser::Arg Parser::getFullArg(char left, char right)
|
||||||
{
|
{
|
||||||
skip_spaces(true);
|
skip_spaces(true);
|
||||||
|
@ -131,6 +131,8 @@ public:
|
|||||||
/// dump contents to screen
|
/// dump contents to screen
|
||||||
void dump() const;
|
void dump() const;
|
||||||
|
|
||||||
|
/// Does an optional argument follow after the current token?
|
||||||
|
bool hasOpt();
|
||||||
///
|
///
|
||||||
typedef std::pair<bool, std::string> Arg;
|
typedef std::pair<bool, std::string> Arg;
|
||||||
/*!
|
/*!
|
||||||
|
@ -968,6 +968,7 @@ void handle_tabular(Parser & p, ostream & os, bool is_long_tabular,
|
|||||||
// special cell properties alignment
|
// special cell properties alignment
|
||||||
vector<ColInfo> t;
|
vector<ColInfo> t;
|
||||||
handle_colalign(p, t, ColInfo());
|
handle_colalign(p, t, ColInfo());
|
||||||
|
p.skip_spaces(true);
|
||||||
ColInfo & ci = t.front();
|
ColInfo & ci = t.front();
|
||||||
|
|
||||||
// The logic of LyX for multicolumn vertical
|
// The logic of LyX for multicolumn vertical
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
\newcommand{\lyxarrow}{\leavevmode\,$\triangleright$\,\allowbreak}
|
\newcommand{\lyxarrow}{\leavevmode\,$\triangleright$\,\allowbreak}
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands.
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands.
|
||||||
\usepackage{doc}
|
|
||||||
\usepackage{subscript} % user specified as long as tex2lyx
|
\usepackage{subscript} % user specified as long as tex2lyx
|
||||||
% produces a format less than 408
|
% produces a format less than 408
|
||||||
|
|
||||||
@ -94,7 +93,8 @@ Now the natbib things:
|
|||||||
\textbackslash{}nocite: \nocite{article-crossref}
|
\textbackslash{}nocite: \nocite{article-crossref}
|
||||||
|
|
||||||
\bibliographystyle{unsrt}
|
\bibliographystyle{unsrt}
|
||||||
\bibliography{xampl}
|
% Remove duplicate call of \bibliography since LaTeX throws an error.
|
||||||
|
% \bibliography{xampl}
|
||||||
|
|
||||||
With \textbackslash{}nocite\{{*}\}:
|
With \textbackslash{}nocite\{{*}\}:
|
||||||
\bibliographystyle{unsrt}
|
\bibliographystyle{unsrt}
|
||||||
@ -129,12 +129,13 @@ There is also some basic support for graphics, in the form
|
|||||||
\section{Tables\index{Tables}}
|
\section{Tables\index{Tables}}
|
||||||
|
|
||||||
The following example is stolen from the longtable documentation.
|
The following example is stolen from the longtable documentation.
|
||||||
|
Since tex2lyx does not understand the special verbatim code that
|
||||||
|
was used in the original some lines have been rewritten using
|
||||||
|
\textbackslash textbackslash etc.
|
||||||
\let\package\textsf
|
\let\package\textsf
|
||||||
\let\env\textsf
|
\let\env\textsf
|
||||||
|
\let\code\texttt
|
||||||
\providecommand\finalclearpage{\clearpage}
|
\providecommand\finalclearpage{\clearpage}
|
||||||
\DeleteShortVerb{\|}
|
|
||||||
\MakeShortVerb{\"}
|
|
||||||
\def\v{\char`}
|
|
||||||
|
|
||||||
\begin{longtable}{@{*}r||p{1in}@{*}}
|
\begin{longtable}{@{*}r||p{1in}@{*}}
|
||||||
KILLED & LINE!!!! \kill
|
KILLED & LINE!!!! \kill
|
||||||
@ -166,28 +167,28 @@ at the end& of the table\\
|
|||||||
\endlastfoot
|
\endlastfoot
|
||||||
\env{longtable} columns are specified& in the \\
|
\env{longtable} columns are specified& in the \\
|
||||||
same way as in the \env{tabular}& environment.\\
|
same way as in the \env{tabular}& environment.\\
|
||||||
"@{*}r||p{1in}@{*}"& in this case.\\
|
%\code{@\{*\}r||p\{1in\}@\{*\}}& in this case.\\
|
||||||
Each row ends with a& "\\" command.\\
|
Each row ends with a& \code{\textbackslash\textbackslash} command.\\
|
||||||
The "\\" command has an& optional\\
|
The \code{\textbackslash\textbackslash} command has an& optional\\
|
||||||
argument, just as in& the\\
|
argument, just as in& the\\
|
||||||
\env{tabular}&environment.\\[10pt]
|
\env{tabular}&environment.\\[10pt]
|
||||||
See the effect of "\\[10pt]"&?\\
|
See the effect of \code{\textbackslash\textbackslash[10pt]}&?\\
|
||||||
Lots of lines& like this.\\
|
Lots of lines& like this.\\
|
||||||
Lots of lines& like this.\\
|
Lots of lines& like this.\\
|
||||||
Lots of lines& like this.\\
|
Lots of lines& like this.\\
|
||||||
Lots of lines& like this.\\
|
Lots of lines& like this.\\
|
||||||
Also "\hline" may be used,& as in \env{tabular}.\\
|
Also \code{\textbackslash hline} may be used,& as in \env{tabular}.\\
|
||||||
\hline
|
\hline
|
||||||
That was a "\hline"&.\\
|
That was a \code{\textbackslash hline}&.\\
|
||||||
\hline\hline
|
\hline\hline
|
||||||
That was "\hline\hline"&.\\
|
That was \code{\textbackslash hline\textbackslash hline}&.\\
|
||||||
\multicolumn{2}{||c||}%
|
\multicolumn{2}{||c||}%
|
||||||
{This is a \ttfamily\v\\multicolumn\v{2\v}\v{||c||\v}}\\
|
{This is a \code{\textbackslash multicolumn\{2\}\{||c||\}}}\\
|
||||||
If a page break occurs at a "\hline" then& a line is drawn\\
|
If a page break occurs at a \code{\textbackslash hline} then& a line is drawn\\
|
||||||
at the bottom of one page and at the& top of the next.\\
|
at the bottom of one page and at the& top of the next.\\
|
||||||
\hline
|
\hline
|
||||||
The "[t] [b] [c]" argument of \env{tabular}& can not be used.\\
|
The \code{[t] [b] [c]} argument of \env{tabular}& can not be used.\\
|
||||||
The optional argument may be one of& "[l] [r] [c]"\\
|
The optional argument may be one of& \code{[l] [r] [c]}\\
|
||||||
to specify whether the table should be& adjusted\\
|
to specify whether the table should be& adjusted\\
|
||||||
to the left, right& or centrally.\\
|
to the left, right& or centrally.\\
|
||||||
\hline\hline
|
\hline\hline
|
||||||
@ -215,7 +216,7 @@ Some lines may take up a lot of space, like this: &
|
|||||||
\raggedleft This last column is a ``p'' column so this
|
\raggedleft This last column is a ``p'' column so this
|
||||||
``row'' of the table can take up several lines. Note however that
|
``row'' of the table can take up several lines. Note however that
|
||||||
\TeX\ will never break a page within such a row. Page breaks only
|
\TeX\ will never break a page within such a row. Page breaks only
|
||||||
occur between rows of the table or at "\hline" commands.
|
occur between rows of the table or at \code{\textbackslash hline} commands.
|
||||||
\tabularnewline
|
\tabularnewline
|
||||||
Lots of lines& like this.\\
|
Lots of lines& like this.\\
|
||||||
Lots of lines& like this.\\
|
Lots of lines& like this.\\
|
||||||
@ -268,9 +269,13 @@ test
|
|||||||
\subsection{Line breaks}
|
\subsection{Line breaks}
|
||||||
|
|
||||||
They can also or be broken by a newline\\
|
They can also or be broken by a newline\\
|
||||||
or a newline command \newline
|
or by a starred newline \\*
|
||||||
|
or by a newline with space, comment and argument \\ %hu
|
||||||
|
[3cm]
|
||||||
|
or by a newline command \newline
|
||||||
or by a line break \linebreak
|
or by a line break \linebreak
|
||||||
or by a defined line break \linebreak[4]
|
or by a defined line break \linebreak % again with a comment
|
||||||
|
[4]
|
||||||
|
|
||||||
There are even newlines with weird arguments, but these are not
|
There are even newlines with weird arguments, but these are not
|
||||||
handled by LyX\\*[1cm]
|
handled by LyX\\*[1cm]
|
||||||
@ -280,7 +285,8 @@ so we try to use ERT in this case.
|
|||||||
|
|
||||||
They can also or be broken by a newpage \newpage
|
They can also or be broken by a newpage \newpage
|
||||||
or by a page break \pagebreak
|
or by a page break \pagebreak
|
||||||
or by a defined page break \pagebreak[4]
|
or by a defined page break \pagebreak % again with a comment
|
||||||
|
[4]
|
||||||
|
|
||||||
\section{Special characters\index{Special characters}}
|
\section{Special characters\index{Special characters}}
|
||||||
|
|
||||||
|
@ -455,7 +455,7 @@ void eat_whitespace(Parser &, ostream &, Context &, bool);
|
|||||||
* This should be called after a command has been parsed that is not put into
|
* This should be called after a command has been parsed that is not put into
|
||||||
* ERT, and where LyX adds "{}" if needed.
|
* ERT, and where LyX adds "{}" if needed.
|
||||||
*/
|
*/
|
||||||
void skip_spaces_braces(Parser & p)
|
void skip_spaces_braces(Parser & p, bool keepws = false)
|
||||||
{
|
{
|
||||||
/* The following four examples produce the same typeset output and
|
/* The following four examples produce the same typeset output and
|
||||||
should be handled by this function:
|
should be handled by this function:
|
||||||
@ -471,7 +471,7 @@ void skip_spaces_braces(Parser & p)
|
|||||||
// results in different output in some cases.
|
// results in different output in some cases.
|
||||||
bool const skipped_spaces = p.skip_spaces(true);
|
bool const skipped_spaces = p.skip_spaces(true);
|
||||||
bool const skipped_braces = skip_braces(p);
|
bool const skipped_braces = skip_braces(p);
|
||||||
if (skipped_spaces && !skipped_braces)
|
if (keepws && skipped_spaces && !skipped_braces)
|
||||||
// put back the space (it is better handled by check_space)
|
// put back the space (it is better handled by check_space)
|
||||||
p.unskip_spaces(true);
|
p.unskip_spaces(true);
|
||||||
}
|
}
|
||||||
@ -643,17 +643,17 @@ void parse_box(Parser & p, ostream & os, unsigned flags, bool outer,
|
|||||||
string height_unit = "in";
|
string height_unit = "in";
|
||||||
string height_special = "totalheight";
|
string height_special = "totalheight";
|
||||||
string latex_height;
|
string latex_height;
|
||||||
if (p.next_token().asInput() == "[") {
|
if (p.hasOpt()) {
|
||||||
position = p.getArg('[', ']');
|
position = p.getArg('[', ']');
|
||||||
if (position != "t" && position != "c" && position != "b") {
|
if (position != "t" && position != "c" && position != "b") {
|
||||||
position = "c";
|
position = "c";
|
||||||
cerr << "invalid position for minipage/parbox" << endl;
|
cerr << "invalid position for minipage/parbox" << endl;
|
||||||
}
|
}
|
||||||
if (p.next_token().asInput() == "[") {
|
if (p.hasOpt()) {
|
||||||
latex_height = p.getArg('[', ']');
|
latex_height = p.getArg('[', ']');
|
||||||
translate_box_len(latex_height, height_value, height_unit, height_special);
|
translate_box_len(latex_height, height_value, height_unit, height_special);
|
||||||
|
|
||||||
if (p.next_token().asInput() == "[") {
|
if (p.hasOpt()) {
|
||||||
inner_pos = p.getArg('[', ']');
|
inner_pos = p.getArg('[', ']');
|
||||||
if (inner_pos != "c" && inner_pos != "t" &&
|
if (inner_pos != "c" && inner_pos != "t" &&
|
||||||
inner_pos != "b" && inner_pos != "s") {
|
inner_pos != "b" && inner_pos != "s") {
|
||||||
@ -794,9 +794,8 @@ void parse_environment(Parser & p, ostream & os, bool outer,
|
|||||||
eat_whitespace(p, os, parent_context, false);
|
eat_whitespace(p, os, parent_context, false);
|
||||||
parent_context.check_layout(os);
|
parent_context.check_layout(os);
|
||||||
begin_inset(os, "Float " + unstarred_name + "\n");
|
begin_inset(os, "Float " + unstarred_name + "\n");
|
||||||
if (p.next_token().asInput() == "[") {
|
if (p.hasOpt())
|
||||||
os << "placement " << p.getArg('[', ']') << '\n';
|
os << "placement " << p.getArg('[', ']') << '\n';
|
||||||
}
|
|
||||||
os << "wide " << convert<string>(is_starred)
|
os << "wide " << convert<string>(is_starred)
|
||||||
<< "\nsideways false"
|
<< "\nsideways false"
|
||||||
<< "\nstatus open\n\n";
|
<< "\nstatus open\n\n";
|
||||||
@ -2464,19 +2463,6 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
|||||||
p.setEncoding(enc);
|
p.setEncoding(enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (t.cs() == "LyX" || t.cs() == "TeX"
|
|
||||||
|| t.cs() == "LaTeX") {
|
|
||||||
context.check_layout(os);
|
|
||||||
os << t.cs();
|
|
||||||
skip_spaces_braces(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (t.cs() == "LaTeXe") {
|
|
||||||
context.check_layout(os);
|
|
||||||
os << "LaTeX2e";
|
|
||||||
skip_spaces_braces(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (t.cs() == "ldots") {
|
else if (t.cs() == "ldots") {
|
||||||
context.check_layout(os);
|
context.check_layout(os);
|
||||||
os << "\\SpecialChar \\ldots{}\n";
|
os << "\\SpecialChar \\ldots{}\n";
|
||||||
@ -2603,11 +2589,13 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
|||||||
|
|
||||||
else if (t.cs() == "\\") {
|
else if (t.cs() == "\\") {
|
||||||
context.check_layout(os);
|
context.check_layout(os);
|
||||||
string const next = p.next_token().asInput();
|
if (p.hasOpt())
|
||||||
if (next == "[")
|
|
||||||
handle_ert(os, "\\\\" + p.getOpt(), context);
|
handle_ert(os, "\\\\" + p.getOpt(), context);
|
||||||
else if (next == "*") {
|
else if (p.next_token().asInput() == "*") {
|
||||||
p.get_token();
|
p.get_token();
|
||||||
|
// getOpt() eats the following space if there
|
||||||
|
// is no optional argument, but that is OK
|
||||||
|
// here since it has no effect in the output.
|
||||||
handle_ert(os, "\\\\*" + p.getOpt(), context);
|
handle_ert(os, "\\\\*" + p.getOpt(), context);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -2617,8 +2605,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (t.cs() == "newline" ||
|
else if (t.cs() == "newline" ||
|
||||||
(t.cs() == "linebreak" &&
|
(t.cs() == "linebreak" && !p.hasOpt())) {
|
||||||
p.next_token().asInput() != "[")) {
|
|
||||||
context.check_layout(os);
|
context.check_layout(os);
|
||||||
begin_inset(os, "Newline ");
|
begin_inset(os, "Newline ");
|
||||||
os << t.cs();
|
os << t.cs();
|
||||||
@ -2804,8 +2791,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (t.cs() == "newpage" ||
|
else if (t.cs() == "newpage" ||
|
||||||
(t.cs() == "pagebreak" &&
|
(t.cs() == "pagebreak" && !p.hasOpt()) ||
|
||||||
p.next_token().asInput() != "[") ||
|
|
||||||
t.cs() == "clearpage" ||
|
t.cs() == "clearpage" ||
|
||||||
t.cs() == "cleardoublepage") {
|
t.cs() == "cleardoublepage") {
|
||||||
context.check_layout(os);
|
context.check_layout(os);
|
||||||
@ -2843,7 +2829,38 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
|||||||
end_inset(os);
|
end_inset(os);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (t.cs() == "let" && p.next_token().asInput() != "*") {
|
||||||
|
// let could be handled by parse_command(),
|
||||||
|
// but we need to call add_known_command() here.
|
||||||
|
string ert = t.asInput();
|
||||||
|
string name;
|
||||||
|
p.skip_spaces();
|
||||||
|
if (p.next_token().cat() == catBegin) {
|
||||||
|
name = p.verbatim_item();
|
||||||
|
ert += '{' + name + '}';
|
||||||
|
} else {
|
||||||
|
name = p.verbatim_item();
|
||||||
|
ert += name;
|
||||||
|
}
|
||||||
|
string command;
|
||||||
|
p.skip_spaces();
|
||||||
|
if (p.next_token().cat() == catBegin) {
|
||||||
|
command = p.verbatim_item();
|
||||||
|
ert += '{' + command + '}';
|
||||||
|
} else {
|
||||||
|
command = p.verbatim_item();
|
||||||
|
ert += command;
|
||||||
|
}
|
||||||
|
// If command is known, make name known too, to parse
|
||||||
|
// its arguments correctly. For this reason we also
|
||||||
|
// have commands in syntax.default that are hardcoded.
|
||||||
|
CommandMap::iterator it = known_commands.find(command);
|
||||||
|
if (it != known_commands.end())
|
||||||
|
known_commands[t.asInput()] = it->second;
|
||||||
|
handle_ert(os, ert, context);
|
||||||
|
}
|
||||||
|
|
||||||
else if (t.cs() == "hspace" || t.cs() == "vspace") {
|
else if (t.cs() == "hspace" || t.cs() == "vspace") {
|
||||||
bool starred = false;
|
bool starred = false;
|
||||||
if (p.next_token().asInput() == "*") {
|
if (p.next_token().asInput() == "*") {
|
||||||
|
Loading…
Reference in New Issue
Block a user