Improved language support for IG development
This commit is contained in:
parent
b2e3c261e4
commit
99ea673b91
|
@ -1342,6 +1342,23 @@ public class Element extends Base implements NamedItem {
|
|||
children.add(ne);
|
||||
return ne;
|
||||
}
|
||||
// polymorphic support
|
||||
if (p.getName().endsWith("[x]")) {
|
||||
String base = p.getName().substring(0, p.getName().length()-3);
|
||||
|
||||
if (name.startsWith(base)) {
|
||||
String type = name.substring(base.length());
|
||||
if (p.getContextUtils().isPrimitiveType(Utilities.uncapitalize(type))) {
|
||||
type = Utilities.uncapitalize(type);
|
||||
}
|
||||
if (p.canBeType(type)) {
|
||||
Element ne = new Element(name, p).setFormat(format);
|
||||
ne.setType(type);
|
||||
children.add(ne);
|
||||
return ne;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error("Unrecognised property '"+name+"' on "+this.name);
|
||||
|
|
|
@ -24,6 +24,10 @@ import org.hl7.fhir.utilities.i18n.LanguageFileProducer;
|
|||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerLanguageSession;
|
||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TextUnit;
|
||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TranslationUnit;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
|
||||
|
||||
/**
|
||||
* in here:
|
||||
|
@ -78,7 +82,6 @@ public class LanguageUtils {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private String contextForElement(Element element) {
|
||||
throw new Error("Not done yet");
|
||||
}
|
||||
|
@ -110,7 +113,7 @@ public class LanguageUtils {
|
|||
}
|
||||
|
||||
private boolean isTranslatable(Element element) {
|
||||
return element.getProperty().isTranslatable() && !Utilities.existsInList(pathForElement(element), "CanonicalResource.version");
|
||||
return element.getProperty().isTranslatable();
|
||||
}
|
||||
|
||||
private String pathForElement(Element element) {
|
||||
|
@ -132,11 +135,24 @@ public class LanguageUtils {
|
|||
return bp;
|
||||
}
|
||||
|
||||
public int importFromTranslations(Element resource, Set<TranslationUnit> translations) {
|
||||
return importFromTranslations(null, resource, translations);
|
||||
|
||||
public int importFromTranslations(Element resource, List<TranslationUnit> translations) {
|
||||
return importFromTranslations(null, resource, translations, new HashSet<>());
|
||||
}
|
||||
|
||||
private int importFromTranslations(Element parent, Element element, Set<TranslationUnit> translations) {
|
||||
public int importFromTranslations(Element resource, List<TranslationUnit> translations, List<ValidationMessage> messages) {
|
||||
Set<TranslationUnit> usedUnits = new HashSet<>();
|
||||
int r = importFromTranslations(null, resource, translations, usedUnits);
|
||||
for (TranslationUnit t : translations) {
|
||||
if (!usedUnits.contains(t)) {
|
||||
messages.add(new ValidationMessage(Source.Publisher, IssueType.INFORMATIONAL, t.getId(), "Unused '"+t.getLanguage()+"' translation '"+t.getSrcText()+"' -> '"+t.getTgtText()+"'", IssueSeverity.INFORMATION));
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
private int importFromTranslations(Element parent, Element element, List<TranslationUnit> translations, Set<TranslationUnit> usedUnits) {
|
||||
int t = 0;
|
||||
if (element.isPrimitive() && isTranslatable(element)) {
|
||||
String base = element.primitiveValue();
|
||||
|
@ -146,13 +162,14 @@ public class LanguageUtils {
|
|||
t++;
|
||||
if (!handleAsSpecial(parent, element, translation)) {
|
||||
element.setTranslation(translation.getLanguage(), translation.getTgtText());
|
||||
usedUnits.add(translation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Element c: element.getChildren()) {
|
||||
if (!c.getName().equals("designation")) {
|
||||
t = t + importFromTranslations(element, c, translations);
|
||||
t = t + importFromTranslations(element, c, translations, usedUnits);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
|
@ -193,7 +210,7 @@ public class LanguageUtils {
|
|||
return true;
|
||||
}
|
||||
|
||||
private Set<TranslationUnit> findTranslations(String path, String src, Set<TranslationUnit> translations) {
|
||||
private Set<TranslationUnit> findTranslations(String path, String src, List<TranslationUnit> translations) {
|
||||
Set<TranslationUnit> res = new HashSet<>();
|
||||
for (TranslationUnit translation : translations) {
|
||||
if (path.equals(translation.getId()) && src.equals(translation.getSrcText())) {
|
||||
|
@ -294,7 +311,7 @@ public class LanguageUtils {
|
|||
}
|
||||
|
||||
public static boolean handlesAsElement(Element element) {
|
||||
return false; // for now...
|
||||
return true; // for now...
|
||||
}
|
||||
|
||||
public static List<TranslationUnit> generateTranslations(Resource res, String lang) {
|
||||
|
@ -334,4 +351,52 @@ public class LanguageUtils {
|
|||
return cd.getDefinition();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static List<TranslationUnit> generateTranslations(Element e, String lang) {
|
||||
List<TranslationUnit> list = new ArrayList<>();
|
||||
generateTranslations(e, lang, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void generateTranslations(Element e, String lang, List<TranslationUnit> list) {
|
||||
if (e.getProperty().isTranslatable()) {
|
||||
String id = e.getProperty().getDefinition().getPath();
|
||||
String context = e.getProperty().getDefinition().getDefinition();
|
||||
String src = e.primitiveValue();
|
||||
String tgt = getTranslation(e, lang);
|
||||
list.add(new TranslationUnit(lang, id, context, src, tgt));
|
||||
}
|
||||
if (e.hasChildren()) {
|
||||
for (Element c : e.getChildren()) {
|
||||
generateTranslations(c, lang, list);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static String getTranslation(Element e, String lang) {
|
||||
if (!e.hasChildren()) {
|
||||
return null;
|
||||
}
|
||||
for (Element ext : e.getChildren()) {
|
||||
if ("Extension".equals(ext.fhirType()) && "http://hl7.org/fhir/StructureDefinition/translation".equals(ext.getNamedChildValue("url"))) {
|
||||
String l = null;
|
||||
String v = null;
|
||||
for (Element subExt : ext.getChildren()) {
|
||||
if ("Extension".equals(subExt.fhirType()) && "lang".equals(subExt.getNamedChildValue("url"))) {
|
||||
lang = subExt.getNamedChildValue("value");
|
||||
}
|
||||
if ("Extension".equals(subExt.fhirType()) && "lang".equals(subExt.getNamedChildValue("content"))) {
|
||||
v = subExt.getNamedChildValue("value");
|
||||
}
|
||||
}
|
||||
if (lang.equals(l)) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -641,14 +641,32 @@ public class Property {
|
|||
|
||||
public boolean isTranslatable() {
|
||||
boolean ok = ToolingExtensions.readBoolExtension(definition, ToolingExtensions.EXT_TRANSLATABLE);
|
||||
if (!ok && !Utilities.existsInList(definition.getBase().getPath(), "Reference.reference", "Coding.version", "Identifier.value", "SampledData.offsets", "SampledData.data", "ContactPoint.value")) {
|
||||
if (!ok && !definition.getPath().endsWith(".id") && !Utilities.existsInList(definition.getBase().getPath(), "Resource.id", "Reference.reference", "Coding.version", "Identifier.value", "SampledData.offsets", "SampledData.data", "ContactPoint.value")) {
|
||||
String t = getType();
|
||||
ok = Utilities.existsInList(t, "string", "markdown");
|
||||
}
|
||||
if (Utilities.existsInList(pathForElement(getStructure().getType(), getDefinition().getBase().getPath()), "CanonicalResource.version")) {
|
||||
return false;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
private String pathForElement(String type, String path) {
|
||||
// special case support for metadata elements prior to R5:
|
||||
if (utils.getCanonicalResourceNames().contains(type)) {
|
||||
String fp = path.replace(type+".", "CanonicalResource.");
|
||||
if (Utilities.existsInList(fp,
|
||||
"CanonicalResource.url", "CanonicalResource.identifier", "CanonicalResource.version", "CanonicalResource.name",
|
||||
"CanonicalResource.title", "CanonicalResource.status", "CanonicalResource.experimental", "CanonicalResource.date",
|
||||
"CanonicalResource.publisher", "CanonicalResource.contact", "CanonicalResource.description", "CanonicalResource.useContext",
|
||||
"CanonicalResource.jurisdiction")) {
|
||||
return fp;
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
public String getXmlTypeName() {
|
||||
TypeRefComponent tr = type;
|
||||
if (tr == null) {
|
||||
|
@ -678,4 +696,14 @@ public class Property {
|
|||
}
|
||||
|
||||
|
||||
public boolean canBeType(String type) {
|
||||
for (TypeRefComponent tr : getDefinition().getType()) {
|
||||
if (type.equals(tr.getWorkingCode())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -167,13 +167,22 @@ public class PoGetTextProducer extends LanguageFileProducer {
|
|||
if (tu.getContext1() != null) {
|
||||
ln(po, "#. "+tu.getContext1());
|
||||
}
|
||||
ln(po, "msgid \""+tu.getSrcText()+"\"");
|
||||
ln(po, "msgstr \""+(tu.getTgtText() == null ? "" : tu.getTgtText())+"\"");
|
||||
ln(po, "msgid \""+stripEoln(tu.getSrcText())+"\"");
|
||||
ln(po, "msgstr \""+(tu.getTgtText() == null ? "" : stripEoln(tu.getTgtText()))+"\"");
|
||||
ln(po, "");
|
||||
}
|
||||
TextFile.stringToFile(po.toString(), Utilities.path(getFolder(), filename));
|
||||
}
|
||||
|
||||
private String stripEoln(String s) {
|
||||
s = s.replace("\r\n\r\n", " ").replace("\n\n", " ").replace("\r\r", " ");
|
||||
s = s.replace("\r\n", " ").replace("\n", " ").replace("\r", " ");
|
||||
// // yes, the double escaping is intentional here - it appears necessary
|
||||
// s = s.replace("\\r\\n\\r\\n", " ").replace("\\n\\n", " ").replace("\\r\\r", " ");
|
||||
// s = s.replace("\\r\\n", " ").replace("\\n", " ").replace("\\r", " ");
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue