@@ -100,13 +100,9 @@ public class CommentsPreparator extends ASTVisitor {
100100 }
101101
102102 private final static Pattern MARKDOWN_LIST_PATTERN = Pattern .compile ("(?<!\\ S)(?:[-+*]|\\ d+\\ .)([ \\ t]+)" ); //$NON-NLS-1$
103-
104- private final static Pattern MARKDOWN_HEADINGS_PATTERN_1 = Pattern .compile ("(?<!\\ S)(#{1,6})([ \\ t]+)([^#\\ n]+)" ); //$NON-NLS-1$
105-
106- private final static Pattern MARKDOWN_HEADINGS_PATTERN_2 = Pattern .compile ("(?<!\\ S)[ \\ t]*([=-])\\ 1*[ \\ t]*(?=\\ n|$)" ); //$NON-NLS-1$
107-
103+ private final static Pattern MARKDOWN_HEADINGS_PATTERN_1 = Pattern .compile ("(?:(?<=^)|(?<=///[ \\ t]*))(#{1,6})([ \\ t]+)([^#\\ n]+)" , Pattern .MULTILINE ); //$NON-NLS-1$
104+ private final static Pattern MARKDOWN_HEADINGS_PATTERN_2 = Pattern .compile ("(?:^|(?<=///[ \\ t]+))[ \\ t]*([=-])\\ 1*[ \\ t]*(?=\\ n|$)" , Pattern .MULTILINE ); //$NON-NLS-1$
108105 private final static Pattern MARKDOWN_CODE_SNIPPET_PATTERN = Pattern .compile ("[ \\ t]*(?:///[ \\ t]*)?```[ \\ t]*(?:\\ R)?" ); //$NON-NLS-1$
109-
110106 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$
111107
112108 // Param tags list copied from IJavaDocTagConstants in legacy formatter for compatibility.
@@ -144,7 +140,6 @@ public class CommentsPreparator extends ASTVisitor {
144140 private final ArrayList <Integer > commonAttributeAnnotations = new ArrayList <>();
145141 private DefaultCodeFormatter preTagCodeFormatter ;
146142 private DefaultCodeFormatter snippetCodeFormatter ;
147-
148143 private boolean snippetForMarkdown = false ;
149144
150145 public CommentsPreparator (TokenManager tm , DefaultCodeFormatterOptions options , String sourceLevel ) {
@@ -806,8 +801,157 @@ private void alignJavadocTag(List<Token> tagTokens, int paramNameAlign, int desc
806801 }
807802 }
808803
809- private void handleHtml (TagElement node ) {
804+ private void handleMarkdown (TagElement node ) {
805+ if (!(node .getParent () instanceof Javadoc javaDoc )
806+ || !javaDoc .isMarkdown ()
807+ || !this .options .comment_format_markdown_comment ) {
808+ return ;
809+ }
810+ String text = this .tm .toString (node );
811+ Matcher matcher = MARKDOWN_LIST_PATTERN .matcher (text ); // Check for MarkDown lists [Ordered & Unordered])
812+ int previousLevel = 0 ;
813+ Map <Integer , Token > tokenIndents = new HashMap <>();
814+ Token parent = null ;
815+ while (matcher .find ()) {
816+ int startPos = matcher .start () + node .getStartPosition ();
817+ int tokenIndex = tokenStartingAt (startPos );
818+ Token listToken = this .ctm .get (tokenIndex );
819+ int currentIndent = 0 ;
820+ int i = matcher .start ();
821+ while (text .charAt (i ) != '/' ) {
822+ if (text .charAt (i ) == '\t' ) {
823+ currentIndent += 2 ;
824+ } else {
825+ currentIndent ++;
826+ }
827+ i --;
828+ if (i == -1 ) {
829+ break ;
830+ }
831+ }
832+ if (tokenIndex != 1 ) {
833+ listToken .breakBefore ();
834+ }
835+ if (!tokenIndents .isEmpty () && tokenIndents .get (currentIndent ) != null ) {
836+ listToken .setIndent (tokenIndents .get (currentIndent ).getIndent ());
837+ } else if (!tokenIndents .isEmpty () && previousLevel > currentIndent ) {
838+ listToken .spaceBefore ();
839+ } else if (!tokenIndents .isEmpty () && currentIndent > 2 && previousLevel < currentIndent ) {
840+ listToken .setIndent (parent .getIndent () + 2 );
841+ } else if (parent != null && parent .getIndent () > 0 ) {
842+ listToken .setIndent (parent .getIndent ());
843+ } else {
844+ listToken .spaceBefore ();
845+ }
846+ listToken .spaceAfter ();
847+ parent = listToken ;
848+ previousLevel = currentIndent ;
849+ tokenIndents .put (currentIndent , listToken );
850+ }
851+
852+ matcher = MARKDOWN_HEADINGS_PATTERN_1 .matcher (text ); // Check for MarkDown headings #h1 - #h6
853+ while (matcher .find ()) {
854+ int startPos = matcher .start () + node .getStartPosition ();
855+ int tokenIndex = tokenStartingAt (startPos );
856+ Token headingToken = this .ctm .get (tokenIndex );
857+ if (tokenIndex != 1 ) {
858+ headingToken .breakBefore ();
859+ }
860+ headingToken .spaceBefore ();
861+ headingToken .spaceAfter ();
862+ }
863+
864+ matcher = MARKDOWN_HEADINGS_PATTERN_2 .matcher (text ); // Check for MarkDown headings with styles '-- & ==='
865+ while (matcher .find ()) {
866+ int startPos = matcher .start () + node .getStartPosition ();
867+ int tokenIndex = tokenStartingAt (startPos );
868+ Token headingToken = this .ctm .get (tokenIndex );
869+ if (tokenIndex != 1 ) {
870+ headingToken .breakBefore ();
871+ }
872+ headingToken .breakAfter ();
873+ }
874+
875+ matcher = MARKDOWN_CODE_SNIPPET_PATTERN .matcher (text ); // Check for MarkDown snippet with styles '``` & ```'
876+ while (matcher .find ()) {
877+ int startPos = matcher .end () + node .getStartPosition ();
878+ int tokenIndex = this .ctm .findIndex (startPos , ANY , true );
879+ if (matcher .find ()) {
880+ int endPos = matcher .start () + node .getStartPosition ();
881+ Token openingToken = this .ctm .get (tokenIndex > 2 ? tokenIndex - 1 : tokenIndex );
882+ openingToken .breakBefore ();
883+ openingToken .breakAfter ();
884+ int tokenIndexLast = this .ctm .findIndex (endPos , ANY , true );
885+ if (this .ctm .size () - 1 != tokenIndexLast ) {
886+ Token closingToken = this .ctm .get (tokenIndexLast );
887+ closingToken .putLineBreaksAfter (2 );
888+ }
889+ if (this .options .comment_format_source ) {
890+ this .snippetForMarkdown = true ;
891+ formatCode (tokenIndex - 1 , tokenIndexLast , true );
892+ }
893+ }
894+ }
895+
896+ matcher = MARKDOWN_TABLE_PATTERN .matcher (text ); // Check for MarkDown tables
897+ while (matcher .find ()) {
898+ int startPos = matcher .start () + node .getStartPosition ();
899+ int tokenIndex = tokenStartingAt (startPos );
900+ int endPos = matcher .end () + node .getStartPosition ();
901+ int tokenIndexLast = tokenStartingAt (endPos );
902+ Token endToken = this .ctm .get (tokenIndexLast );
903+ this .snippetForMarkdown = false ;
904+ boolean firstRow = false ;
905+ boolean firstRowSecondCol = false ;
906+ int currentColumnLen = -1 ;
907+ int alignDistance = 0 ;
908+ int rowCount = 0 ;
909+ for (int i = tokenIndex ; i < tokenIndexLast ; i ++) {
910+ Token currentToken = this .ctm .get (i );
911+ if (this .ctm .getSource ().charAt (currentToken .originalStart ) == '\n' ) {
912+ continue ;
913+ }
914+ if (this .ctm .toString (currentToken ).equals ("|" )) { //$NON-NLS-1$
915+ if (currentColumnLen < 0 ) {
916+ currentToken .spaceAfter ();
917+ currentToken .spaceBefore ();
918+ } else {
919+ if (firstRow ) {
920+ firstRowSecondCol = true ;
921+ firstRow = false ;
922+ } else if (firstRowSecondCol ) {
923+ Token prev = this .ctm .get (i - 1 );
924+ int previousLen = this .ctm .toString (prev ).length ();
925+ int previousAlign = prev .getIndent ();
926+ if (prev .isSpaceBefore ()) {
927+ previousAlign ++;
928+ }
929+ alignDistance += currentColumnLen - previousLen + previousAlign + rowCount + 2 ;
930+ rowCount ++;
931+ currentToken .setAlign (alignDistance );
932+ }
933+ }
934+ if (this .ctm .getSource ().charAt (currentToken .originalStart + 1 ) == '\n'
935+ && currentToken != endToken ) {
936+ currentToken .breakAfter ();
937+ alignDistance = 0 ;
938+ firstRowSecondCol = false ;
939+ firstRow = true ;
940+ rowCount = 0 ;
941+ }
942+ } else if (this .ctm .toString (currentToken ).startsWith ("|--" ) //$NON-NLS-1$
943+ && this .ctm .toString (currentToken ).endsWith ("--|" )) { //$NON-NLS-1$
944+ String column = this .ctm .toString (currentToken );
945+ currentColumnLen = column .indexOf ("-|" ); //$NON-NLS-1$
946+ currentToken .breakBefore ();
947+ currentToken .breakAfter ();
948+ firstRow = true ;
949+ }
950+ }
951+ }
810952
953+ }
954+ private void handleHtml (TagElement node ) {
811955 if (!this .options .comment_format_html && !this .options .comment_format_source )
812956 return ;
813957 String text = this .tm .toString (node );
@@ -1579,158 +1723,4 @@ public void finishUp() {
15791723 if (this .lastFormatOffComment != null )
15801724 this .tm .addDisableFormatTokenPair (this .lastFormatOffComment , this .tm .get (this .tm .size () - 1 ));
15811725 }
1582-
1583- private void handleMarkdown (TagElement node ) {
1584- if (node .getParent () instanceof Javadoc javaDoc && javaDoc .isMarkdown ()
1585- && this .options .comment_format_markdown_comment ) {
1586- String text = this .tm .toString (node );
1587- Matcher matcher = MARKDOWN_LIST_PATTERN .matcher (text ); // Check for MarkDown lists [Ordered & Unordered]
1588- int previousLevel = 0 ;
1589- Map <Integer , Token > tokenPositions = new HashMap <>();
1590- Token parent = null ;
1591- while (matcher .find ()) {
1592- int startPos = matcher .start () + node .getStartPosition ();
1593- int tokenIndex = tokenStartingAt (startPos );
1594- Token listToken = this .ctm .get (tokenIndex );
1595- int currentIndent = 0 ;
1596- int i = matcher .start ();
1597- while (text .charAt (i ) != '/' ) {
1598- if (text .charAt (i ) == '\t' ) {
1599- currentIndent += 2 ;
1600- } else {
1601- currentIndent ++;
1602- }
1603- i --;
1604- if (i == -1 ) {
1605- break ;
1606- }
1607- }
1608- int currentSize = tokenPositions .size ();
1609- if (tokenIndex != 1 ) {
1610- listToken .breakBefore ();
1611- }
1612- if (currentSize > 0 && tokenPositions .get (currentIndent ) != null ) {
1613- listToken .setIndent (tokenPositions .get (currentIndent ).getIndent ());
1614- } else if (currentSize > 0 && previousLevel > currentIndent ) {
1615- listToken .spaceBefore ();
1616- } else if (currentSize > 0 && currentIndent > 2 && previousLevel < currentIndent ) {
1617- listToken .setIndent (parent .getIndent () + 2 );
1618- } else {
1619- if (parent != null && parent .getIndent () > 0 ) {
1620- listToken .setIndent (parent .getIndent ());
1621- } else {
1622- listToken .spaceBefore ();
1623- }
1624- }
1625- listToken .spaceAfter ();
1626- parent = listToken ;
1627- previousLevel = currentIndent ;
1628- tokenPositions .put (currentIndent , listToken );
1629- }
1630-
1631- matcher = MARKDOWN_HEADINGS_PATTERN_1 .matcher (text ); // Check for MarkDown headings #h1 - #h6
1632- while (matcher .find ()) {
1633- int startPos = matcher .start () + node .getStartPosition ();
1634- int tokenIndex = tokenStartingAt (startPos );
1635- Token listToken = this .ctm .get (tokenIndex );
1636- if (tokenIndex != 1 ) {
1637- listToken .breakBefore ();
1638- }
1639- listToken .spaceBefore ();
1640- listToken .spaceAfter ();
1641- }
1642-
1643- matcher = MARKDOWN_HEADINGS_PATTERN_2 .matcher (text ); // Check for MarkDown headings with styles '-- & ==='
1644- while (matcher .find ()) {
1645- int startPos = matcher .start () + node .getStartPosition ();
1646- int tokenIndex = tokenStartingAt (startPos );
1647- Token listToken = this .ctm .get (tokenIndex );
1648- if (tokenIndex != 1 ) {
1649- listToken .breakBefore ();
1650- }
1651- }
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-
1733- }
1734- }
1735-
17361726}
0 commit comments