public class CodeFragments
extends java.lang.Object
Fragments can be defined in .java, .md and build.gradle files,
by surrounding them with these comments:
// start_code_fragment: my.fragment.id
hello world
// end_code_fragment:
Here, my.fragment.id is the fragment key. It can be any Java identifier including dots.
When reading the fragment, each line is stripped of indentation to the level the
start_code_fragment line was on.
This means the above fragment's content will be hello world\n, with \n being a newline symbol.
You can also define fragments manually using addFragment(String, String).
Fragment insertion happens in .java and .md files, using special HTML comments:
<!-- insert_code_fragment: my.fragment.id -->
<!-- end_code_fragment: -->
The inserted code fragment will use the same indentation as the insertion tag line, plus 4 extra spaces.
The characters * (asterisk) and > (greater than) also count as indentation.
This allows you to insert code fragments into JavaDoc or Markdown blockquotes:
/*
* <!-- insert_code_fragment: my.fragment.id -->
* <!-- end_code_fragment: -->
* /
> <!-- insert_code_fragment: my.fragment.id -->
> <!-- end_code_fragment: -->
After processing, the above examples will look like this:
<!-- insert_code_fragment: my.fragment.id -->
hello world
<!-- end_code_fragment: -->
/*
* <!-- insert_code_fragment: my.fragment.id -->
* hello world
* <!-- end_code_fragment: -->
* /
> <!-- insert_code_fragment: my.fragment.id -->
> hello world
> <!-- end_code_fragment: -->
To update all code fragments in the current project, put this line into a main() program or test and run it:
FulibTools.codeFragments().update(".");
You can limit the process to certain files and directories.
This can avoid unwanted file changes and is generally faster.
FulibTools.codeFragments().update("README.md", "docs/", "src/test/java/");
There may be situations in which you don't want the inserted code fragment to be formatted in exactly the same way
as the original input.
For example, you may want to wrap Java code in <pre> </pre> tags before including it in a JavaDoc comment,
or you want to format code in a markdown document.
You can achieve this with Pipes.
Just put a pipe symbol (|) and the name of the pipe you want to apply behind the fragment name:
<!-- insert_code_fragment: my.fragment.id | fenced -->
<!-- end_code_fragment: -->
The output will look like this:
<!-- insert_code_fragment: my.fragment.id | fenced -->
```
hello world
```
<!-- end_code_fragment: -->
A pipe may have an optional argument that follows the pipe name with a colon (:) in between.
E.g.:
<!-- insert_code_fragment: my.fragment.id | fenced:java -->
<!-- end_code_fragment: -->
The output will look like this:
<!-- insert_code_fragment: my.fragment.id | fenced:java -->
```java
hello world
```
<!-- end_code_fragment: -->
How the argument is interpreted depends on the pipe.
In this example, we used the CodeFencePipe, which uses the argument as the language tag.
The following pipes are predefined:
| Name | Class |
|---|---|
| indent | IndentPipe |
| javadoc | JavaDocPipe |
| fenced | CodeFencePipe |
| html | HtmlPipe |
You can create your own pipes by implementing the Pipe interface.
Then, register them with the CodeFragments instance using the addPipe(String, Pipe) method.
Pipe is a functional interface, which allows you to implement it with a
lambda expression, e.g. addPipe("foo", (content, arg) -> content + "foo" + arg);.
With the removePipe(String) method, you can disable predefined or custom pipes.
| Constructor and Description |
|---|
CodeFragments() |
| Modifier and Type | Method and Description |
|---|---|
void |
addFragment(java.lang.String key,
java.lang.String content)
Allows specifying fragments that can be inserted but don't have to be present in source files.
|
void |
addPipe(java.lang.String name,
Pipe pipe)
Adds or replaces a pipe with the given name.
|
java.lang.String |
getFragment(java.lang.String key) |
java.util.LinkedHashMap<java.lang.String,java.lang.String> |
getFragmentMap()
Deprecated.
since 1.2; use
getFragments() instead |
java.util.Map<java.lang.String,java.lang.String> |
getFragments() |
Pipe |
getPipe(java.lang.String name) |
void |
load(java.lang.String... folders)
Loads code fragments from all files within the given folders.
|
void |
removePipe(java.lang.String name)
Removes the pipe with the given name if one exists, otherwise does nothing.
|
void |
update(java.lang.String... folders)
Runs
load(String...) and write(String...) in succession. |
java.util.Map<java.lang.String,java.lang.String> |
updateCodeFragments(java.lang.String... folders)
Deprecated.
since 1.2; use
update(String...) and getFragments() instead |
void |
write(java.lang.String... folders)
Inserts code fragments into all files within the given folders.
|
@Deprecated public java.util.LinkedHashMap<java.lang.String,java.lang.String> getFragmentMap()
getFragments() insteadpublic java.util.Map<java.lang.String,java.lang.String> getFragments()
public java.lang.String getFragment(java.lang.String key)
key - the fragment keykey, or null if not foundpublic void addFragment(java.lang.String key,
java.lang.String content)
Example:
Example.java:
final CodeFragments fragments = new CodeFragments();
// start_code_fragment: exampleCode
final String foo = "bar" + 42 + "baz";
// end_code_fragment:
fragments.add("exampleOutput", foo);
fragments.updateCodeFragments(".");
README.md, before:
Use the following code:
<!-- insert_code_fragment: exampleCode -->
<!-- end_code_fragment: -->
to get the output:
<!-- insert_code_fragment: exampleOutput -->
<!-- end_code_fragment: -->
README.md, after:
Use the following code:
<!-- insert_code_fragment: exampleCode -->
final String foo = "bar" + 42 + "baz";
<!-- end_code_fragment: -->
to get the output:
<!-- insert_code_fragment: exampleOutput -->
bar42baz
<!-- end_code_fragment: -->
key - the fragment keycontent - the fragment contentpublic Pipe getPipe(java.lang.String name)
name - the name of the pipenull if none is foundpublic void addPipe(java.lang.String name,
Pipe pipe)
name - the name of the pipepipe - the pipe implementationpublic void removePipe(java.lang.String name)
name - the name of the pipe to removepublic void load(java.lang.String... folders)
folders - the folders to search for fragmentspublic void write(java.lang.String... folders)
folders - the folders to search for fragment insertion pointspublic void update(java.lang.String... folders)
load(String...) and write(String...) in succession.folders - the folders to search for fragments and fragment insertion points@Deprecated public java.util.Map<java.lang.String,java.lang.String> updateCodeFragments(java.lang.String... folders)
update(String...) and getFragments() insteadupdate(String...) and then returns the map of fragments.folders - the folders to search for fragments and fragment insertion points