Ich habe die Anforderung, eine Art Markdown-Tags zu erstellen, um beim Erstellen von {{X2 }} mit IText
.
Also, angesichts dieser Zeichenfolge:
String toCheck = "Example [N]bold text[N] other example [C]italic text[C]";
Sollte ergeben:
Beispiel Fettdruck anderes Beispiel Kursivtext
Also, lasst uns gehen:
Ich habe eine Aufzählung mit Schriftarten:
private enum FontType {
BOLD, ITALIC, NORMAL
}
Um dies zu erreichen, möchte ich ein LinkedHashMap<String, Enum>
erstellen, um die String-Fragmente mit dem entsprechenden Schrifttyp einzufügen (letzteres wird in com.itextpdf.text.Chunk
umgewandelt und in ein einzelnes com.itextpdf.text.Paragraph
eingefügt.
Wie kann ich das LinkedHashMap
Ergebnis so erzielen?
pos String enum
0 "Example " NORMAL
1 "bold text" BOLD
2 " other example " NORMAL
3 "italic text" ITALIC
Ich habe ein benutzerdefiniertes Iterator
erstellt, das mir die Tag-Position gibt:
public class OwnIterator implements Iterator<Integer>
{
private Iterator<Integer> occurrencesItr;
public OwnIterator(String toCheck, String[] validPair) {
// build regex to search for every item in validPair
Matcher[] matchValidPair = new Matcher[validPair.length];
for (int i = 0 ; i < validPair.length ; i++) {
String regex =
"(" + // start capturing group
"\\Q" + // quote entire input string so it is not interpreted as regex
validPair[i] + // this is what we are looking for, duhh
"\\E" + // end quote
")" ; // end capturing group
Pattern p = Pattern.compile(regex);
matchValidPair[i] = p.matcher(toCheck);
}
// do the search, saving found occurrences in list
List<Integer> occurrences = new ArrayList<>();
for (int i = 0 ; i < matchValidPair.length ; i++) {
while (matchValidPair[i].find()) {
occurrences.add(matchValidPair[i].start(0)+1); // +1 if you want index to start at 1
}
}
// sort the list
Collections.sort(occurrences);
occurrencesItr = occurrences.iterator();
}
@Override
public boolean hasNext() {
return occurrencesItr.hasNext();
}
@Override
public Integer next() {
return occurrencesItr.next();
}
@Override
public void remove() {
occurrencesItr.remove();
}
}
Ich habe bereits überprüft, ob Tags ausgeglichen sind, und kann alle Tag-Positionen abrufen:
String[] validPair = {"[N]", "[C]" };
OwnIterator itr = new OwnIterator(toCheck, validPair);
while (itr.hasNext()) {
System.out.println(itr.next());
}
Aber nachdem Sie alle Positionen erhalten haben, können Sie nicht herausfinden, wie Sie jeden Teil unterscheiden und den richtigen Aufzählungswert zuweisen können.
Einige Ideen? Vielleicht irre ich mich oder jemand kann einen besseren sehen?
2 Antworten
Der folgende Code gibt Ihnen das gewünschte LinkedHashMap
,
private Map<String, FontType> getMapFromTags(String toCheck) {
Map<String, FontType> chunksMap = new LinkedHashMap<>();
boolean openTag = false;
while (toCheck.contains(TAG_NEGRITA) || toCheck.contains(TAG_CURSIVA)) {
final int indexOfBold = toCheck.indexOf(TAG_NEGRITA);
final int indexOfItalics = toCheck.indexOf(TAG_CURSIVA);
final int indexToUse = getValidIndexToUse(indexOfBold, indexOfItalics);
final String substring = toCheck.substring(0, indexToUse);
toCheck = toCheck.substring(indexToUse + 3, toCheck.length());
if (!substring.isEmpty()) {
if (!openTag) {
chunksMap.put(substring, FontType.NORMAL);
} else if (indexToUse == indexOfBold) {
chunksMap.put(substring, FontType.BOLD);
} else {
chunksMap.put(substring, FontType.ITALIC);
}
}
openTag = !openTag;
}
// check if there is some NORMAL text at the end
if (!toCheck.isEmpty())
chunksMap.put(toCheck, FontType.NORMAL);
return chunksMap;
}
private int getValidIndexToUse(int indexOfBold, int indexOfItalics) {
if (indexOfBold > -1 && indexOfItalics == -1)
return indexOfBold;
else if (indexOfItalics > -1 && indexOfBold == -1)
return indexOfItalics;
else
return indexOfBold > -1 && indexOfBold < indexOfItalics ? indexOfBold : indexOfItalics;
}
Es wird jedoch Probleme geben, wenn Sie zwei oder mehr gleiche Zeichenfolgen finden, die gehasht werden müssen.
Wie wäre es damit?
...
String toCheck = "Example [N]bold text[N] other example [C]italic text[C]";
toCheck = replacePairs(toCheck , "[N]","<b>", "</b>");
toCheck = replacePairs(toCheck , "[C]","<i>", "</i>");
OutputStream file = new FileOutputStream(new File("Test.pdf"));
Document document = new Document();
PdfWriter.getInstance(document, file);
document.open();
HTMLWorker htmlWorker = new HTMLWorker(document);
htmlWorker.parse(new StringReader(toCheck));
document.close();
file.close();
...
private String replacePairs(String input, String tag, String openTag, String closeTag) {
String output = input;
while(output.indexOf(tag) >= 0) {
output = output.replaceFirst(tag, openTag);
if (output.indexOf(tag) < 0) {
throw new IllegalArgumentException("Missing closing tag:" + tag);
}
output = output.replaceFirst(tag, closeTag);
}
return output;
}
Haftungsausschluss: Dies ist nicht kompilierter und somit nicht getesteter Code. Sie sollten Ausnahmen behandeln und Ihre Ressourcen im finally-Block ordnungsgemäß schließen (oder Try-with-Resources verwenden).
Neue Fragen
java
Java ist eine Programmiersprache auf hoher Ebene. Verwenden Sie dieses Tag, wenn Sie Probleme haben, die Sprache selbst zu verwenden oder zu verstehen. Dieses Tag wird selten alleine verwendet und wird am häufigsten in Verbindung mit [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] und [maven] verwendet.