public static boolean replaceGeneratedContent(final Path file,
                                                  final String generatedContent,
                                                  final String startMarker,
                                                  final String endMarker) {
        if (NullSafe.isBlankString(generatedContent)) {
            throw new RuntimeException("content is blank");
        }
        checkFileExists(file);
        checkFileIsWritable(file);

        try {
            final String existingFileContent = Files.readString(file);
            final List<String> headerLines = new ArrayList<>();
            final List<String> footerLines = new ArrayList<>();
            // Add the existing non-generated content
            final AtomicBoolean seenStartMarker = new AtomicBoolean(false);
            final AtomicBoolean seenEndMarker = new AtomicBoolean(false);

            // Markers are assumed to take a whole line, so anything else on that line is
            // ignored if it contains a marker
            existingFileContent.lines()
                    .forEach(line -> {
                        if (NullSafe.contains(line, startMarker)) {
                            seenStartMarker.set(true);
                        } else if (NullSafe.contains(line, endMarker)) {
                            if (!seenStartMarker.get()) {
                                throw new RuntimeException(LogUtil.message(
                                        "Seen end marker '{}' before start marker '{}'",
                                        endMarker,
                                        startMarker));
                            }
                            seenEndMarker.set(true);
                        } else {
                            if (!seenStartMarker.get()) {
                                headerLines.add(line);
                            } else if (seenEndMarker.get()) {
                                footerLines.add(line);
                            }
                        }
                    });

            if (!seenStartMarker.get()) {
                throw new RuntimeException(LogUtil.message("Did not find start marker '{}'", startMarker));
            }

            // Add the marker line
            final List<String> modifiedLines = new ArrayList<>(headerLines);
            modifiedLines.add(MARKER_START_HTML);

            // Now add in the new generated content
            generatedContent.lines().forEach(modifiedLines::add);

            // Not all files need an end marker
            if (seenEndMarker.get()) {
                modifiedLines.add(MARKER_END_HTML);
                modifiedLines.addAll(footerLines);
            }

            final String newFileContent = String.join("\n", modifiedLines);

            final boolean contentDiffers = DiffUtil.unifiedDiff(
                    existingFileContent,
                    newFileContent,
                    true,
                    3,
                    diffLines -> LOGGER.debug(() -> LogUtil.message(
                            "Showing modifications for file {}\n{}",
                            file, String.join("\n", diffLines))));

            if (contentDiffers) {
                Files.writeString(
                        file,
                        newFileContent,
                        StandardOpenOption.WRITE,
                        StandardOpenOption.TRUNCATE_EXISTING);

                return true;
            } else {
                LOGGER.debug("File content not changed for file {}", file);
                return false;
            }
        } catch (IOException e) {
            throw new RuntimeException(LogUtil.message("Error reading file '{}': {}",
                    file.toAbsolutePath().normalize(),
                    LogUtil.exceptionMessage(e)));
        }
    }
Utils to help with generating docs content for the stroom-docs repo from stroom code.
stroom-test-common/src/main/java/stroom/test/common/docs/StroomDocsUtil.java