@@ -0,0 +1,2803 @@
+package net.darkhax.bookshelf.crafting.recipes.smithing;%0A%0Aimport com.google.gson.JsonObject;%0A%0Aimport net.darkhax.bookshelf.util.TextUtils;%0Aimport net.minecraft.inventory.IInventory;%0Aimport net.minecraft.item.ItemStack;%0Aimport net.minecraft.item.crafting.IRecipeSerializer;%0Aimport net.minecraft.item.crafting.Ingredient;%0Aimport net.minecraft.item.crafting.SmithingRecipe;%0Aimport net.minecraft.network.PacketBuffer;%0Aimport net.minecraft.util.JSONUtils;%0Aimport net.minecraft.util.ResourceLocation;%0Aimport net.minecraftforge.registries.ForgeRegistryEntry;%0A%0Apublic class SmithingRecipeFont extends SmithingRecipe %7B%0A    %0A    public static final IRecipeSerializer%3C?%3E SERIALIZER = new Serializer();%0A    %0A    private final ResourceLocation fontId;%0A    %0A    public SmithingRecipeFont(ResourceLocation recipeId, Ingredient base, Ingredient addition, ResourceLocation fontId) %7B%0A        %0A        super(recipeId, base, addition, ItemStack.EMPTY);%0A        this.fontId = fontId;%0A    %7D%0A    %0A    @Override%0A    public ItemStack getCraftingResult (IInventory inv) %7B%0A        %0A        final ItemStack stack = inv.getStackInSlot(0).copy();%0A        stack.setDisplayName(TextUtils.applyFont(stack.getDisplayName(), this.fontId));%0A        return stack;%0A    %7D%0A    %0A    @Override%0A    public boolean isDynamic () %7B%0A        %0A        return true;%0A    %7D%0A    %0A    @Override%0A    public IRecipeSerializer%3C?%3E getSerializer () %7B%0A        %0A        return SERIALIZER;%0A    %7D%0A    %0A    private static class Serializer extends ForgeRegistryEntry%3CIRecipeSerializer%3C?%3E%3E implements IRecipeSerializer%3CSmithingRecipeFont%3E %7B%0A        %0A        @Override%0A        public SmithingRecipeFont read (ResourceLocation recipeId, JsonObject json) %7B%0A            %0A            final Ingredient base = Ingredient.deserialize(JSONUtils.getJsonObject(json, %22base%22));%0A            final Ingredient addition = Ingredient.deserialize(JSONUtils.getJsonObject(json, %22addition%22));%0A            final ResourceLocation font = ResourceLocation.tryCreate(JSONUtils.getString(json, %22font%22));%0A            return new SmithingRecipeFont(recipeId, base, addition, font);%0A        %7D%0A        %0A        @Override%0A        public SmithingRecipeFont read (ResourceLocation recipeId, PacketBuffer buffer) %7B%0A            %0A            final Ingredient base = Ingredient.read(buffer);%0A            final Ingredient addition = Ingredient.read(buffer);%0A            final ResourceLocation font = ResourceLocation.tryCreate(buffer.readString());%0A            return new SmithingRecipeFont(recipeId, base, addition, font);%0A        %7D%0A        %0A        @Override%0A        public void write (PacketBuffer buffer, SmithingRecipeFont recipe) %7B%0A            %0A            recipe.base.write(buffer);%0A            recipe.addition.write(buffer);%0A            buffer.writeString(recipe.fontId.toString());%0A        %7D%0A    %7D%0A%7D

Add smithing recipe serializer that can apply a font to the item.