class AbbreviationNodeFormatter extends NodeRepositoryFormatter<AbbreviationRepository, AbbreviationBlock, Abbreviation> {
    final public static DataKey<Map<String, String>> ABBREVIATION_TRANSLATION_MAP = new DataKey<>("ABBREVIATION_TRANSLATION_MAP", new HashMap<>()); //
    final public static DataKey<Map<String, String>> ABBREVIATION_UNIQUIFICATION_MAP = new DataKey<>("ABBREVIATION_UNIQUIFICATION_MAP", new HashMap<>()); // uniquified references
    final private AbbreviationFormatOptions options;
    final private boolean transformUnderscores;
    final private boolean makeMergedAbbreviationsUnique;

    public AbbreviationNodeFormatter(DataHolder options) {
        super(options, ABBREVIATION_TRANSLATION_MAP, ABBREVIATION_UNIQUIFICATION_MAP);
        this.options = new AbbreviationFormatOptions(options);

        String transformedId = String.format(Formatter.TRANSLATION_ID_FORMAT.get(options), 1);
        transformUnderscores = transformedId.startsWith("_") && transformedId.endsWith("_");
        makeMergedAbbreviationsUnique = AbbreviationExtension.MAKE_MERGED_ABBREVIATIONS_UNIQUE.get(options);
    }

    @Override
    protected boolean makeReferencesUnique() {
        return makeMergedAbbreviationsUnique;
    }

    @Override
    public AbbreviationRepository getRepository(DataHolder options) {
        return AbbreviationExtension.ABBREVIATIONS.get(options);
    }

    @Override
    public ElementPlacement getReferencePlacement() {
        return options.abbreviationsPlacement;
    }

    @Override
    public ElementPlacementSort getReferenceSort() {
        return options.abbreviationsSort;
    }

    @Override
    public String modifyTransformedReference(String transformedText, NodeFormatterContext context) {<FILL_FUNCTION_BODY>}

    @Override
    public void renderReferenceBlock(AbbreviationBlock node, NodeFormatterContext context, MarkdownWriter markdown) {
        markdown.append(node.getOpeningMarker());
        markdown.append(transformReferenceId(node.getText().toString(), context));
        markdown.append(node.getClosingMarker()).append(' ');
        markdown.appendTranslating(node.getAbbreviation()).line();
    }

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

    @Nullable
    @Override
    public Set<Class<?>> getNodeClasses() {
        if (options.abbreviationsPlacement.isNoChange() || !options.abbreviationsSort.isUnused()) return null;
        // noinspection ArraysAsListWithZeroOrOneArgument
        return new HashSet<>(Arrays.asList(
                Abbreviation.class
        ));
    }

    private void render(AbbreviationBlock node, NodeFormatterContext context, MarkdownWriter markdown) {
        renderReference(node, context, markdown);
    }

    private void render(Abbreviation node, NodeFormatterContext context, MarkdownWriter markdown) {
        if (context.isTransformingText()) {
            String referenceId = transformReferenceId(node.getChars().toString(), context);
            markdown.append(referenceId);
        } else {
            markdown.append(node.getChars());
        }
    }

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

        if (transformUnderscores && context.isTransformingText()) {
            if (transformedText.startsWith("-") && transformedText.endsWith("-")) {
                transformedText = "_" + transformedText.substring(1, transformedText.length() - 1) + "_";
            } else if (transformedText.startsWith("_") && transformedText.endsWith("_")) {
                transformedText = "-" + transformedText.substring(1, transformedText.length() - 1) + "-";
            }
        }

        return transformedText;
    
<methods>public void <init>(com.vladsch.flexmark.util.data.DataHolder, DataKey<Map<java.lang.String,java.lang.String>>, DataKey<Map<java.lang.String,java.lang.String>>) ,public @Nullable Set<FormattingPhase> getFormattingPhases() ,public Comparator<com.vladsch.flexmark.ext.abbreviation.AbbreviationBlock> getReferenceComparator() ,public abstract com.vladsch.flexmark.util.format.options.ElementPlacement getReferencePlacement() ,public abstract com.vladsch.flexmark.util.format.options.ElementPlacementSort getReferenceSort() ,public abstract com.vladsch.flexmark.ext.abbreviation.internal.AbbreviationRepository getRepository(com.vladsch.flexmark.util.data.DataHolder) ,public java.lang.String modifyTransformedReference(java.lang.String, com.vladsch.flexmark.formatter.NodeFormatterContext) ,public void renderDocument(@NotNull NodeFormatterContext, @NotNull MarkdownWriter, @NotNull Document, @NotNull FormattingPhase) <variables>public static final HashSet<com.vladsch.flexmark.formatter.FormattingPhase> FORMATTING_PHASES,protected final non-sealed com.vladsch.flexmark.ext.abbreviation.AbbreviationBlock lastReference,protected final non-sealed Comparator<com.vladsch.flexmark.ext.abbreviation.AbbreviationBlock> myComparator,private final non-sealed DataKey<Map<java.lang.String,java.lang.String>> myReferenceMapKey,private final non-sealed DataKey<Map<java.lang.String,java.lang.String>> myReferenceUniqificationMapKey,protected boolean recheckUndefinedReferences,protected final non-sealed List<com.vladsch.flexmark.ext.abbreviation.AbbreviationBlock> referenceList,protected final non-sealed com.vladsch.flexmark.ext.abbreviation.internal.AbbreviationRepository referenceRepository,private Map<java.lang.String,java.lang.String> referenceTranslationMap,protected Map<java.lang.String,java.lang.String> referenceUniqificationMap,protected boolean repositoryNodesDone,protected final non-sealed HashSet<com.vladsch.flexmark.util.ast.Node> unusedReferences