[ https://issues.apache.org/jira/browse/FLINK-9792?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16545075#comment-16545075 ]
ASF GitHub Bot commented on FLINK-9792: --------------------------------------- Github user zentol commented on a diff in the pull request: https://github.com/apache/flink/pull/6312#discussion_r202644607 --- Diff: flink-core/src/main/java/org/apache/flink/configuration/description/LineBreakElement.java --- @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.flink.configuration.description; + +/** + * Represents a line break in the {@link Description}. + */ +public class LineBreakElement implements BlockElement { + + /** + * Creates a line break in the description. + */ + public static LineBreakElement linebreak() { + return new LineBreakElement(); + } + + private LineBreakElement() { + } + + @Override + public String format(Formatter formatter) { --- End diff -- hmm... i think we can do this with internal state. I gave it a shot and came up with 2 versions: 1) internal state kept in `HtmlFormatter` The internal state is a simple Stringbuilder. The only tricky part is the format string for `text()`, for this i create a new `HtmlFormatter` for each individual element, and then add them to the actual state. Changes are isolated to `HtmlFormatter`. 2) internal state kept in `Formatter`, main formatting logic now resides in `Formatter` with hooks for specific elements (like List prefixes) that subclasses implement. Same approach for dealing with `text()` as for 1), solved with `Formatter#duplicate()` method. ## 1) ``` public abstract class Formatter { /** * Formats the description into a String using format specific tags. * * @param description description to be formatted * @return string representation of the description */ public String format(Description description) { description.getBlocks().forEach(b -> b.format(this)); return finalizeFormatting(); } public abstract String finalizeFormatting(); public abstract void format(LinkElement element); public abstract void format(TextElement element); public abstract void format(LineBreakElement element); public abstract void format(ListElement element); } public class HtmlFormatter extends Formatter { private final StringBuilder state = new StringBuilder(); public String finalizeFormatting() { return state.toString(); //TODO: clean state } @Override public void format(LinkElement element) { state.append(String.format("<a href=\"%s\">%s</a>", element.getLink(), element.getText())); } @Override public void format(TextElement element) { String format = escapeCharacters(element.getFormat()); final List<InlineElement> inlineElements = element.getElements(); if (inlineElements.isEmpty()) { state.append(format); } else { Object[] formattedInlineElements = new String[inlineElements.size()]; for (int x = 0; x < formattedInlineElements.length; x++) { HtmlFormatter innerFormatter = new HtmlFormatter(); inlineElements.get(x).format(innerFormatter); formattedInlineElements[x] = innerFormatter.finalizeFormatting(); } state.append(String.format(format, formattedInlineElements)); } } @Override public void format(LineBreakElement element) { state.append("<br/>"); } @Override public void format(ListElement element) { state.append("<ul>"); for (InlineElement item : element.getEntries()) { state.append("<li>"); item.format(this); state.append("</li>"); } state.append("</ul>"); } private static String escapeCharacters(String value) { return value .replaceAll("<", "<") .replaceAll(">", ">"); } } ## 2) ``` public abstract class Formatter { private final StringBuilder state = new StringBuilder(); /** * Formats the description into a String using format specific tags. * * @param description description to be formatted * @return string representation of the description */ public String format(Description description) { description.getBlocks().forEach(b -> b.format(this)); return finalizeFormatting(); } public String finalizeFormatting() { return state.toString(); } public void format(LinkElement element) { state.append(getLinkPrefix() + element.getLink() + getLinkInfix() + element.getText() + getLinkSuffix()); } public abstract String getLinkPrefix(); public abstract String getLinkInfix(); public abstract String getLinkSuffix(); public void format(TextElement element) { String format = escapeTextCharacters(element.getFormat()); final List<InlineElement> inlineElements = element.getElements(); if (inlineElements.isEmpty()) { state.append(format); } else { Object[] formattedInlineElements = new String[inlineElements.size()]; for (int x = 0; x < formattedInlineElements.length; x++) { Formatter innerFormatter = duplicate(); inlineElements.get(x).format(innerFormatter); formattedInlineElements[x] = innerFormatter.finalizeFormatting(); } state.append(String.format(format, formattedInlineElements)); } } public void format(LineBreakElement element) { state.append(createLineBreak()); } public abstract String createLineBreak(); public void format(ListElement element) { state.append(getListPrefix()); for (InlineElement item : element.getEntries()) { state.append(getListItemPrefix()); item.format(this); state.append(getListItemSuffix()); } state.append(getListSuffix()); } public abstract String getListPrefix(); public abstract String getListSuffix(); public abstract String getListItemPrefix(); public abstract String getListItemSuffix(); public abstract Formatter duplicate(); protected abstract String escapeTextCharacters(String value); } public class HtmlFormatter extends Formatter { @Override public String getLinkPrefix() { return "<a href=\""; } @Override public String getLinkInfix() { return "\">"; } @Override public String getLinkSuffix() { return "</a>"; } @Override public String createLineBreak() { return "<br/>"; } @Override public String getListPrefix() { return "<ul>"; } @Override public String getListSuffix() { return "</ul>"; } @Override public String getListItemPrefix() { return "<li>"; } @Override public String getListItemSuffix() { return "</li>"; } protected String escapeTextCharacters(String value) { return value .replaceAll("<", "<") .replaceAll(">", ">"); } @Override public Formatter duplicate() { return new HtmlFormatter(); } } ``` > Cannot add html tags in options description > ------------------------------------------- > > Key: FLINK-9792 > URL: https://issues.apache.org/jira/browse/FLINK-9792 > Project: Flink > Issue Type: Bug > Components: Documentation > Affects Versions: 1.5.1, 1.6.0 > Reporter: Dawid Wysakowicz > Assignee: Dawid Wysakowicz > Priority: Major > Labels: pull-request-available > > Right now it is impossible to add any html tags in options description, > because all "<" and ">" are escaped. Therefore some links there do not work. -- This message was sent by Atlassian JIRA (v7.6.3#76005)