From 9801a7a04e44ed6c78f9f0eb0b3ecccdfc52526b Mon Sep 17 00:00:00 2001 From: Florin Iucha Date: Mon, 6 Apr 2020 00:00:58 -0400 Subject: [PATCH] Preserve the indentation of external code --- .../antlr/net/signbit/samx/parser/SamX.g4 | 23 +++++++++++++++---- .../signbit/samx/PrettyPrinterVisitor.java | 9 ++++++-- src/main/java/net/signbit/samx/Tokenize.java | 3 +++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/main/antlr/net/signbit/samx/parser/SamX.g4 b/src/main/antlr/net/signbit/samx/parser/SamX.g4 index 5d8c58d..8929ae4 100644 --- a/src/main/antlr/net/signbit/samx/parser/SamX.g4 +++ b/src/main/antlr/net/signbit/samx/parser/SamX.g4 @@ -20,7 +20,7 @@ grammar SamX; package net.signbit.samx.parser; } -tokens { INDENT, DEDENT, END, INVALID } +tokens { INDENT, DEDENT, END, INVALID, CODE_INDENT } @lexer::members { @@ -31,6 +31,9 @@ tokens { INDENT, DEDENT, END, INVALID } private boolean prepareProcessingCode = false; private boolean processingCode = false; + private int thisIndent = 0; + private int codeIndentBase = 0; + private Token lastToken; @Override @@ -125,6 +128,15 @@ tokens { INDENT, DEDENT, END, INVALID } } } + private void addCodeIndent() + { + CommonToken codeIndent = makeToken(SamXParser.CODE_INDENT, java.lang.Integer.toString(thisIndent - codeIndentBase)); + codeIndent.setLine(_tokenStartLine); + codeIndent.setCharPositionInLine(_tokenStartCharPositionInLine); + + tokens.add(codeIndent); + } + } SKIP_ @@ -145,7 +157,7 @@ NEWLINE ) { final char[] tokenText = getText().toCharArray(); - int thisIndent = 0; + thisIndent = 0; for (char ch: tokenText) { if (ch == ' ') @@ -186,6 +198,7 @@ NEWLINE { processingCode = true; prepareProcessingCode = false; + codeIndentBase = thisIndent; } } @@ -265,10 +278,12 @@ flow : ( text | phrase | localInsert | url | inlineCode )+ ; paragraph : ( flow NEWLINE )+ NEWLINE ; recordRow : ( COLSEP flow )+ NEWLINE ; -EXTCODE : (~'\n')+ { processingCode }?; +EXTCODE : (~'\n')+ { processingCode }? { addCodeIndent(); }; CODE_MARKER : '```(' { prepareProcessingCode = true; }; +externalCode : CODE_INDENT EXTCODE ; + block : NAME TYPESEP attribute* description=flow? NEWLINE+ INDENT block+ DEDENT # TypedBlock | NAME TYPESEP attribute* value=flow NEWLINE # Field @@ -280,7 +295,7 @@ block : | '"""[' text ']' NEWLINE ( INDENT block+ DEDENT ) # CitationBlock | '>>>(' text ')' attribute* # InsertFragment | '<<<(' text ')' attribute* # IncludeFile - | CODE_MARKER language=text ')' attribute* NEWLINE+ INDENT (EXTCODE? NEWLINE)+ DEDENT # CodeBlock + | CODE_MARKER language=text ')' attribute* NEWLINE+ INDENT (externalCode? NEWLINE)+ DEDENT # CodeBlock | NEWLINE # Empty ; diff --git a/src/main/java/net/signbit/samx/PrettyPrinterVisitor.java b/src/main/java/net/signbit/samx/PrettyPrinterVisitor.java index e5c08d8..70eeee7 100644 --- a/src/main/java/net/signbit/samx/PrettyPrinterVisitor.java +++ b/src/main/java/net/signbit/samx/PrettyPrinterVisitor.java @@ -362,10 +362,15 @@ public StringBuilder visitCodeBlock(SamXParser.CodeBlockContext ctx) builder.append('\n'); indentLevel ++; - for (TerminalNode tn: ctx.EXTCODE()) + for (SamXParser.ExternalCodeContext ecc: ctx.externalCode()) { addIndent(builder); - builder.append(tn.getText()); + int codeIndent = Integer.valueOf(ecc.CODE_INDENT().getText()); + for (int ii = 0; ii < codeIndent; ++ii) + { + builder.append(' '); + } + builder.append(ecc.EXTCODE().getText()); builder.append('\n'); } indentLevel --; diff --git a/src/main/java/net/signbit/samx/Tokenize.java b/src/main/java/net/signbit/samx/Tokenize.java index efc5bbb..883cc61 100644 --- a/src/main/java/net/signbit/samx/Tokenize.java +++ b/src/main/java/net/signbit/samx/Tokenize.java @@ -67,6 +67,9 @@ public static void main(String[] args) case SamXParser.INVALID: tokenSymbol = "INVALID"; break; + case SamXParser.CODE_INDENT: + tokenSymbol = "CODE_IDT"; + break; default: tokenSymbol = "¯\\_(ツ)_/¯"; break;