3030import java .util .Map ;
3131import java .util .Objects ;
3232
33+ /**
34+ * Processes the {@code .md} files in a directory expanding code blocks following a custom directive
35+ * (expressed as MyST comment):
36+ * <pre>
37+ * % :::{include-code} src={{doc-tests-src}}/path/to/SomeCode.java tag=some-marker
38+ * ```java
39+ * this is replaced by the section of SomeCode.java delimited
40+ * with `tag::some-marker` and `end::some-marker`
41+ * ```
42+ * </pre>
43+ *
44+ * Note: the MyST format has the {@code {literalinclude}} directive, which is currently only partially supported
45+ * by docs-builder (the whole file is included, ignoring {@code start-after} and {@code end-before} parameters).
46+ * <p>
47+ * See <a href="https://mystmd.org/guide/code#docs-literalinclude">MyST docs</a>
48+ */
3349public class IncludeExpander {
3450
3551 public static void main (String [] args ) throws IOException {
3652
37-
3853 File dir = new File (args .length == 0 ? "docs/reference" : args [0 ]);
3954
4055 if (!dir .isDirectory ()) {
4156 throw new IllegalArgumentException (dir .getAbsolutePath () + " is not a directory" );
4257 }
4358
59+ // FIXME: we should read this from `docset.yml` in the `dir` directory.
4460 processDirectory (dir , Map .of ("doc-tests-src" , "java-client/src/test/java/co/elastic/clients/documentation" ));
4561 }
4662
@@ -79,8 +95,8 @@ public static void processFile(File file, Map<String, String> subst) throws IOEx
7995
8096 enum State {
8197 NORMAL_TEXT ,
82- INCLUDE_CODE ,
83- CODE_BLOCK ,
98+ INCLUDE_CODE_DIRECTIVE ,
99+ REPLACED_CODE_BLOCK ,
84100 }
85101
86102 public static void fail (String message , String path , LineNumberReader reader , Throwable e ) {
@@ -107,28 +123,28 @@ public static String expandText(String input, Map<String, String> subst, String
107123 if (line .startsWith ("% :::{include-code}" )) {
108124 output .append (line ).append ("\n " );
109125 includeCodeLine = line ;
110- state = State .INCLUDE_CODE ;
126+ state = State .INCLUDE_CODE_DIRECTIVE ;
111127
112128 } else {
113129 // Regular text line
114130 output .append (line ).append ("\n " );
115131 }
116132 }
117133
118- case INCLUDE_CODE -> {
134+ case INCLUDE_CODE_DIRECTIVE -> {
119135 if (!line .startsWith ("```" )) {
120136 fail ("The '% :::{include-code}' should be followed by a code block" , path , reader , null );
121137 }
122138 output .append (line ).append ("\n " );
123- state = State .CODE_BLOCK ;
139+ state = State .REPLACED_CODE_BLOCK ;
124140 try {
125141 expandIncludeCodeDirective (includeCodeLine , subst , output );
126142 } catch (Exception e ) {
127143 fail ("Failed to expand include directive" , path , reader , e );
128144 }
129145 }
130146
131- case CODE_BLOCK -> {
147+ case REPLACED_CODE_BLOCK -> {
132148 // Skip existing code until we reach the end
133149 if (line .startsWith ("```" )) {
134150 output .append (line ).append ("\n " );
@@ -156,7 +172,7 @@ public static void expandIncludeCodeDirective(String command, Map<String, String
156172 var src = Objects .requireNonNull (args .get ("src" ), "Missing 'src' attribute" );
157173 var tag = Objects .requireNonNull (args .get ("tag" ), "Missing 'tag' attribute" );
158174
159- // Brute force replacement of placeholders
175+ // Brute force replacement of placeholders. We can do better.
160176 for (var kv : subst .entrySet ()) {
161177 src = src .replace ("{{" + kv .getKey () + "}}" , kv .getValue ());
162178 }
0 commit comments