diff --git a/README.md b/README.md index 7660e74..ba65981 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,20 @@ files: escape_special_characters: 0 ``` +Or to escape quotes + +- `0` - do not escape +- `1` - escape single quote with another single quote +- `2` - escape single quote with a backslash +- `3` - escape single quote with another single quote only in strings containing variables ( {0} ) + +```yml +files: + - source: "**/values/strings.xml" + translation: "/values-%two_letters_code%/%original_file_name%" + escape_quotes: 3 +``` + ##### Translations upload options The following properties can be used to configure the import options for uploaded translations: diff --git a/build.gradle b/build.gradle index 7d3ad85..6122931 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,7 @@ repositories { dependencies { implementation 'net.lingala.zip4j:zip4j:2.11.3' - implementation 'com.github.crowdin:crowdin-api-client-java:1.19.5' + implementation 'com.github.crowdin:crowdin-api-client-java:1.33.0' implementation 'commons-io:commons-io:2.15.1' implementation 'org.yaml:snakeyaml:2.2' diff --git a/src/main/java/com/crowdin/client/config/CrowdinPropertiesLoader.java b/src/main/java/com/crowdin/client/config/CrowdinPropertiesLoader.java index 3438dcd..9c3a139 100644 --- a/src/main/java/com/crowdin/client/config/CrowdinPropertiesLoader.java +++ b/src/main/java/com/crowdin/client/config/CrowdinPropertiesLoader.java @@ -38,6 +38,7 @@ public class CrowdinPropertiesLoader { private static final String PROPERTY_FILES_UPDATE_STRINGS = "update_strings"; private static final String PROPERTY_EXCLUDED_TARGET_LANGUAGES = "excluded_target_languages"; private static final String PROPERTY_ESCAPE_SPECIAL_CHARACTERS = "escape_special_characters"; + private static final String PROPERTY_ESCAPE_QUOTES = "escape_quotes"; private static final Pattern BASE_URL_PATTERN = Pattern.compile("^(https://([a-zA-Z0-9_-]+\\.(api\\.)?)?crowdin\\.com/?|http://(.+)\\.dev\\.crowdin\\.com/?)$"); @@ -184,6 +185,7 @@ private static List getSourcesWithTranslations(Map pro Boolean updateStrings = getBooleanProperty(file, PROPERTY_FILES_UPDATE_STRINGS); Boolean cleanupMode = getBooleanProperty(file, PROPERTY_FILES_CLEANUP_MODE); Integer escapeSpecialCharacters = getIntegerProperty(file, PROPERTY_ESCAPE_SPECIAL_CHARACTERS); + Integer escapeQuotes = getIntegerProperty(file, PROPERTY_ESCAPE_QUOTES); List labels = getListStringsProperty(file, PROPERTY_LABELS); List excludedTargetLanguages = getListStringsProperty(file, PROPERTY_EXCLUDED_TARGET_LANGUAGES); @@ -196,6 +198,7 @@ private static List getSourcesWithTranslations(Map pro fb.setUpdateStrings(updateStrings); fb.setCleanupMode(cleanupMode); fb.setEscapeSpecialCharacters(escapeSpecialCharacters); + fb.setEscapeQuotes(escapeQuotes); fileBeans.add(fb); } else if (StringUtils.isEmpty(source)) { errors.add(String.format(MESSAGES_BUNDLE.getString("errors.config.missing_property"), PROPERTY_FILES_SOURCE)); diff --git a/src/main/java/com/crowdin/client/config/FileBean.java b/src/main/java/com/crowdin/client/config/FileBean.java index 85e6524..330f296 100644 --- a/src/main/java/com/crowdin/client/config/FileBean.java +++ b/src/main/java/com/crowdin/client/config/FileBean.java @@ -12,6 +12,7 @@ public class FileBean { private Boolean cleanupMode; private Boolean updateStrings; private Integer escapeSpecialCharacters; + private Integer escapeQuotes; public String getSource() { return source; @@ -69,17 +70,24 @@ public void setEscapeSpecialCharacters(Integer escapeSpecialCharacters) { this.escapeSpecialCharacters = escapeSpecialCharacters; } + public Integer getEscapeQuotes() { + return escapeQuotes; + } + + public void setEscapeQuotes(Integer escapeQuotes) { + this.escapeQuotes = escapeQuotes; + } + @Override public boolean equals(Object o) { - if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; FileBean fileBean = (FileBean) o; - return Objects.equals(source, fileBean.source) && Objects.equals(translation, fileBean.translation) && Objects.equals(excludedTargetLanguages, fileBean.excludedTargetLanguages) && Objects.equals(labels, fileBean.labels) && Objects.equals(cleanupMode, fileBean.cleanupMode) && Objects.equals(updateStrings, fileBean.updateStrings) && Objects.equals(escapeSpecialCharacters, fileBean.escapeSpecialCharacters); + return Objects.equals(source, fileBean.source) && Objects.equals(translation, fileBean.translation) && Objects.equals(excludedTargetLanguages, fileBean.excludedTargetLanguages) && Objects.equals(labels, fileBean.labels) && Objects.equals(cleanupMode, fileBean.cleanupMode) && Objects.equals(updateStrings, fileBean.updateStrings) && Objects.equals(escapeSpecialCharacters, fileBean.escapeSpecialCharacters) && Objects.equals(escapeQuotes, fileBean.escapeQuotes); } @Override public int hashCode() { - return Objects.hash(source, translation, excludedTargetLanguages, labels, cleanupMode, updateStrings, escapeSpecialCharacters); + return Objects.hash(source, translation, excludedTargetLanguages, labels, cleanupMode, updateStrings, escapeSpecialCharacters, escapeQuotes); } @Override @@ -92,6 +100,7 @@ public String toString() { ", cleanupMode=" + cleanupMode + ", updateStrings=" + updateStrings + ", escapeSpecialCharacters=" + escapeSpecialCharacters + + ", escapeQuotes=" + escapeQuotes + '}'; } } diff --git a/src/main/java/com/crowdin/logic/SourceLogic.java b/src/main/java/com/crowdin/logic/SourceLogic.java index 432e5bc..df0d51f 100644 --- a/src/main/java/com/crowdin/logic/SourceLogic.java +++ b/src/main/java/com/crowdin/logic/SourceLogic.java @@ -118,6 +118,10 @@ public void uploadSource(VirtualFile source, FileBean fileBean, boolean preserve exportOptions.setEscapeSpecialCharacters(fileBean.getEscapeSpecialCharacters()); } + if (fileBean.getEscapeQuotes() != null) { + exportOptions.setEscapeQuotes(fileBean.getEscapeQuotes()); + } + String outputName = FileUtil.noSepAtStart(path); FileInfo foundFile = filePaths.get(path); if (foundFile != null) {