use of com.google.template.soy.msgs.restricted.SoyMsgPart in project closure-templates by google.
the class MsgFuncGenerator method processMsgPartsHelper.
/**
* Private helper to build valid Python string for a list of {@link SoyMsgPart}s.
*
* <p>It only processes {@link SoyMsgRawTextPart} and {@link SoyMsgPlaceholderPart} and ignores
* others, because we didn't generate a direct string for plural and select nodes.
*
* <p>For {@link SoyMsgRawTextPart}, it appends the raw text and applies necessary escaping; For
* {@link SoyMsgPlaceholderPart}, it turns the placeholder's variable name into Python replace
* format.
*
* @param parts The SoyMsgPart parts to convert.
* @param escaper A Function which provides escaping for raw text.
* @return A String representing all the {@code parts} in Python.
*/
private static String processMsgPartsHelper(ImmutableList<SoyMsgPart> parts, Function<String, String> escaper) {
StringBuilder rawMsgTextSb = new StringBuilder();
for (SoyMsgPart part : parts) {
if (part instanceof SoyMsgRawTextPart) {
rawMsgTextSb.append(escaper.apply(((SoyMsgRawTextPart) part).getRawText()));
}
if (part instanceof SoyMsgPlaceholderPart) {
String phName = ((SoyMsgPlaceholderPart) part).getPlaceholderName();
rawMsgTextSb.append("{" + phName + "}");
}
}
return rawMsgTextSb.toString();
}
use of com.google.template.soy.msgs.restricted.SoyMsgPart in project closure-templates by google.
the class InsertMsgsVisitor method buildReplacementNodesFromTranslation.
/**
* Private helper for visitMsgFallbackGroupNode() to build the list of replacement nodes for a
* message from its translation.
*/
private void buildReplacementNodesFromTranslation(MsgNode msg, SoyMsg translation) {
currReplacementNodes = Lists.newArrayList();
for (SoyMsgPart msgPart : translation.getParts()) {
if (msgPart instanceof SoyMsgRawTextPart) {
// Append a new RawTextNode to the currReplacementNodes list.
String rawText = ((SoyMsgRawTextPart) msgPart).getRawText();
currReplacementNodes.add(new RawTextNode(nodeIdGen.genId(), rawText, msg.getSourceLocation()));
} else if (msgPart instanceof SoyMsgPlaceholderPart) {
// Get the representative placeholder node and iterate through its contents.
String placeholderName = ((SoyMsgPlaceholderPart) msgPart).getPlaceholderName();
MsgPlaceholderNode placeholderNode = msg.getRepPlaceholderNode(placeholderName);
for (StandaloneNode contentNode : placeholderNode.getChildren()) {
// simply add the content node to the currReplacementNodes list being built.
if (contentNode instanceof MsgHtmlTagNode) {
currReplacementNodes.addAll(((MsgHtmlTagNode) contentNode).getChildren());
} else {
currReplacementNodes.add(contentNode);
}
}
} else {
throw new AssertionError();
}
}
}
use of com.google.template.soy.msgs.restricted.SoyMsgPart in project closure-templates by google.
the class IcuSyntaxUtils method convertMsgPartsHelper.
/**
* Private helper for {@code convertMsgPartsToEmbeddedIcuSyntax()} to convert msg parts.
*
* @param newMsgPartsBuilder The new msg parts being built.
* @param currRawTextSb The collector for the current raw text, which hasn't yet been turned into
* a SoyMsgRawTextPart and added to newMsgPartsBuilder because it might not be complete.
* @param origMsgParts The msg parts to convert.
* @param isInPlrselPart Whether we're currently within a plural/select part's subtree.
*/
private static void convertMsgPartsHelper(ImmutableList.Builder<SoyMsgPart> newMsgPartsBuilder, StringBuilder currRawTextSb, List<SoyMsgPart> origMsgParts, boolean isInPlrselPart) {
for (SoyMsgPart origMsgPart : origMsgParts) {
if (origMsgPart instanceof SoyMsgRawTextPart) {
String rawText = ((SoyMsgRawTextPart) origMsgPart).getRawText();
if (isInPlrselPart) {
rawText = icuEscape(rawText);
}
currRawTextSb.append(rawText);
} else if (origMsgPart instanceof SoyMsgPlaceholderPart) {
// a msg part for it and clear the collector.
if (currRawTextSb.length() > 0) {
newMsgPartsBuilder.add(SoyMsgRawTextPart.of(currRawTextSb.toString()));
currRawTextSb.setLength(0);
}
// Reuse the msg part for the placeholder since it's immutable.
newMsgPartsBuilder.add(origMsgPart);
} else if (origMsgPart instanceof SoyMsgPluralRemainderPart) {
currRawTextSb.append(getPluralRemainderString());
} else if (origMsgPart instanceof SoyMsgPluralPart) {
convertPluralPartHelper(newMsgPartsBuilder, currRawTextSb, (SoyMsgPluralPart) origMsgPart);
} else if (origMsgPart instanceof SoyMsgSelectPart) {
convertSelectPartHelper(newMsgPartsBuilder, currRawTextSb, (SoyMsgSelectPart) origMsgPart);
}
}
}
use of com.google.template.soy.msgs.restricted.SoyMsgPart in project closure-templates by google.
the class XliffGenerator method generateXliff.
/**
* Generates the output XLIFF file content for a given SoyMsgBundle.
*
* @param msgBundle The SoyMsgBundle to process.
* @param sourceLocaleString The source language/locale string of the messages.
* @param targetLocaleString The target language/locale string of the messages (optional). If
* specified, the resulting XLIFF file will specify this target language and will contain
* empty 'target' tags. If not specified, the resulting XLIFF file will not contain target
* language and will not contain 'target' tags.
* @return The generated XLIFF file content.
*/
static CharSequence generateXliff(SoyMsgBundle msgBundle, String sourceLocaleString, @Nullable String targetLocaleString) {
Escaper attributeEscaper = XmlEscapers.xmlAttributeEscaper();
Escaper contentEscaper = XmlEscapers.xmlContentEscaper();
boolean hasTarget = targetLocaleString != null && targetLocaleString.length() > 0;
IndentedLinesBuilder ilb = new IndentedLinesBuilder(2);
ilb.appendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
ilb.appendLine("<xliff version=\"1.2\" xmlns=\"urn:oasis:names:tc:xliff:document:1.2\">");
ilb.increaseIndent();
ilb.appendLineStart("<file original=\"SoyMsgBundle\" datatype=\"x-soy-msg-bundle\"", " xml:space=\"preserve\"", " source-language=\"", attributeEscaper.escape(sourceLocaleString), "\"");
if (hasTarget) {
ilb.appendParts(" target-language=\"", attributeEscaper.escape(targetLocaleString), "\"");
}
ilb.appendLineEnd(">");
ilb.increaseIndent();
ilb.appendLine("<body>");
ilb.increaseIndent();
for (SoyMsg msg : msgBundle) {
// Begin 'trans-unit'.
ilb.appendLineStart("<trans-unit id=\"", Long.toString(msg.getId()), "\"");
String contentType = msg.getContentType();
if (contentType != null && contentType.length() > 0) {
String xliffDatatype = CONTENT_TYPE_TO_XLIFF_DATATYPE_MAP.get(contentType);
if (xliffDatatype == null) {
// just use the contentType string
xliffDatatype = contentType;
}
ilb.appendParts(" datatype=\"", attributeEscaper.escape(xliffDatatype), "\"");
}
ilb.appendLineEnd(">");
ilb.increaseIndent();
// Source.
ilb.appendLineStart("<source>");
for (SoyMsgPart msgPart : msg.getParts()) {
if (msgPart instanceof SoyMsgRawTextPart) {
String rawText = ((SoyMsgRawTextPart) msgPart).getRawText();
ilb.append(contentEscaper.escape(rawText));
} else if (msgPart instanceof SoyMsgPlaceholderPart) {
SoyMsgPlaceholderPart placeholder = (SoyMsgPlaceholderPart) msgPart;
ilb.appendParts("<x id=\"", attributeEscaper.escape(placeholder.getPlaceholderName()), "\"" + // convention so we add it in the hope that tools will support it anyway.
(placeholder.getPlaceholderExample() != null ? " example=\"" + attributeEscaper.escape(placeholder.getPlaceholderExample()) + "\"" : "") + "/>");
} else {
throw new RuntimeException("Xliff doesn't support plurals or genders. " + msg.getSourceLocations());
}
}
ilb.appendLineEnd("</source>");
// Target.
if (hasTarget) {
ilb.appendLine("<target/>");
}
// Description and meaning.
String desc = msg.getDesc();
if (desc != null && desc.length() > 0) {
ilb.appendLine("<note priority=\"1\" from=\"description\">", contentEscaper.escape(desc), "</note>");
}
String meaning = msg.getMeaning();
if (meaning != null && meaning.length() > 0) {
ilb.appendLine("<note priority=\"1\" from=\"meaning\">", contentEscaper.escape(meaning), "</note>");
}
// End 'trans-unit'.
ilb.decreaseIndent();
ilb.appendLine("</trans-unit>");
}
ilb.decreaseIndent();
ilb.appendLine("</body>");
ilb.decreaseIndent();
ilb.appendLine("</file>");
ilb.decreaseIndent();
ilb.appendLine("</xliff>");
return ilb;
}
use of com.google.template.soy.msgs.restricted.SoyMsgPart in project closure-templates by google.
the class RenderVisitorAssistantForMsgs method renderMsgFromTranslation.
/**
* Private helper for visitMsgFallbackGroupNode() to render a message from its translation.
*/
private void renderMsgFromTranslation(MsgNode msg, ImmutableList<SoyMsgPart> msgParts, @Nullable ULocale locale) {
SoyMsgPart firstPart = msgParts.get(0);
if (firstPart instanceof SoyMsgPluralPart) {
new PlrselMsgPartsVisitor(msg, locale).visitPart((SoyMsgPluralPart) firstPart);
} else if (firstPart instanceof SoyMsgSelectPart) {
new PlrselMsgPartsVisitor(msg, locale).visitPart((SoyMsgSelectPart) firstPart);
} else {
for (SoyMsgPart msgPart : msgParts) {
if (msgPart instanceof SoyMsgRawTextPart) {
RenderVisitor.append(master.getCurrOutputBufForUseByAssistants(), ((SoyMsgRawTextPart) msgPart).getRawText());
} else if (msgPart instanceof SoyMsgPlaceholderPart) {
String placeholderName = ((SoyMsgPlaceholderPart) msgPart).getPlaceholderName();
visit(msg.getRepPlaceholderNode(placeholderName));
} else {
throw new AssertionError();
}
}
}
}
Aggregations