diff --git a/resources/bnf/Latex.bnf b/resources/bnf/Latex.bnf index a4ec69a..bbc22c4 100644 --- a/resources/bnf/Latex.bnf +++ b/resources/bnf/Latex.bnf @@ -22,16 +22,16 @@ COMMA = "," COLON = ":" ASTERISK = "*" - SLASH = '\' LINE_BREAK = '\\' + IDENTIFIER_END = '\end' + IDENTIFIER_BEGIN = '\begin' + IDENTIFIER = "regexp:\\\p{Alpha}+" - INSTRUCTION = "regexp:\\[a-zA-Z]+" - IDENTIFIER = "regexp:[a-zA-Z]+" - ARGUMENT = "regexp:\b[\p{L}\w ]+\b|\\\W" + ARGUMENT = "regexp:\b([^\]\}\),\\])+\b" COMMENT = "regexp:%.*" - SPECIAL = "regexp:[\S]" + SPECIAL = "regexp:[\S]|\\." CRLF = "regexp:[\s\r\n]+" ] @@ -42,33 +42,28 @@ latexFile ::= item_ * -private item_ ::= !<> expr * - -private expr ::= text_expr - | group_expr + - | argument_expr - | instruction_expr - | special_expr +private item_ ::= !<> expr * { pin = 1 } +private expr ::= section + | instruction | TEXT + | SPECIAL | CRLF -private expr_inside ::= argument_expr - | group_expr + - | instruction_expr - | special_expr -private instruction_ ::= INSTRUCTION_BEGIN - | INSTRUCTION_END - | INSTRUCTION + | LINE_BREAK + +section ::= instruction_begin expr * instruction_end { pin = 1 } +instruction ::= IDENTIFIER ASTERISK ? argument_group * { pin = 1 } +instruction_begin ::= IDENTIFIER_BEGIN expr_list_brace +instruction_end ::= IDENTIFIER_END expr_list_brace +argument_group ::= expr_list_bracket | expr_list_brace | expr_list_paren + +private argument_expr ::= ( special_expr * ( ARGUMENT | instruction ) special_expr * ) * { pin(".*") = 2 } -INSTRUCTION_BEGIN ::= "\\begin" -INSTRUCTION_END ::= "\\end" +TEXT ::= ( ARGUMENT special_expr ? ) + -private argument_expr ::= (ARGUMENT | IDENTIFIER) (special_expr + ( ARGUMENT | IDENTIFIER | instruction_expr | CRLF ) ) * { pin(".*") = 1 } -private group_expr ::= expr_list_bracket | expr_list_brace | expr_list_paren -instruction_expr ::= instruction_ ASTERISK ? group_expr * private text_expr ::= ( special_expr * ARGUMENT special_expr * CRLF * ) + -private special_expr ::= SPECIAL | COLON | COMMA | LINE_BREAK +private special_expr ::= SPECIAL | COLON | COMMA | LINE_BREAK | CRLF -private meta expr_list_bracket ::= LBRACKET <> ? RBRACKET { pin(".*") = 1 } -private meta expr_list_brace ::= LBRACE <> ? RBRACE { pin(".*") = 1 } -private meta expr_list_paren ::= LPAREN <> ? RPAREN { pin(".*") = 1 } -private meta sequence ::= <

> + (<> <

>) * { pin(".*") = 1 } +private meta expr_list_bracket ::= LBRACKET <> ? RBRACKET { pin(".*") = 1 } +private meta expr_list_brace ::= LBRACE <> ? RBRACE { pin(".*") = 1 } +private meta expr_list_paren ::= LPAREN <> ? RPAREN { pin(".*") = 1 } +private meta sequence ::= <

> (<> <

>) * { pin(".*") = 1 } diff --git a/src/mobi/hsz/idea/latex/lang/LatexFoldingBuilder.java b/src/mobi/hsz/idea/latex/lang/LatexFoldingBuilder.java index 9027e91..39078cf 100644 --- a/src/mobi/hsz/idea/latex/lang/LatexFoldingBuilder.java +++ b/src/mobi/hsz/idea/latex/lang/LatexFoldingBuilder.java @@ -28,7 +28,6 @@ import com.intellij.lang.folding.FoldingBuilderEx; import com.intellij.lang.folding.FoldingDescriptor; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.search.PsiElementProcessor; import com.intellij.psi.tree.IElementType; @@ -59,20 +58,13 @@ public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull D final List result = ContainerUtil.newArrayList(); - final List begins = ContainerUtil.newArrayList(); - if (!quick) { PsiTreeUtil.processElements(file, new PsiElementProcessor() { @Override public boolean execute(@NotNull PsiElement element) { IElementType type = element.getNode().getElementType(); - if (type.equals(LatexTypes.INSTRUCTION_BEGIN)) { - begins.add(element); - } else if (type.equals(LatexTypes.INSTRUCTION_END)) { - PsiElement last = begins.get(begins.size() - 1); - TextRange range = new TextRange(last.getTextRange().getStartOffset(), element.getTextRange().getEndOffset()); - result.add(new FoldingDescriptor(last, range)); - begins.remove(last); + if (type.equals(LatexTypes.SECTION)) { + result.add(new FoldingDescriptor(element.getNode(), element.getNode().getTextRange())); } return true; } @@ -85,7 +77,7 @@ public boolean execute(@NotNull PsiElement element) { @Nullable @Override public String getPlaceholderText(@NotNull ASTNode node) { - return node.getTreeParent().getText() + LatexBundle.message("folding.placeholder"); + return node.getFirstChildNode().getText() + LatexBundle.message("folding.placeholder"); } @Override diff --git a/src/mobi/hsz/idea/latex/lang/LatexParserDefinition.java b/src/mobi/hsz/idea/latex/lang/LatexParserDefinition.java index 40ce71a..7d1915b 100644 --- a/src/mobi/hsz/idea/latex/lang/LatexParserDefinition.java +++ b/src/mobi/hsz/idea/latex/lang/LatexParserDefinition.java @@ -57,7 +57,7 @@ public class LatexParserDefinition implements ParserDefinition { /** Latex instruction started with \ */ public static final TokenSet INSTRUCTIONS = TokenSet.create( - LatexTypes.INSTRUCTION, LatexTypes.INSTRUCTION_BEGIN, LatexTypes.INSTRUCTION_END + LatexTypes.IDENTIFIER, LatexTypes.IDENTIFIER_BEGIN, LatexTypes.IDENTIFIER_END ); /** Latex instruction's argument */ diff --git a/src/mobi/hsz/idea/latex/lexer/Latex.flex b/src/mobi/hsz/idea/latex/lexer/Latex.flex index 0e90552..0d51d37 100644 --- a/src/mobi/hsz/idea/latex/lexer/Latex.flex +++ b/src/mobi/hsz/idea/latex/lexer/Latex.flex @@ -27,7 +27,7 @@ EOL = "\r"|"\n"|"\r\n" LINE_WS = [\ \t\f] WHITE_SPACE = ({LINE_WS}|{EOL})+ -INSTRUCTION = \\[a-zA-Z]+ +IDENTIFIER = \\[a-zA-Z]+ COMMENT = %.* ARGUMENT = [^\(\)\{\}\[\]\\,] TEXT = [^\(\)\{\}\[\]\\\%\ \t\f\r\n]|"\\\%"|("\\"{SPECIAL}) @@ -59,8 +59,8 @@ SPECIAL = "$"|"&"|"#"|"_"|"~"|"^"|"\\" {WHITE_SPACE}+ { return WHITE_SPACE; } - "\\begin" { return INSTRUCTION_BEGIN; } - "\\end" { return INSTRUCTION_END; } - {INSTRUCTION} { return INSTRUCTION; } + "\\begin" { return IDENTIFIER_BEGIN; } + "\\end" { return IDENTIFIER_END; } + {IDENTIFIER} { return IDENTIFIER; } {COMMENT} { return COMMENT; } - {TEXT}+ { return TEXT; } + {TEXT}+ { return ARGUMENT; } diff --git a/src/mobi/hsz/idea/latex/lexer/LatexLexer.java b/src/mobi/hsz/idea/latex/lexer/LatexLexer.java index ccd1f14..3d7be32 100644 --- a/src/mobi/hsz/idea/latex/lexer/LatexLexer.java +++ b/src/mobi/hsz/idea/latex/lexer/LatexLexer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.4.3 on 23.01.15 14:38 */ +/* The following code was generated by JFlex 1.4.3 on 27.01.15 17:17 */ package mobi.hsz.idea.latex.lexer; @@ -14,7 +14,7 @@ /** * This class is a scanner generated by * JFlex 1.4.3 - * on 23.01.15 14:38 from the specification file + * on 27.01.15 17:17 from the specification file * /home/hsz/Projects/idea-latex/src/mobi/hsz/idea/latex/lexer/Latex.flex */ public class LatexLexer implements FlexLexer { @@ -57,9 +57,9 @@ public class LatexLexer implements FlexLexer { private static final String ZZ_ACTION_PACKED_0 = "\2\0\1\1\1\2\1\3\1\4\1\5\1\3\1\6"+ - "\1\7\1\10\1\11\1\12\1\13\1\14\1\15\1\16"+ - "\1\17\1\0\1\3\1\20\3\3\4\21\1\22\1\21"+ - "\1\23"; + "\1\7\1\10\1\11\1\12\1\13\1\14\1\1\1\15"+ + "\1\16\1\0\1\3\1\17\3\3\4\20\1\21\1\20"+ + "\1\22"; private static int [] zzUnpackAction() { int [] result = new int[31]; @@ -474,41 +474,45 @@ else if (zzAtEOF) { case 8: { yybegin(IN_ARGUMENT); return LBRACKET; } - case 20: break; - case 15: + case 19: break; + case 14: { return COMMA; } - case 21: break; + case 20: break; case 3: { return SPECIAL; } - case 22: break; + case 21: break; case 4: { return COMMENT; } - case 23: break; + case 22: break; case 16: + { return IDENTIFIER; + } + case 23: break; + case 15: { return LINE_BREAK; } case 24: break; - case 13: + case 1: { return ARGUMENT; } case 25: break; + case 17: + { return IDENTIFIER_END; + } + case 26: break; case 11: { return COLON; } - case 26: break; + case 27: break; case 10: { yybegin(IN_ARGUMENT); return LBRACE; } - case 27: break; - case 14: - { yypushback(1); yybegin(YYINITIAL); - } case 28: break; - case 18: - { return INSTRUCTION_END; + case 13: + { yypushback(1); yybegin(YYINITIAL); } case 29: break; case 2: @@ -523,30 +527,22 @@ else if (zzAtEOF) { { return RBRACE; } case 32: break; - case 12: - { return ASTERISK; + case 18: + { return IDENTIFIER_BEGIN; } case 33: break; - case 1: - { return TEXT; + case 12: + { return ASTERISK; } case 34: break; - case 19: - { return INSTRUCTION_BEGIN; - } - case 35: break; case 6: { yybegin(IN_ARGUMENT); return LPAREN; } - case 36: break; - case 17: - { return INSTRUCTION; - } - case 37: break; + case 35: break; case 9: { return RBRACKET; } - case 38: break; + case 36: break; default: if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { zzAtEOF = true;