Skip to content

Commit 1920be5

Browse files
committed
Avoided segmentation inside HTML attributes
1 parent eaf3659 commit 1920be5

3 files changed

Lines changed: 61 additions & 27 deletions

File tree

lib/openxliff.jar

222 Bytes
Binary file not shown.

src/com/maxprograms/converters/Constants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ private Constants() {
2222
public static final String TOOLID = "OpenXLIFF";
2323
public static final String TOOLNAME = "OpenXLIFF Filters";
2424
public static final String VERSION = "4.7.0";
25-
public static final String BUILD = "20250711_1319";
25+
public static final String BUILD = "20250714_1234";
2626

2727
public static final String SUCCESS = "0";
2828
public static final String ERROR = "1";

src/com/maxprograms/converters/json/Json2Xliff.java

Lines changed: 60 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ protected static List<String[]> loadEntities(Catalog catalog)
215215
throws SAXException, IOException, NumberFormatException {
216216
List<String[]> result = new Vector<>();
217217

218-
Pattern pattern = Pattern.compile("&#[\\d]+\\;");
218+
Pattern pattern = Pattern.compile("&#[\\d]+;");
219219

220220
DTDParser parser = new DTDParser();
221221
String latin = catalog.matchPublic("-//W3C//ENTITIES Latin 1 for XHTML//EN");
@@ -313,7 +313,8 @@ private static void parseJson(JSONObject json) {
313313
}
314314
}
315315

316-
private static void parseJson(JSONObject json, JsonConfig config) throws IOException {
316+
private static void parseJson(JSONObject json, JsonConfig config)
317+
throws IOException, SAXException, ParserConfigurationException {
317318
List<String> translatableKeys = config.getSourceKeys();
318319
List<String> ignorable = config.getIgnorableKeys();
319320
Set<String> parsedKeys = new HashSet<>();
@@ -388,62 +389,82 @@ private static void parseJson(JSONObject json, JsonConfig config) throws IOExcep
388389
if (!resnameText.isEmpty()) {
389390
parsedKeys.add(resnameKey);
390391
}
392+
ElementHolder sourceHolder = ElementBuilder.buildElement("source", sourceText, trimTags,
393+
mergeTags, htmlIgnore, config.getPreserveSpaces());
394+
ElementHolder targetHolder = ElementBuilder.buildElement("target", targetText, trimTags,
395+
mergeTags, htmlIgnore, config.getPreserveSpaces());
391396

392-
String[] sourceSegments = new String[] { sourceText };
397+
Element fullSource = sortTags(sourceHolder.getElement());
398+
Element fullTarget = matchTags(fullSource, targetHolder.getElement());
399+
400+
List<Element> sourceList = new Vector<>();
393401
if (segmenter != null) {
394-
sourceSegments = rawSegmentation ? segmenter.segmentRawString(sourceText)
395-
: segmenter.segment(sourceText);
402+
Element segmentedSource = segmenter.segment(fullSource);
403+
sourceList.addAll(splitSegmented("source", segmentedSource));
404+
} else {
405+
sourceList.add(fullSource);
396406
}
397-
String[] targetSegments = new String[] {};
398-
if (!tgtLang.isEmpty() && !targetText.isEmpty() && targetSegmenter != null) {
399-
targetSegments = rawSegmentation ? segmenter.segmentRawString(targetText)
400-
: targetSegmenter.segment(targetText);
401-
if (targetSegments.length != sourceSegments.length) {
402-
sourceSegments = new String[] { sourceText };
403-
targetSegments = new String[] { targetText };
404-
}
407+
List<Element> targetList = new Vector<>();
408+
if (targetSegmenter != null) {
409+
Element segmentedTarget = targetSegmenter.segment(fullTarget);
410+
targetList.addAll(splitSegmented("target", segmentedTarget));
411+
} else {
412+
targetList.add(fullTarget);
405413
}
414+
415+
if (sourceList.size() != targetList.size()) {
416+
sourceList.clear();
417+
sourceList.add(fullSource);
418+
targetList.clear();
419+
targetList.add(fullTarget);
420+
}
421+
406422
StringBuilder sb = new StringBuilder();
407-
for (int h = 0; h < sourceSegments.length; h++) {
423+
for (int h = 0; h < sourceList.size(); h++) {
408424
Element transUnit = new Element("trans-unit");
409425
if (!resnameText.isEmpty()) {
410426
transUnit.setAttribute("resname", resnameText);
411427
}
412-
String suffix = sourceSegments.length > 1 ? "-" + (h + 1) : "";
428+
String suffix = sourceList.size() > 1 ? "-" + (h + 1) : "";
413429
transUnit.setAttribute("id", idString.isEmpty() ? "" + id : idString + suffix);
414430
if (ids.contains(transUnit.getAttributeValue("id"))) {
415431
MessageFormat mf = new MessageFormat(Messages.getString("Json2Xliff.4"));
416432
throw new IOException(mf.format(new String[] { transUnit.getAttributeValue("id") }));
417433
}
418434
ids.add(transUnit.getAttributeValue("id"));
419435
transUnit.addContent("\n ");
420-
ElementHolder sourceHolder = ElementBuilder.buildElement("source", sourceSegments[h], trimTags,
421-
mergeTags, htmlIgnore, config.getPreserveSpaces());
422-
Element source = sortTags(sourceHolder.getElement());
436+
437+
Element source = sourceList.get(h);
423438
transUnit.addContent(source);
424439
if (transUnit.getChild("source").getChildren().isEmpty() || config.getPreserveSpaces()) {
425440
transUnit.setAttribute("xml:space", "preserve");
426441
}
427442
boolean hasTarget = false;
428443
if (tgtLang.isEmpty() || targetText.isEmpty()) {
429-
sb.append(sourceHolder.getStart());
444+
if (h == 0) {
445+
sb.append(sourceHolder.getStart());
446+
}
430447
sb.append("%%%");
431448
sb.append(idString.isEmpty() ? "" + id++ : transUnit.getAttributeValue("id"));
432449
sb.append("%%%");
433-
sb.append(sourceHolder.getEnd());
450+
if (h == sourceList.size() - 1) {
451+
sb.append(sourceHolder.getEnd());
452+
}
434453
json.put(sourceKey, sb.toString());
435454
} else {
436-
ElementHolder targetHolder = ElementBuilder.buildElement("target", targetSegments[h], trimTags,
437-
mergeTags, htmlIgnore, config.getPreserveSpaces());
438-
Element target = matchTags(source, targetHolder.getElement());
455+
Element target = targetList.get(h);
439456
transUnit.addContent("\n ");
440457
transUnit.addContent(target);
441458
hasTarget = true;
442-
sb.append(targetHolder.getStart());
459+
if (h == 0) {
460+
sb.append(targetHolder.getStart());
461+
}
443462
sb.append("%%%");
444463
sb.append(idString.isEmpty() ? "" + id++ : transUnit.getAttributeValue("id"));
445464
sb.append("%%%");
446-
sb.append(targetHolder.getEnd());
465+
if (h == sourceList.size() - 1) {
466+
sb.append(targetHolder.getEnd());
467+
}
447468
json.put(targetKey, sb.toString());
448469
}
449470
if (approved && hasTarget) {
@@ -501,6 +522,18 @@ private static void parseJson(JSONObject json, JsonConfig config) throws IOExcep
501522
}
502523
}
503524

525+
private static List<Element> splitSegmented(String name, Element segmented) {
526+
List<Element> result = new Vector<>();
527+
List<Element> marks = segmented.getChildren("mrk");
528+
for (int i = 0; i < marks.size(); i++) {
529+
Element mrk = marks.get(i);
530+
Element e = new Element(name);
531+
e.setContent(mrk.getContent());
532+
result.add(e);
533+
}
534+
return result;
535+
}
536+
504537
private static Element sortTags(Element source) {
505538
List<Element> sourceTags = source.getChildren();
506539
Iterator<Element> it = sourceTags.iterator();
@@ -658,7 +691,8 @@ private static void parseArray(JSONArray array) {
658691
}
659692
}
660693

661-
private static void parseArray(JSONArray array, JsonConfig config) throws JSONException, IOException {
694+
private static void parseArray(JSONArray array, JsonConfig config)
695+
throws JSONException, IOException, SAXException, ParserConfigurationException {
662696
for (int i = 0; i < array.length(); i++) {
663697
Object obj = array.get(i);
664698
if (obj instanceof String string) {

0 commit comments

Comments
 (0)