001package ca.cdr.api.hl7v2.util;
002
003import ca.uhn.hl7v2.model.primitive.FormattedTextEncoder;
004import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter;
005import com.vladsch.flexmark.util.data.MutableDataSet;
006import org.apache.commons.lang3.StringUtils;
007
008/**
009 * <p>Utility class for encoding the following character sequences contained in HL7v2 FT (formatted text) fields:</p>
010 * <ul>
011 *      <li>\h\ \n\ - Bold text highlighting</li>
012 *              <li>\.br\ - Line break</li>
013 *              <li>\.ce\ - Center line</li>
014 *              <li>\.fi\ - Fill mode (word wrap)</li>
015 *              <li>\.nf\ - No-fill mode (no wrap)</li>
016 *              <li>\.in X\ - Indent by X spaces</li>
017 *              <li>\.ti X\ - Temporarily indent by X spaces</li>
018 *              <li>\.sk X\ - Skip X spaces to the right</li>
019 *              <li>\.sp X\ - Skip X vertical spaces</li>
020 * </ul>
021 * <p>See {@link OutputFormat} for available output formats.</p>
022 */
023public final class Hl7v2FormattedTextEncoder {
024
025        /**
026         * Output formats for {@link Hl7v2FormattedTextEncoder}
027         */
028        public enum OutputFormat {
029                XHTML,
030                MARKDOWN
031        }
032
033        private Hl7v2FormattedTextEncoder() {
034                // Utility class
035        }
036
037        /**
038         * Encodes a String with HL7v2 FT character sequences to the specified output format
039         * @param theFormattedText - A String containing HL7v2 FT character sequences to be encoded
040         * @param theOutputFormat - The {@link OutputFormat}
041         * @return A String with HL7v2 FT character sequences encoded
042         */
043        public static String encode(String theFormattedText, OutputFormat theOutputFormat) {
044                if (StringUtils.isBlank(theFormattedText)) {
045                        return "";
046                }
047
048                FormattedTextEncoder encoder = FormattedTextEncoder.getInstanceHtml();
049                String htmlResult = encoder.encode(theFormattedText);
050
051                return switch (theOutputFormat) {
052                        case XHTML -> htmlResult;
053                        case MARKDOWN -> convertXhtmlToMarkdown(htmlResult);
054                        default -> throw new IllegalArgumentException("Cannot handle output format: %s".formatted(theOutputFormat));
055                };
056        }
057
058        private static String convertXhtmlToMarkdown(String theXhtml) {
059                MutableDataSet options = new MutableDataSet()
060                                .set(FlexmarkHtmlConverter.BR_AS_PARA_BREAKS, false)
061                                .set(FlexmarkHtmlConverter.BR_AS_EXTRA_BLANK_LINES, false);
062
063                return FlexmarkHtmlConverter.builder(options).build().convert(theXhtml).trim();
064        }
065}