src/main/java/com/ruleoftech/markdown/page/generator/plugin/MdPageGeneratorMojo.java
private void processMarkdown(List<MarkdownDTO> markdownDTOs, int options, final Map<String, Attributes> attributesMap) throws MojoExecutionException {
        getLog().debug("Process Markdown");
        getLog().debug("inputEncoding: '" + getInputEncoding() + "', outputEncoding: '" + getOutputEncoding() + "'");
        //getLog().debug("parsingTimeout: " + getParsingTimeoutInMillis() + " ms");
        getLog().debug("applyFiltering: " + applyFiltering);

        MutableDataHolder flexmarkOptions = PegdownOptionsAdapter.flexmarkOptions(options).toMutable();
        ArrayList<Extension> extensions = new ArrayList<Extension>();
        for (Extension extension : flexmarkOptions.get(Parser.EXTENSIONS)) {
            extensions.add(extension);
        }

        if (transformRelativeMarkdownLinks) {
            flexmarkOptions.set(PageGeneratorExtension.INPUT_FILE_EXTENSIONS, inputFileExtensions);
            extensions.add(PageGeneratorExtension.create());
        }

        if (!attributesMap.isEmpty()) {
            flexmarkOptions.set(AttributesExtension.ATTRIBUTE_MAP, attributesMap);
            extensions.add(AttributesExtension.create());
        }

        flexmarkOptions.set(Parser.EXTENSIONS, extensions);

        Parser parser = Parser.builder(flexmarkOptions).build();
        HtmlRenderer renderer = HtmlRenderer.builder(flexmarkOptions).build();

        for (MarkdownDTO dto : markdownDTOs) {
            getLog().debug("dto: " + dto);

            try {
                String headerHtml = "";
                String footerHtml = "";

                try {
                    if (StringUtils.isNotEmpty(headerHtmlFile)) {
                        headerHtml = FileUtils.readFileToString(new File(headerHtmlFile), getInputEncoding());
                        headerHtml = addTitleToHtmlFile(headerHtml, dto.title);
                        headerHtml = replaceVariables(headerHtml, dto.substitutes);
                        headerHtml = updateRelativePaths(headerHtml, dto.folderDepth);
                    }
                    if (StringUtils.isNotEmpty(footerHtmlFile)) {
                        footerHtml = FileUtils.readFileToString(new File(footerHtmlFile), getInputEncoding());
                        footerHtml = replaceVariables(footerHtml, dto.substitutes);
                        footerHtml = updateRelativePaths(footerHtml, dto.folderDepth);
                    }
                } catch (FileNotFoundException e) {
                    if (failIfFilesAreMissing) {
                        throw e;
                    } else {
                        getLog().warn("header and/or footer file is missing.");
                        headerHtml = "";
                        footerHtml = "";
                    }
                } catch (Exception e) {
                    throw new MojoExecutionException("Error while processing header/footer: " + e.getMessage(), e);
                }

                String markdown = FileUtils.readFileToString(dto.markdownFile, getInputEncoding());
                markdown = replaceVariables(markdown, dto.substitutes);
                // getLog().debug(markdown);

                String markdownAsHtml;

                Node document = parser.parse(markdown);
                markdownAsHtml = renderer.render(document);

                String data = headerHtml + markdownAsHtml + footerHtml;
                FileUtils.writeStringToFile(dto.htmlFile, data, getOutputEncoding());
            } catch (MojoExecutionException e) {
                throw e;
            } catch (IOException e) {
                getLog().error("Error : " + e.getMessage(), e);
                throw new MojoExecutionException("Unable to write file " + e.getMessage(), e);
            }
        }
    }
private void processMarkdown(List<MarkdownDTO> markdownDTOs, int options, final Map<String, Attributes> attributesMap) throws MojoExecutionException {
        getLog().debug("Process Markdown");
        getLog().debug("inputEncoding: '" + getInputEncoding() + "', outputEncoding: '" + getOutputEncoding() + "'");
        //getLog().debug("parsingTimeout: " + getParsingTimeoutInMillis() + " ms");
        getLog().debug("applyFiltering: " + applyFiltering);

        MutableDataHolder flexmarkOptions = PegdownOptionsAdapter.flexmarkOptions(options).toMutable();
        ArrayList<Extension> extensions = new ArrayList<Extension>();
        for (Extension extension : flexmarkOptions.get(Parser.EXTENSIONS)) {
            extensions.add(extension);
        }

        if (transformRelativeMarkdownLinks) {
            flexmarkOptions.set(PageGeneratorExtension.INPUT_FILE_EXTENSIONS, inputFileExtensions);
            extensions.add(PageGeneratorExtension.create());
        }

        if (!attributesMap.isEmpty()) {
            flexmarkOptions.set(AttributesExtension.ATTRIBUTE_MAP, attributesMap);
            extensions.add(AttributesExtension.create());
        }

        flexmarkOptions.set(Parser.EXTENSIONS, extensions);

        Parser parser = Parser.builder(flexmarkOptions).build();
        HtmlRenderer renderer = HtmlRenderer.builder(flexmarkOptions).build();

        for (MarkdownDTO dto : markdownDTOs) {
            getLog().debug("dto: " + dto);

            try {
                String headerHtml = "";
                String footerHtml = "";

                try {
                    if (StringUtils.isNotEmpty(headerHtmlFile)) {
                        headerHtml = FileUtils.readFileToString(new File(headerHtmlFile), getInputEncoding());
                        headerHtml = addTitleToHtmlFile(headerHtml, dto.title);
                        headerHtml = replaceVariables(headerHtml, dto.substitutes);
                        headerHtml = updateRelativePaths(headerHtml, dto.folderDepth);
                    }
                    if (StringUtils.isNotEmpty(footerHtmlFile)) {
                        footerHtml = FileUtils.readFileToString(new File(footerHtmlFile), getInputEncoding());
                        footerHtml = replaceVariables(footerHtml, dto.substitutes);
                        footerHtml = updateRelativePaths(footerHtml, dto.folderDepth);
                    }
                } catch (FileNotFoundException e) {
                    if (failIfFilesAreMissing) {
                        throw e;
                    } else {
                        getLog().warn("header and/or footer file is missing.");
                        headerHtml = "";
                        footerHtml = "";
                    }
                } catch (Exception e) {
                    throw new MojoExecutionException("Error while processing header/footer: " + e.getMessage(), e);
                }

                String markdown = FileUtils.readFileToString(dto.markdownFile, getInputEncoding());
                markdown = replaceVariables(markdown, dto.substitutes);
                // getLog().debug(markdown);

                String markdownAsHtml;

                Node document = parser.parse(markdown);
                markdownAsHtml = renderer.render(document);

                String data = headerHtml + markdownAsHtml + footerHtml;
                FileUtils.writeStringToFile(dto.htmlFile, data, getOutputEncoding());
            } catch (MojoExecutionException e) {
                throw e;
            } catch (IOException e) {
                getLog().error("Error : " + e.getMessage(), e);
                throw new MojoExecutionException("Unable to write file " + e.getMessage(), e);
            }
        }
    }
Going through list of DTOs and parsing the markdown into HTML.
Add header and footer to the big String.

@throws MojoExecutionException Unable to write file