@@ -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,88 @@ 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+ 					if  (this .ctm .size () - 1  != tokenIndexLast ) {
1665+ 						Token  closingToken  = this .ctm .get (tokenIndexLast );
1666+ 						closingToken .putLineBreaksBefore (2 );
1667+ 						closingToken .putLineBreaksAfter (2 );
1668+ 					}
1669+ 					this .snippetForMarkdown  = true ;
1670+ 					formatCode (tokenIndex  - 1 , tokenIndexLast , true );
1671+ 					this .snippetForMarkdown  = false ;
1672+ 				}
1673+ 			}
1674+ 
1675+ 			matcher  = MARKDOWN_TABLE_PATTERN .matcher (text ); // Check for MarkDown tables 
1676+ 			while  (matcher .find ()) {
1677+ 				int  startPos  = matcher .start () + node .getStartPosition ();
1678+ 				int  tokenIndex  = tokenStartingAt (startPos );
1679+ 				int  endPos  = matcher .end () + node .getStartPosition ();
1680+ 				int  tokenIndexLast  = tokenStartingAt (endPos );
1681+ 				Token  endToken  = this .ctm .get (tokenIndexLast );
1682+ 				this .snippetForMarkdown  = false ;
1683+ 				Token  currentToken ;
1684+ 				boolean  firstRow  = false ;
1685+ 				boolean  firstRowSecondCol  = false ;
1686+ 				int  currentColumnLen  = -1 ;
1687+ 				int  alignDistance  = 0 ;
1688+ 				int  rowCount  = 0 ;
1689+ 				for  (int  i  = tokenIndex ; i  < tokenIndexLast ; i ++) {
1690+ 					currentToken  = this .ctm .get (i );
1691+ 					if  (this .ctm .getSource ().charAt (currentToken .originalStart ) == '\n' ) {
1692+ 						continue ;
1693+ 					}
1694+ 					if  (this .ctm .toString (currentToken ).equals ("|" )) { //$NON-NLS-1$ 
1695+ 						if  (currentColumnLen  < 0 ) {
1696+ 							currentToken .spaceAfter ();
1697+ 							currentToken .spaceBefore ();
1698+ 						} else  {
1699+ 							if  (firstRow ) {
1700+ 								firstRowSecondCol  = true ;
1701+ 								firstRow  = false ;
1702+ 							} else  if  (firstRowSecondCol ) {
1703+ 								Token  prev  = this .ctm .get (i  - 1 );
1704+ 								int  previousLen  = this .ctm .toString (prev ).length ();
1705+ 								int  previousAlign  = prev .getIndent ();
1706+ 								if  (prev .isSpaceBefore ()) {
1707+ 									previousAlign ++;
1708+ 								}
1709+ 								alignDistance  += currentColumnLen  - previousLen  + previousAlign  + rowCount  + 2 ;
1710+ 								rowCount ++;
1711+ 								currentToken .setAlign (alignDistance );
1712+ 							}
1713+ 						}
1714+ 						if  (this .ctm .getSource ().charAt (currentToken .originalStart  + 1 ) == '\n' 
1715+ 								&& currentToken  != endToken ) {
1716+ 							currentToken .breakAfter ();
1717+ 							alignDistance  = 0 ;
1718+ 							firstRowSecondCol  = false ;
1719+ 							firstRow  = true ;
1720+ 							rowCount  = 0 ;
1721+ 						}
1722+ 					} else  if  (this .ctm .toString (currentToken ).startsWith ("|--" ) //$NON-NLS-1$ 
1723+ 							&& this .ctm .toString (currentToken ).endsWith ("--|" )) { //$NON-NLS-1$ 
1724+ 						String  column  = this .ctm .toString (currentToken );
1725+ 						currentColumnLen  = column .indexOf ("-|" ); //$NON-NLS-1$ 
1726+ 						currentToken .breakBefore ();
1727+ 						currentToken .breakAfter ();
1728+ 						firstRow  = true ;
1729+ 					}
1730+ 				}
1731+ 			}
1732+ 
16401733		}
16411734	}
1735+ 
16421736}
0 commit comments