| /******************************************************************************* |
| * Copyright (c) 2010, 2011 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| ******************************************************************************/ |
| package org.eclipse.equinox.bidi; |
| |
| import org.eclipse.equinox.bidi.advanced.*; |
| import org.eclipse.equinox.bidi.custom.StructuredTextTypeHandler; |
| |
| /** |
| * Provides methods to process bidirectional text with a specific |
| * structure. The methods in this class are the most straightforward |
| * way to add directional formatting characters to the source text to |
| * ensure correct presentation, or to remove those characters to |
| * restore the original text |
| * (for more explanations, please see the |
| * {@link org.eclipse.equinox.bidi package documentation}. |
| * <p> |
| * This class can be used without OSGi running (but only the structured text types declared |
| * in {@link StructuredTextTypeHandlerFactory} are available in that mode). |
| * </p> |
| * |
| * @noinstantiate This class is not intended to be instantiated by clients. |
| */ |
| public final class StructuredTextProcessor { |
| |
| /** |
| * The default set of separators used to segment a string: dot, |
| * colon, slash, backslash. |
| */ |
| private static final String defaultSeparators = ".:/\\"; //$NON-NLS-1$ |
| |
| // left to right mark |
| private static final char LRM = '\u200e'; |
| |
| // left to right embedding |
| private static final char LRE = '\u202a'; |
| |
| // right to left embedding |
| private static final char RLE = '\u202b'; |
| |
| // pop directional format |
| private static final char PDF = '\u202c'; |
| |
| /** |
| * Prevents instantiation. |
| */ |
| private StructuredTextProcessor() { |
| // empty |
| } |
| |
| /** |
| * Processes the given (<i>lean</i>) text and returns a string with appropriate |
| * directional formatting characters (<i>full</i> text). This is equivalent to |
| * calling {@link #process(String str, String separators)} with the default |
| * set of separators. |
| * <p> |
| * The processing adds directional formatting characters so that presentation |
| * using the Unicode Bidirectional Algorithm will provide the expected result. |
| * The text is segmented according to the provided separators. |
| * Each segment has the Unicode Bidi Algorithm applied to it, |
| * but as a whole, the string is oriented left to right. |
| * </p><p> |
| * For example, a file path such as <code>d:\myfolder\FOLDER\MYFILE.java</code> |
| * (where capital letters indicate RTL text) should render as |
| * <code>d:\myfolder\REDLOF\ELIFYM.java</code>. |
| * </p> |
| * |
| * @param str the <i>lean</i> text to process |
| * |
| * @return the processed string (<i>full</i> text) |
| * |
| * @see #deprocess(String) |
| */ |
| public static String process(String str) { |
| return process(str, defaultSeparators); |
| } |
| |
| /** |
| * Processes a string that has a particular semantic meaning to render |
| * it correctly in bidi environments. |
| * For more details, see {@link #process(String)}. |
| * |
| * @param str the <i>lean</i> text to process |
| * @param separators characters by which the string will be segmented |
| * |
| * @return the processed string (<i>full</i> text) |
| * |
| * @see #deprocess(String) |
| */ |
| public static String process(String str, String separators) { |
| if ((str == null) || (str.length() <= 1)) |
| return str; |
| |
| // do not process a string that has already been processed. |
| if (str.charAt(0) == LRE && str.charAt(str.length() - 1) == PDF) |
| return str; |
| |
| StructuredTextEnvironment env = new StructuredTextEnvironment(null, false, StructuredTextEnvironment.ORIENT_UNKNOWN); |
| // do not process a string if all the following conditions are true: |
| // a) it has no RTL characters |
| // b) it starts with a LTR character |
| // c) it ends with a LTR character or a digit |
| boolean isStringBidi = false; |
| int strLength = str.length(); |
| char c; |
| for (int i = 0; i < strLength; i++) { |
| c = str.charAt(i); |
| if (((c >= 0x05d0) && (c <= 0x07b1)) || ((c >= 0xfb1d) && (c <= 0xfefc))) { |
| isStringBidi = true; |
| break; |
| } |
| } |
| while (!isStringBidi) { |
| if (!Character.isLetter(str.charAt(0))) |
| break; |
| c = str.charAt(strLength - 1); |
| if (!Character.isDigit(c) && !Character.isLetter(c)) |
| break; |
| return str; |
| } |
| |
| if (separators == null) |
| separators = defaultSeparators; |
| |
| // make sure that LRE/PDF are added around the string |
| StructuredTextTypeHandler handler = new StructuredTextTypeHandler(separators); |
| IStructuredTextExpert expert = StructuredTextExpertFactory.getStatefulExpert(handler, env); |
| return expert.leanToFullText(str); |
| } |
| |
| /** |
| * Processes a string that has a particular semantic meaning to render |
| * it correctly in bidi environments. |
| * For more details, see {@link #process(String)}. |
| * |
| * @param str the <i>lean</i> text to process. |
| * @param textType an identifier for the structured text handler |
| * appropriate for the type of the text submitted. |
| * It may be one of the identifiers defined in |
| * {@link StructuredTextTypeHandlerFactory} or a type handler identifier |
| * registered by a plug-in. |
| * |
| * @return the processed string (<i>full</i> text). |
| * |
| * @see #deprocessTyped |
| */ |
| public static String processTyped(String str, String textType) { |
| if ((str == null) || (str.length() <= 1)) |
| return str; |
| |
| // do not process a string that has already been processed. |
| char c = str.charAt(0); |
| if (((c == LRE) || (c == RLE)) && str.charAt(str.length() - 1) == PDF) |
| return str; |
| |
| // make sure that LRE/PDF are added around the string |
| StructuredTextEnvironment env = new StructuredTextEnvironment(null, false, StructuredTextEnvironment.ORIENT_UNKNOWN); |
| IStructuredTextExpert expert = StructuredTextExpertFactory.getExpert(textType, env); |
| return expert.leanToFullText(str); |
| } |
| |
| /** |
| * Removes directional formatting characters in the given string. |
| * |
| * @param str string with directional characters to remove (<i>full</i> text). |
| * |
| * @return string without directional formatting characters (<i>lean</i> text). |
| */ |
| public static String deprocess(String str) { |
| if ((str == null) || (str.length() <= 1)) |
| return str; |
| |
| StringBuilder buf = new StringBuilder(); |
| int strLen = str.length(); |
| for (int i = 0; i < strLen; i++) { |
| char c = str.charAt(i); |
| switch (c) { |
| case LRM : |
| continue; |
| case LRE : |
| continue; |
| case PDF : |
| continue; |
| default : |
| buf.append(c); |
| } |
| } |
| return buf.toString(); |
| } |
| |
| /** |
| * Removes directional formatting characters in the given string. |
| * |
| * @param str string with directional characters to remove (<i>full</i> text). |
| * @param textType an identifier for the structured text handler |
| * appropriate for the type of the text submitted. |
| * It may be one of the identifiers defined in |
| * {@link StructuredTextTypeHandlerFactory} or a type handler identifier |
| * registered by a plug-in. |
| * |
| * @return string without directional formatting characters (<i>lean</i> text). |
| * |
| * @see #processTyped(String, String) |
| */ |
| public static String deprocessTyped(String str, String textType) { |
| if ((str == null) || (str.length() <= 1)) |
| return str; |
| |
| // make sure that LRE/PDF are removed from the string |
| StructuredTextEnvironment env = new StructuredTextEnvironment(null, false, StructuredTextEnvironment.ORIENT_UNKNOWN); |
| IStructuredTextExpert expert = StructuredTextExpertFactory.getExpert(textType, env); |
| return expert.fullToLeanText(str); |
| } |
| |
| /** |
| * Returns a string containing all the default separator characters to be |
| * used to segment a given string. |
| * |
| * @return string containing all separators. |
| */ |
| public static String getDefaultSeparators() { |
| return defaultSeparators; |
| } |
| |
| } |