Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support figure environment #3

Merged
merged 2 commits into from Feb 12, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/latex-to-ast/environment/common.ts
Expand Up @@ -44,11 +44,12 @@ export const BeginEnvironment = (

export const EndEnvironment = (context: Context): Parsimmon.Parser<null> =>
Parsimmon((input, i) => {
const m = input.slice(i).match(new RegExp(`^\\\\end\\{${context.name}\\}`));
const pattern = context.name.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&');
Copy link
Member

@tani tani Feb 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

現在は.*?が代入されるので問題無いのですが、BeginEnvironmentにも今後同様の可能性があるので、BeginEnvironmentの際にも同様のエスケープをしていただけますか?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

また、好みの問題ですが変数の寿命が短いので変数名はpatternではなくpにしてもらえると嬉しいです。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。対応致します。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 変数名については修正しました。
  • BeginEnvironmentのエスケープについて確認させてください。

以下の部分でBeginEnvironment(".*?", context)という形で使用されているので、同様のエスケープをすると"\\.\\*\\?"となってしまいませんか?

https://github.com/ta2gch/textlint-plugin-latex2e/blob/571e268eaef651dee094920409219156f1d6bf93/src/latex-to-ast/environment/common.ts#L55-L60

また、今回実装したfigureでも?はメタ文字として使用しているため、エスケープは使用する側に任せた方が良いのではないかと思います(引数名もpatternなので、正規表現のパターンが期待されていることは読み取れます)。

https://github.com/kn1cht/textlint-plugin-latex2e/blob/3e0bdbd5a8d20c932b6507412b3348cb6a53a15e/src/latex-to-ast/environment/figure.ts#L33-L35

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

全くもってその通りですね。ご指摘ありがとうございます。見た限りテストも追加されており問題無く完璧なようですので、マージさせてもらいます。

const m = input.slice(i).match(new RegExp(`^\\\\end\\{${pattern}\\}`));
if (m !== null) {
return Parsimmon.makeSuccess(i + m[0].length, null);
} else {
return Parsimmon.makeFailure(i, `\\end{${context.name}}`);
return Parsimmon.makeFailure(i, `\\end{${pattern}}`);
}
});

Expand Down
40 changes: 40 additions & 0 deletions src/latex-to-ast/environment/figure.ts
@@ -0,0 +1,40 @@
/*
* This file is part of textlint-plugin-latex2e
*
* Foobar is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Foobar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/

import Parsimmon from "parsimmon";
import { Rules } from "../rules";
import { BeginEnvironment, EndEnvironment, EnvironmentNode } from "./common";

export const Figure = (r: Rules) => {
const context = { name: "" };
const body = Parsimmon.seqMap(
Parsimmon.index,
Parsimmon.index,
(start, end) => ({
start,
end,
name: "figure"
})
);
return Parsimmon.seqObj<EnvironmentNode>(
["name", BeginEnvironment("figure\\\*?", context)],
["arguments", Parsimmon.alt(r.Option, r.Argument).many()],
Parsimmon.whitespace,
["body", body],
EndEnvironment(context)
).node("environment");
};
1 change: 1 addition & 0 deletions src/latex-to-ast/environment/index.ts
Expand Up @@ -16,6 +16,7 @@
*/
export { DisplayMath } from "./displaymath";
export { Environment } from "./common";
export { Figure } from "./figure";
export { InlineMath } from "./inlinemath";
export { Document } from "./document";
export { List } from "./list";
7 changes: 7 additions & 0 deletions src/latex-to-ast/index.ts
Expand Up @@ -167,6 +167,13 @@ export const parse = (text: string) => {
children: node.value.arguments.concat(node.value.body)
});
break;
case "figure":
this.update({
...tmp,
type: ASTNodeTypes.Image,
children: node.value.arguments.concat(node.value.body)
});
break;
default:
this.update({
...tmp,
Expand Down
2 changes: 2 additions & 0 deletions src/latex-to-ast/latex.ts
Expand Up @@ -19,6 +19,7 @@ import Parsimmon from "parsimmon";
import {
Environment,
DisplayMath,
Figure,
InlineMath,
Document,
List
Expand All @@ -35,6 +36,7 @@ export const LaTeX = Parsimmon.createLanguage({
Document,
List,
DisplayMath,
Figure,
InlineMath,
Command,
Verbatim,
Expand Down
13 changes: 13 additions & 0 deletions test/latex-to-ast.test.ts
Expand Up @@ -76,6 +76,19 @@ describe("Parsimmon AST", async () => {
const ast = LaTeX.Program.tryParse(code);
expect(ast.value[0].value.body.value.length).toBe(2);
});
test("figure environment", async () => {
const code = `\\begin{figure}
\\includegraphics[width=5cm]{somefigure.png}
\\caption{This is a caption}
\\end{figure}
\\begin{figure*}
\\includegraphics[width=5cm]{anotherfigure.png}
\\caption{This is an another caption}
\\end{figure*}`;
const ast = LaTeX.Program.tryParse(code);
expect(ast.value[0].value.name).toBe("figure");
expect(ast.value[2].value.name).toBe("figure*");
});
});

describe("TxtNode AST", async () => {
Expand Down