class JekyllTagNodeFormatter implements PhasedNodeFormatter {
    private boolean embedIncludedContent;

    public JekyllTagNodeFormatter(DataHolder options) {
    }

    @Override
    public @Nullable Set<FormattingPhase> getFormattingPhases() {
        return Collections.singleton(FormattingPhase.COLLECT);
    }

    @Override
    public void renderDocument(@NotNull NodeFormatterContext context, @NotNull MarkdownWriter markdown, @NotNull Document document, @NotNull FormattingPhase phase) {
        this.embedIncludedContent = JekyllTagExtension.EMBED_INCLUDED_CONTENT.get(document);
    }

    @Nullable
    @Override
    public Set<Class<?>> getNodeClasses() {
        return null;
    }

    @Nullable
    @Override
    public Set<NodeFormattingHandler<?>> getNodeFormattingHandlers() {
        return new HashSet<>(Arrays.asList(
                new NodeFormattingHandler<>(JekyllTagBlock.class, JekyllTagNodeFormatter.this::render),
                new NodeFormattingHandler<>(JekyllTag.class, JekyllTagNodeFormatter.this::render)
        ));
    }

    private void render(JekyllTagBlock node, NodeFormatterContext context, MarkdownWriter markdown) {<FILL_FUNCTION_BODY>}

    private void render(JekyllTag node, NodeFormatterContext context, MarkdownWriter markdown) {
        if (embedIncludedContent) {
            // remove jekyll tag node and just leave the included content
            context.renderChildren(node);
        } else {
            if (!(node.getParent() instanceof JekyllTagBlock)) {
                Node prev = node.getPrevious();
                if (prev != null) {
                    BasedSequence chars = prev.getChars();
                    markdown.pushOptions().preserveSpaces()
                            .append(chars.baseSubSequence(chars.getEndOffset(), node.getStartOffset()))
                            .popOptions();
                } else {
                    int startLine = node.getBaseSequence().startOfLine(node.getStartOffset());
                    if (startLine < node.getStartOffset()) {
                        BasedSequence chars = node.baseSubSequence(startLine, node.getStartOffset());
                        markdown.pushOptions().preserveSpaces()
                                .append(chars)
                                .popOptions();
                    }
                }
            }
            
            markdown.append(node.getChars());
        }
    }

    public static class Factory implements NodeFormatterFactory {
        @NotNull
        @Override
        public NodeFormatter create(@NotNull DataHolder options) {
            return new JekyllTagNodeFormatter(options);
        }
    }
}

//        if (embedIncludedContent) {
//            // remove jekyll tag node and just leave the included content
//            Node child = node.getFirstChild();
//
//            if (child != null) child = child.getNextAnyNot(JekyllTag.class);
//
//            while (child != null) {
//                Node next = child.getNextAnyNot(JekyllTag.class);
//                context.render(child);
//                child = next;
//            }
//        } else {
//            Node child = node.getFirstChild();
//            while (child != null) {
//                Node next = child.getNextAny(JekyllTag.class);
//                context.render(child);
//                child = next;
//            }
//        }
        context.renderChildren(node);
    
<no_super_class>