| #include "xmb.h" |
| |
| #include "file_utils.h" |
| #include "localize.h" |
| #include "ValuesFile.h" |
| #include "XMLHandler.h" |
| #include "XLIFFFile.h" |
| |
| #include <map> |
| |
| using namespace std; |
| |
| const char *const NS_MAP[] = { |
| "xml", XMLNS_XMLNS, |
| NULL, NULL |
| }; |
| |
| set<string> g_tags; |
| |
| static string |
| strip_newlines(const string& str) |
| { |
| string res; |
| const size_t N = str.length(); |
| for (size_t i=0; i<N; i++) { |
| char c = str[i]; |
| if (c != '\n' && c != '\r') { |
| res += c; |
| } else { |
| res += ' '; |
| } |
| } |
| return res; |
| } |
| |
| static int |
| rename_id_attribute(XMLNode* node) |
| { |
| vector<XMLAttribute>& attrs = node->EditAttributes(); |
| const size_t I = attrs.size(); |
| for (size_t i=0; i<I; i++) { |
| XMLAttribute attr = attrs[i]; |
| if (attr.name == "id") { |
| attr.name = "name"; |
| attrs.erase(attrs.begin()+i); |
| attrs.push_back(attr); |
| return 0; |
| } |
| } |
| return 1; |
| } |
| |
| static int |
| convert_xliff_to_ph(XMLNode* node, int* phID) |
| { |
| int err = 0; |
| if (node->Type() == XMLNode::ELEMENT) { |
| if (node->Namespace() == XLIFF_XMLNS) { |
| g_tags.insert(node->Name()); |
| node->SetName("", "ph"); |
| |
| err = rename_id_attribute(node); |
| if (err != 0) { |
| char name[30]; |
| (*phID)++; |
| sprintf(name, "id-%d", *phID); |
| node->EditAttributes().push_back(XMLAttribute("", "name", name)); |
| err = 0; |
| } |
| } |
| vector<XMLNode*>& children = node->EditChildren(); |
| const size_t I = children.size(); |
| for (size_t i=0; i<I; i++) { |
| err |= convert_xliff_to_ph(children[i], phID); |
| } |
| } |
| return err; |
| } |
| |
| 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; |
| } |
| } |
| |
| 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; |
| } |
| |