@@ -105,6 +105,10 @@ public class CommentsPreparator extends ASTVisitor {
105105
106106 private final static Pattern MARKDOWN_HEADINGS_PATTERN_2 = Pattern .compile ("(?<!\\ S)[ \\ t]*([=-])\\ 1*[ \\ t]*(?=\\ n|$)" ); //$NON-NLS-1$
107107
108+ private final static Pattern MARKDOWN_CODE_SNIPPET_PATTERN = Pattern .compile ("[ \\ t]*(?:///[ \\ t]*)?```[ \\ t]*(?:\\ R)?" ); //$NON-NLS-1$
109+
110+ private final static Pattern MARKDOWN_TABLE_PATTERN = Pattern .compile ("(?m)(?s)(?:\\ s*///\\ s*)?\\ |[^\\ r\\ n]*?\\ |[ \\ t]*(?:\\ r?\\ n|$)(?:\\ s*///\\ s*)?\\ |(?:\\ s*[:-]+\\ s*\\ |)+[ \\ t]*(?:\\ r?\\ n|$)(?:(?:\\ s*///\\ s*)?\\ |[^\\ r\\ n]*?\\ |[ \\ t]*(?:\\ r?\\ n|$))+" ); //$NON-NLS-1$
111+
108112 // Param tags list copied from IJavaDocTagConstants in legacy formatter for compatibility.
109113 // There were the following comments:
110114 // TODO (frederic) should have another name than 'param' for the following tags
@@ -141,6 +145,8 @@ public class CommentsPreparator extends ASTVisitor {
141145 private DefaultCodeFormatter preTagCodeFormatter ;
142146 private DefaultCodeFormatter snippetCodeFormatter ;
143147
148+ private boolean snippetForMarkdown = false ;
149+
144150 public CommentsPreparator (TokenManager tm , DefaultCodeFormatterOptions options , String sourceLevel ) {
145151 this .tm = tm ;
146152 this .options = options ;
@@ -1377,8 +1383,10 @@ private boolean formatCode(int openingIndex, int closingIndex, boolean snippetTa
13771383 formattedTokens = translateFormattedTokens (codeStartPosition , formattedTokens , positionMapping , null );
13781384
13791385 Token openingToken = this .ctm .get (openingIndex );
1380- for (Token token : formattedTokens )
1386+ for (Token token : formattedTokens ) {
13811387 token .setAlign (token .getAlign () + openingToken .getAlign () + openingToken .getIndent ());
1388+ token .setSnippetForMarkdown (this .snippetForMarkdown );
1389+ }
13821390 fixJavadocTagAlign (openingToken , closingIndex );
13831391
13841392 // there are too few linebreaks at the start and end
@@ -1447,6 +1455,9 @@ private void getCodeToFormat(int startPos, int endPos, StringBuilder sb, int[] p
14471455 } else if (!ScannerHelper .isWhitespace (c )) {
14481456 if (c == '*' )
14491457 lineStart = (this .ctm .charAt (i + 1 ) == ' ' ) ? i + 2 : i + 1 ;
1458+ if (c == '/' && this .snippetForMarkdown )
1459+ lineStart = ((this .ctm .charAt (i + 1 ) == '/' ) && (this .ctm .charAt (i + 2 ) == '/' )) ? i + 4
1460+ : i + 1 ;
14501461 break ;
14511462 }
14521463 }
@@ -1616,6 +1627,7 @@ private void handleMarkdown(TagElement node) {
16161627 previousLevel = currentIndent ;
16171628 tokenPositions .put (currentIndent , listToken );
16181629 }
1630+
16191631 matcher = MARKDOWN_HEADINGS_PATTERN_1 .matcher (text ); // Check for MarkDown headings #h1 - #h6
16201632 while (matcher .find ()) {
16211633 int startPos = matcher .start () + node .getStartPosition ();
@@ -1637,6 +1649,82 @@ private void handleMarkdown(TagElement node) {
16371649 listToken .breakBefore ();
16381650 }
16391651 }
1652+
1653+ matcher = MARKDOWN_CODE_SNIPPET_PATTERN .matcher (text ); // Check for MarkDown snippet with styles '``` & ```'
1654+ while (matcher .find ()) {
1655+ int startPos = matcher .end () + node .getStartPosition ();
1656+ Token openingToken ;
1657+ int tokenIndex = this .ctm .findIndex (startPos , ANY , true );
1658+ if (matcher .find ()) {
1659+ int endPos = matcher .start () + node .getStartPosition ();
1660+ openingToken = this .ctm .get (tokenIndex > 2 ? tokenIndex - 1 : tokenIndex );
1661+ openingToken .breakBefore ();
1662+ openingToken .breakAfter ();
1663+ int tokenIndexLast = this .ctm .findIndex (endPos , ANY , true );
1664+ this .snippetForMarkdown = true ;
1665+ formatCode (tokenIndex - 1 , tokenIndexLast , true );
1666+ this .snippetForMarkdown = false ;
1667+ }
1668+ }
1669+
1670+ matcher = MARKDOWN_TABLE_PATTERN .matcher (text ); // Check for MarkDown tables
1671+ while (matcher .find ()) {
1672+ int startPos = matcher .start () + node .getStartPosition ();
1673+ int tokenIndex = tokenStartingAt (startPos );
1674+ int endPos = matcher .end () + node .getStartPosition ();
1675+ int tokenIndexLast = tokenStartingAt (endPos );
1676+ Token endToken = this .ctm .get (tokenIndexLast );
1677+ this .snippetForMarkdown = false ;
1678+ Token currentToken ;
1679+ boolean firstRow = false ;
1680+ boolean firstRowSecondCol = false ;
1681+ int currentColumnLen = -1 ;
1682+ int alignDistance = 0 ;
1683+ int rowCount = 0 ;
1684+ for (int i = tokenIndex ; i < tokenIndexLast ; i ++) {
1685+ currentToken = this .ctm .get (i );
1686+ if (this .ctm .getSource ().charAt (currentToken .originalStart )=='\n' ) {
1687+ continue ;
1688+ }
1689+ if (this .ctm .toString (currentToken ).equals ("|" )) { //$NON-NLS-1$
1690+ if (currentColumnLen < 0 ) {
1691+ currentToken .spaceAfter ();
1692+ currentToken .spaceBefore ();
1693+ } else {
1694+ if (firstRow ) {
1695+ firstRowSecondCol = true ;
1696+ firstRow = false ;
1697+ } else if (firstRowSecondCol ) {
1698+ Token prev = this .ctm .get (i -1 );
1699+ int previousLen = this .ctm .toString (prev ).length ();
1700+ int previousAlign = prev .getIndent ();
1701+ if (prev .isSpaceBefore ()) {
1702+ previousAlign ++;
1703+ }
1704+ alignDistance += currentColumnLen - previousLen + previousAlign + rowCount +2 ;
1705+ rowCount ++;
1706+ currentToken .setAlign (alignDistance );
1707+ }
1708+ }
1709+ if (this .ctm .getSource ().charAt (currentToken .originalStart +1 ) == '\n' && currentToken != endToken ) {
1710+ currentToken .breakAfter ();
1711+ alignDistance = 0 ;
1712+ firstRowSecondCol = false ;
1713+ firstRow = true ;
1714+ rowCount = 0 ;
1715+ }
1716+ } else if (this .ctm .toString (currentToken ).startsWith ("|--" ) && this .ctm .toString (currentToken ).endsWith ("--|" )) { //$NON-NLS-1$ //$NON-NLS-2$
1717+ String column = this .ctm .toString (currentToken );
1718+ currentColumnLen = column .indexOf ("-|" ) ; //$NON-NLS-1$
1719+ currentToken .breakBefore ();
1720+ currentToken .breakAfter ();
1721+ firstRow = true ;
1722+ }
1723+ }
1724+ }
1725+
1726+
16401727 }
16411728 }
1729+
16421730}
0 commit comments