/******************************************************************************* * Copyright (c) 2007, 2016 David Green and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * David Green - initial API and implementation *******************************************************************************/ package org.eclipse.mylyn.wikitext.parser.builder; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.text.Normalizer; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import com.google.common.base.CharMatcher; import com.google.common.base.Charsets; import com.google.common.base.Splitter; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ListMultimap; class HtmlEntities { private static HtmlEntities instance = new HtmlEntities(); private static ListMultimap<String, String> readHtmlEntities() { ImmutableListMultimap.Builder<String, String> builder = ImmutableListMultimap.builder(); try { BufferedReader reader = new BufferedReader(new InputStreamReader( HtmlDocumentBuilder.class.getResourceAsStream("html-entity-references.txt"), Charsets.UTF_8)); //$NON-NLS-1$ try { Splitter splitter = Splitter.on(CharMatcher.WHITESPACE).trimResults().omitEmptyStrings(); String line; while ((line = reader.readLine()) != null) { List<String> lineItems = splitter.splitToList(line); checkState(lineItems.size() > 1); for (int x = 1; x < lineItems.size(); ++x) { builder.put(lineItems.get(0), lineItems.get(x)); } } } finally { reader.close(); } } catch (IOException e) { throw Throwables.propagate(e); } return builder.build(); } public static HtmlEntities instance() { return instance; } private final ListMultimap<String, String> nameToNumericEntityReferences; private final Map<String, String> nameToStringEquivalent; private HtmlEntities() { nameToNumericEntityReferences = readHtmlEntities(); nameToStringEquivalent = createNameToStringEquivalent(nameToNumericEntityReferences); } public List<String> nameToEntityReferences(String name) { return nameToNumericEntityReferences.get(name); } public String nameToStringEquivalent(String name) { return nameToStringEquivalent.get(name); } private Map<String, String> createNameToStringEquivalent( ListMultimap<String, String> nameToNumericEntityReferences) { ImmutableMap.Builder<String, String> mapBuilder = ImmutableMap.builder(); for (String name : nameToNumericEntityReferences.keySet()) { mapBuilder.put(name, stringEquivalent(nameToNumericEntityReferences.get(name))); } return mapBuilder.build(); } private String stringEquivalent(List<String> values) { return Normalizer.normalize(values.stream().map(s -> numericEntityToString(s)).collect(Collectors.joining()), Normalizer.Form.NFC); } private String numericEntityToString(String s) { checkArgument(s.charAt(0) == '#'); return String.valueOf((char) Integer.parseInt(s.substring(1))); } }