static XMLNode*
pseudolocalize_xml_node(const XMLNode* source, const PseudolocalizeSettings* settings)
{
    if (source->Type() == XMLNode::TEXT) {
        return XMLNode::NewText(source->Position(), pseudolocalize_string(source->Text(), settings),
                                source->Pretty());
    } else {
        XMLNode* target;
        if (source->Namespace() == XLIFF_XMLNS && source->Name() == "g") {
            // XXX don't translate these
            target = XMLNode::NewElement(source->Position(), source->Namespace(),
                                         source->Name(), source->Attributes(), source->Pretty());
        } else {
            target = XMLNode::NewElement(source->Position(), source->Namespace(),
                                         source->Name(), source->Attributes(), source->Pretty());
        }

        const vector<XMLNode*>& children = source->Children();
        const size_t I = children.size();
        for (size_t i=0; i<I; i++) {
            target->EditChildren().push_back(pseudolocalize_xml_node(children[i], settings));
        }

        return target;
    }
}
示例#2
0
XMLNode*
resource_to_xmb_msg(const StringResource& res)
{
    // the msg element
    vector<XMLAttribute> attrs;
    string name = res.pos.file;
    name += ":";
    name += res.TypedID();
    attrs.push_back(XMLAttribute("", "name", name));
    attrs.push_back(XMLAttribute("", "desc", strip_newlines(res.comment)));
    attrs.push_back(XMLAttribute(XMLNS_XMLNS, "space", "preserve"));
    XMLNode* msg = XMLNode::NewElement(res.pos, "", "msg", attrs, XMLNode::EXACT);

    // the contents are in xliff/html, convert it to xliff
    int err = 0;
    XMLNode* value = res.value;
    string tag = value->Name();
    int phID = 0;
    for (vector<XMLNode*>::const_iterator it=value->Children().begin();
            it!=value->Children().end(); it++) {
        err |= convert_html_to_xliff(*it, tag, msg, &phID);
    }

    if (err != 0) {
        return NULL;
    }

    // and then convert that to xmb
    for (vector<XMLNode*>::iterator it=msg->EditChildren().begin();
            it!=msg->EditChildren().end(); it++) {
        err |= convert_xliff_to_ph(*it, &phID);
    }

    if (err == 0) {
        return msg;
    } else {
        return NULL;
    }
}
XMLNode*
XLIFFFile::ToXMLNode() const
{
    XMLNode* root;
    size_t N;

    // <xliff>
    {
        vector<XMLAttribute> attrs;
        XLIFF_NAMESPACES.AddToAttributes(&attrs);
        attrs.push_back(XMLAttribute(XLIFF_XMLNS, "version", "1.2"));
        root = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "xliff", attrs, XMLNode::PRETTY);
    }

    vector<TransUnit> groups;

    // <file>
    vector<File> files = m_files;
    sort(files.begin(), files.end());
    const size_t I = files.size();
    for (size_t i=0; i<I; i++) {
        const File& file = files[i];

        vector<XMLAttribute> fileAttrs;
        fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "datatype", "x-android-res"));
        fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "original", file.filename));

        struct timeval tv;
        struct timezone tz;
        gettimeofday(&tv, &tz);
        fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "date", trim_string(ctime(&tv.tv_sec))));

        fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "source-language", m_sourceConfig.locale));
        fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "target-language", m_targetConfig.locale));
        fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "build-num", m_currentVersion));

        XMLNode* fileNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "file", fileAttrs,
                                                XMLNode::PRETTY);
        root->EditChildren().push_back(fileNode);

        // <body>
        XMLNode* bodyNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "body",
                                                vector<XMLAttribute>(), XMLNode::PRETTY);
        fileNode->EditChildren().push_back(bodyNode);

        // <trans-unit>
        vector<TransUnit> transUnits = file.transUnits;
        sort(transUnits.begin(), transUnits.end(), compare_id);
        const size_t J = transUnits.size();
        for (size_t j=0; j<J; j++) {
            const TransUnit& transUnit = transUnits[j];

            vector<XMLAttribute> tuAttrs;

            // strings start with string:
            tuAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "id", transUnit.id));
            XMLNode* transUnitNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "trans-unit",
                                                         tuAttrs, XMLNode::PRETTY);
            bodyNode->EditChildren().push_back(transUnitNode);

            // <extradata>
            if (transUnit.source.comment != "") {
                vector<XMLAttribute> extradataAttrs;
                XMLNode* extraNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "extradata",
                                                            extradataAttrs, XMLNode::EXACT);
                transUnitNode->EditChildren().push_back(extraNode);
                extraNode->EditChildren().push_back(
                        XMLNode::NewText(GENERATED_POS, transUnit.source.comment,
                                         XMLNode::PRETTY));
            }

            // <source>
            if (transUnit.source.id != "") {
                transUnitNode->EditChildren().push_back(
                                    create_string_node(transUnit.source, "source"));
            }
            
            // <target>
            if (transUnit.target.id != "") {
                transUnitNode->EditChildren().push_back(
                                    create_string_node(transUnit.target, "target"));
            }

            // <alt-trans>
            if (transUnit.altSource.id != "" || transUnit.altTarget.id != ""
                    || transUnit.rejectComment != "") {
                vector<XMLAttribute> altTransAttrs;
                XMLNode* altTransNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "alt-trans",
                                                            altTransAttrs, XMLNode::PRETTY);
                transUnitNode->EditChildren().push_back(altTransNode);

                // <extradata>
                if (transUnit.rejectComment != "") {
                    vector<XMLAttribute> extradataAttrs;
                    XMLNode* extraNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS,
                                                                "extradata", extradataAttrs,
                                                                XMLNode::EXACT);
                    altTransNode->EditChildren().push_back(extraNode);
                    extraNode->EditChildren().push_back(
                            XMLNode::NewText(GENERATED_POS, transUnit.rejectComment,
                                             XMLNode::PRETTY));
                }
                
                // <source>
                if (transUnit.altSource.id != "") {
                    altTransNode->EditChildren().push_back(
                                        create_string_node(transUnit.altSource, "source"));
                }
                
                // <target>
                if (transUnit.altTarget.id != "") {
                    altTransNode->EditChildren().push_back(
                                        create_string_node(transUnit.altTarget, "target"));
                }
            }
            
        }
    }

    return root;
}
int
convert_html_to_xliff(const XMLNode* original, const string& name, XMLNode* addTo, int* phID)
{
    int err = 0;
    if (original->Type() == XMLNode::TEXT) {
        addTo->EditChildren().push_back(original->Clone());
        return 0;
    } else {
        string ctype;
        if (original->Namespace() == "") {
            if (original->Name() == "b") {
                ctype = "bold";
            }
            else if (original->Name() == "i") {
                ctype = "italic";
            }
            else if (original->Name() == "u") {
                ctype = "underline";
            }
        }
        if (ctype != "") {
            vector<XMLAttribute> attrs;
            attrs.push_back(XMLAttribute(XLIFF_XMLNS, "ctype", ctype));
            XMLNode* copy = XMLNode::NewElement(original->Position(), XLIFF_XMLNS, "g",
                                                attrs, XMLNode::EXACT);

            const vector<XMLNode*>& children = original->Children();
            size_t I = children.size();
            for (size_t i=0; i<I; i++) {
                err |= convert_html_to_xliff(children[i], name, copy, phID);
            }
            return err;
        }
        else {
            if (original->Namespace() == XLIFF_XMLNS) {
                addTo->EditChildren().push_back(original->Clone());
                return 0;
            } else {
                if (original->Namespace() == "") {
                    // flatten out the tag into ph tags -- but only if there is no namespace
                    // that's still unsupported because propagating the xmlns attribute is hard.
                    vector<XMLAttribute> attrs;
                    char idStr[30];
                    (*phID)++;
                    sprintf(idStr, "id-%d", *phID);
                    attrs.push_back(XMLAttribute(XLIFF_XMLNS, "id", idStr));

                    if (original->Children().size() == 0) {
                        XMLNode* ph = XMLNode::NewElement(original->Position(), XLIFF_XMLNS,
                                "ph", attrs, XMLNode::EXACT);
                        ph->EditChildren().push_back(
                                XMLNode::NewText(original->Position(),
                                    original->ToString(XLIFF_NAMESPACES),
                                    XMLNode::EXACT));
                        addTo->EditChildren().push_back(ph);
                    } else {
                        XMLNode* begin = XMLNode::NewElement(original->Position(), XLIFF_XMLNS,
                                "bpt", attrs, XMLNode::EXACT);
                        begin->EditChildren().push_back(
                                XMLNode::NewText(original->Position(),
                                    original->OpenTagToString(XLIFF_NAMESPACES, XMLNode::EXACT),
                                    XMLNode::EXACT));
                        XMLNode* end = XMLNode::NewElement(original->Position(), XLIFF_XMLNS,
                                "ept", attrs, XMLNode::EXACT);
                        string endText = "</";
                            endText += original->Name();
                            endText += ">";
                        end->EditChildren().push_back(XMLNode::NewText(original->Position(),
                                endText, XMLNode::EXACT));

                        addTo->EditChildren().push_back(begin);

                        const vector<XMLNode*>& children = original->Children();
                        size_t I = children.size();
                        for (size_t i=0; i<I; i++) {
                            err |= convert_html_to_xliff(children[i], name, addTo, phID);
                        }

                        addTo->EditChildren().push_back(end);
                    }
                    return err;
                } else {
                    original->Position().Error("invalid <%s> element in <%s> tag\n",
                                                original->Name().c_str(), name.c_str());
                    return 1;
                }
            }
        }
    }
}
static int
create_string_node_test()
{
    int err = 0;
    StringResource res;
    vector<XMLAttribute> attrs;
    res.value = XMLNode::NewElement(GENERATED_POS, "", "something", attrs, XMLNode::EXACT);
    res.value->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, " begin ", XMLNode::EXACT));

    XMLNode* child;

    child = add_html_tag(res.value, "b");
    child->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, "b", XMLNode::EXACT));

    child = add_html_tag(res.value, "i");
    child->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, "i", XMLNode::EXACT));

    child = add_html_tag(child, "b");
    child->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, "b", XMLNode::EXACT));

    child = add_html_tag(res.value, "u");
    child->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, "u", XMLNode::EXACT));


    res.value->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, " end ", XMLNode::EXACT));

    XMLNode* xliff = create_string_node(res, "blah");

    string oldString = res.value->ToString(XLIFF_NAMESPACES);
    string newString = xliff->ToString(XLIFF_NAMESPACES);

    if (false) {
        printf("OLD=\"%s\"\n", oldString.c_str());
        printf("NEW=\"%s\"\n", newString.c_str());
    }

    const char* const EXPECTED_OLD
                    = "<something> begin <b>b</b><i>i<b>b</b></i><u>u</u> end </something>";
    if (oldString != EXPECTED_OLD) {
        fprintf(stderr, "oldString mismatch:\n");
        fprintf(stderr, "    expected='%s'\n", EXPECTED_OLD);
        fprintf(stderr, "      actual='%s'\n", oldString.c_str());
        err |= 1;
    }

    const char* const EXPECTED_NEW
                    = "<blah xml:space=\"preserve\"> begin <g ctype=\"bold\">b</g>"
                    "<g ctype=\"italic\">i<g ctype=\"bold\">b</g></g><g ctype=\"underline\">u</g>"
                    " end </blah>";
    if (newString != EXPECTED_NEW) {
        fprintf(stderr, "newString mismatch:\n");
        fprintf(stderr, "    expected='%s'\n", EXPECTED_NEW);
        fprintf(stderr, "      actual='%s'\n", newString.c_str());
        err |= 1;
    }

    if (err != 0) {
        fprintf(stderr, "create_string_node_test failed\n");
    }
    return err;
}
示例#6
0
int
do_xlb_export(const string& outfile, const vector<string>& resFiles)
{
    int err = 0;

    size_t totalFileCount = resFiles.size();

    Configuration english;
        english.locale = "en_US";

    set<StringResource> allResources;

    const size_t J = resFiles.size();
    for (size_t j=0; j<J; j++) {
        string resFile = resFiles[j];

        ValuesFile* valuesFile = get_local_values_file(resFile, english, CURRENT_VERSION, "", true);
        if (valuesFile != NULL) {
            set<StringResource> resources = valuesFile->GetStrings();
            allResources.insert(resources.begin(), resources.end());
        } else {
            fprintf(stderr, "error reading file %s\n", resFile.c_str());
        }

        delete valuesFile;
    }

    // Construct the XLB xml
    vector<XMLAttribute> attrs;
    attrs.push_back(XMLAttribute("", "locale", "en"));
    XMLNode* localizationbundle = XMLNode::NewElement(GENERATED_POS, "", "localizationbundle",
            attrs, XMLNode::PRETTY);

    for (set<StringResource>::iterator it=allResources.begin(); it!=allResources.end(); it++) {
        XMLNode* msg = resource_to_xmb_msg(*it);
        if (msg) {
            localizationbundle->EditChildren().push_back(msg);
        } else {
            err = 1;
        }
    }

#if 0
    for (set<string>::iterator it=g_tags.begin(); it!=g_tags.end(); it++) {
        printf("tag: %s\n", it->c_str());
    }
    printf("err=%d\n", err);
#endif
    if (err == 0) {
        FILE* f = fopen(outfile.c_str(), "wb");
        if (f == NULL) {
            fprintf(stderr, "can't open outputfile: %s\n", outfile.c_str());
            return 1;
        }
        fprintf(f, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        fprintf(f, "%s\n", localizationbundle->ToString(NS_MAP).c_str());
        fclose(f);
    }

    return err;
}