use of com.vladsch.flexmark.ast.Node in project flexmark-java by vsch.
the class TextNodeConverter method mergeTextNodes.
// insert and clear list
public static void mergeTextNodes(Node parent) {
Node prevNode = null;
Node child = parent.getFirstChild();
while (child != null) {
Node nextChild = child.getNext();
if (prevNode instanceof Text && child instanceof Text && prevNode.getChars().isContinuedBy(child.getChars())) {
// merge them
child.setChars(prevNode.getChars().spliceAtEnd(child.getChars()));
prevNode.unlink();
}
prevNode = child;
child = nextChild;
}
}
use of com.vladsch.flexmark.ast.Node in project flexmark-java by vsch.
the class TextNodeMergingList method insertMergedBefore.
// insert and clear list
public void insertMergedBefore(Node sibling) {
mergeList();
for (Node node : list) {
sibling.insertBefore(node);
}
clear();
}
use of com.vladsch.flexmark.ast.Node in project flexmark-java by vsch.
the class TextNodeMergingList method mergeList.
private void mergeList() {
if (!isMerged) {
// go through and see if some can be combined
ArrayList<Node> mergedList = null;
Node lastText = null;
for (Node child : list) {
if (child instanceof Text) {
if (!child.getChars().isEmpty()) {
if (lastText == null) {
lastText = child;
} else if (lastText.getChars().isContinuedBy(child.getChars())) {
// merge their text
lastText.setChars(lastText.getChars().spliceAtEnd(child.getChars()));
} else {
if (mergedList == null)
mergedList = new ArrayList<Node>();
mergedList.add(lastText);
lastText = child;
}
}
} else {
if (mergedList == null)
mergedList = new ArrayList<Node>();
if (lastText != null) {
mergedList.add(lastText);
lastText = null;
}
mergedList.add(child);
}
}
if (lastText != null) {
if (mergedList == null) {
list.clear();
list.add(lastText);
} else {
mergedList.add(lastText);
}
}
if (mergedList != null) {
list = mergedList;
}
}
}
use of com.vladsch.flexmark.ast.Node in project flexmark-java by vsch.
the class PostProcessorManager method postProcess.
public Document postProcess(Document document) {
// first initialize node tracker if
ClassifyingNodeTracker classifyingNodeTracker;
classifyingNodeTracker = null;
for (PostProcessorDependencyStage stage : postProcessorDependencies.getDependentStages()) {
// idiosyncrasy of post processors the last dependency can be global, in which case it processes the whole document and no ancestry info is
// provided
// new ClassifyingNodeTracker()
boolean hadGlobal = false;
for (PostProcessorFactory dependent : stage.dependents) {
if (dependent.affectsGlobalScope()) {
document = dependent.create(document).processDocument(document);
hadGlobal = true;
// assume it no longer reflects reality;
classifyingNodeTracker = null;
} else {
if (hadGlobal) {
int tmp = 0;
}
assert !hadGlobal;
if (classifyingNodeTracker == null) {
// build the node type information by traversing the document tree
classifyingNodeTracker = new NodeClassifierVisitor(stage.myNodeMap).classify(document);
}
Map<Class<?>, Set<Class<?>>> dependentNodeTypes = dependent.getNodeTypes();
PostProcessor postProcessor = dependent.create(document);
BitSet exclusionSet = new BitSet();
for (Set<Class<?>> excluded : dependentNodeTypes.values()) {
BitSet mapped = classifyingNodeTracker.getExclusionSet().indexBitSet(excluded);
exclusionSet.or(mapped);
}
ReversibleIterable<Node> nodes = classifyingNodeTracker.getCategoryItems(Node.class, dependentNodeTypes.keySet());
for (Node node : nodes) {
// was already removed
if (node.getParent() == null)
continue;
// now we need to get the bitset for the excluded ancestors of the node, then intersect it with the actual ancestors of this factory
int index;
BitSet nodeAncestors;
BitSet nodeExclusions;
Set<Class<?>> excluded = dependentNodeTypes.get(node.getClass());
if (excluded != null) {
index = classifyingNodeTracker.getItems().indexOf(node);
if (index != -1) {
nodeAncestors = classifyingNodeTracker.getNodeAncestryMap().get(index);
if (nodeAncestors != null) {
nodeExclusions = classifyingNodeTracker.getExclusionSet().indexBitSet(excluded);
nodeExclusions.and(nodeAncestors);
if (!nodeExclusions.isEmpty()) {
// has excluded ancestor
continue;
}
}
}
}
postProcessor.process(classifyingNodeTracker, node);
}
}
}
}
return document;
}
use of com.vladsch.flexmark.ast.Node in project flexmark-java by vsch.
the class HtmlRendererTest method attributeProviderForCodeBlock.
@Test
public void attributeProviderForCodeBlock() {
AttributeProviderFactory factory = new IndependentAttributeProviderFactory() {
@Override
public AttributeProvider create(LinkResolverContext context) {
// noinspection ReturnOfInnerClass
return new AttributeProvider() {
@Override
public void setAttributes(Node node, AttributablePart part, Attributes attributes) {
if (node instanceof FencedCodeBlock && part == CoreNodeRenderer.CODE_CONTENT) {
FencedCodeBlock fencedCodeBlock = (FencedCodeBlock) node;
// Remove the default attribute for info
attributes.remove("class");
// Put info in custom attribute instead
attributes.replaceValue("data-custom", fencedCodeBlock.getInfo().toString());
}
}
};
}
};
HtmlRenderer renderer = HtmlRenderer.builder().attributeProviderFactory(factory).build();
String rendered = renderer.render(parse("```info\ncontent\n```"));
assertEquals("<pre><code data-custom=\"info\">content\n</code></pre>\n", rendered);
String rendered2 = renderer.render(parse("```evil\"\ncontent\n```"));
assertEquals("<pre><code data-custom=\"evil"\">content\n</code></pre>\n", rendered2);
}
Aggregations