diff options
author | Andras Timar <atimar@suse.com> | 2012-11-27 14:12:22 +0100 |
---|---|---|
committer | Andras Timar <atimar@suse.com> | 2012-11-27 14:35:53 +0100 |
commit | 869dab55c133a80096e516a5d2b0f0c4d573fab6 (patch) | |
tree | 472f9c3681ea705ecdcfaa1d31fd28568102cb10 /l10ntools | |
parent | a511a4f2a9e911ba2a8cd8bc452e1fc80d9462d8 (diff) |
add new tool "stringex" to extract/merge strings from/to android UI
Change-Id: I8210957cedf911418044da340642cf97396f3e14
Diffstat (limited to 'l10ntools')
-rw-r--r-- | l10ntools/Executable_stringex.mk | 37 | ||||
-rw-r--r-- | l10ntools/Module_l10ntools.mk | 1 | ||||
-rw-r--r-- | l10ntools/inc/stringmerge.hxx | 42 | ||||
-rw-r--r-- | l10ntools/source/localize.cxx | 5 | ||||
-rw-r--r-- | l10ntools/source/stringex.cxx | 59 | ||||
-rw-r--r-- | l10ntools/source/stringmerge.cxx | 179 |
6 files changed, 322 insertions, 1 deletions
diff --git a/l10ntools/Executable_stringex.mk b/l10ntools/Executable_stringex.mk new file mode 100644 index 000000000000..f42b36c79acf --- /dev/null +++ b/l10ntools/Executable_stringex.mk @@ -0,0 +1,37 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + + +$(eval $(call gb_Executable_Executable,stringex)) + +$(eval $(call gb_Executable_set_include,stringex,\ + -I$(SRCDIR)/l10ntools/inc \ + $$(INCLUDE) \ +)) + +$(eval $(call gb_Executable_use_libraries,stringex,\ + sal \ +)) + +$(eval $(call gb_Executable_use_static_libraries,stringex,\ + transex \ +)) + +$(eval $(call gb_Executable_add_exception_objects,stringex,\ + l10ntools/source/stringmerge \ + l10ntools/source/stringex \ +)) + +$(eval $(call gb_Executable_use_externals,stringex,\ + libxml2 \ + icuuc \ + $(if $(filter MSC,$(COM)),icuin,icui18n) \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/l10ntools/Module_l10ntools.mk b/l10ntools/Module_l10ntools.mk index 4b2b0f6d970d..02b88dc276e1 100644 --- a/l10ntools/Module_l10ntools.mk +++ b/l10ntools/Module_l10ntools.mk @@ -39,6 +39,7 @@ $(eval $(call gb_Module_add_targets,l10ntools,\ Executable_renewpo \ Executable_propex \ Executable_treex \ + Executable_stringex \ StaticLibrary_transex \ Package_inc \ Package_scripts \ diff --git a/l10ntools/inc/stringmerge.hxx b/l10ntools/inc/stringmerge.hxx new file mode 100644 index 000000000000..01a7b9b719cd --- /dev/null +++ b/l10ntools/inc/stringmerge.hxx @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef _STRINGMERGE_INCLUDED +#define _STRINGMERGE_INCLUDED + +#include <libxml/tree.h> +#include <rtl/string.hxx> +#include <vector> + +/** Class for Android strings.xml localization + + Parse strings.xml files, extract translatable strings + and merge translated strings. +*/ +class StringParser +{ +private: + xmlDocPtr m_pSource; + OString m_sLang; + bool m_bIsInitialized; + +public: + StringParser( + const OString& rInputFile, const OString& rLang ); + ~StringParser(); + + bool isInitialized() const { return m_bIsInitialized; } + void Extract( + const OString& rSDFFile, const OString& rPrj, const OString& rRoot ); + void Merge( + const OString &rMergeSrc, const OString &rDestinationFile ); +}; + +#endif //_STRINGMERGE_INCLUDED +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/l10ntools/source/localize.cxx b/l10ntools/source/localize.cxx index eb284eaaa8d4..07a240ceb523 100644 --- a/l10ntools/source/localize.cxx +++ b/l10ntools/source/localize.cxx @@ -131,6 +131,7 @@ bool passesPositiveList(OUString const & url) { { RTL_CONSTASCII_STRINGPARAM( "/dbaccess/source/ui/inc/toolbox_tmpl.hrc") }, { RTL_CONSTASCII_STRINGPARAM("/description.xml") }, + { RTL_CONSTASCII_STRINGPARAM("/android/sdremote/res/values/strings.xml") }, { RTL_CONSTASCII_STRINGPARAM("/offmgr/inc/offmenu_tmpl.hrc") }, { RTL_CONSTASCII_STRINGPARAM( "/offmgr/source/offapp/intro/intro_tmpl.hrc") }, @@ -305,7 +306,8 @@ void handleFile( { RTL_CONSTASCII_STRINGPARAM(".ulf"), "ulfex", false }, { RTL_CONSTASCII_STRINGPARAM(".xcu"), "cfgex", false }, { RTL_CONSTASCII_STRINGPARAM(".xrm"), "xrmex", false }, - { RTL_CONSTASCII_STRINGPARAM(".xml"), "xrmex", true }, + { RTL_CONSTASCII_STRINGPARAM("description.xml"), "xrmex", true }, + { RTL_CONSTASCII_STRINGPARAM("strings.xml"), "stringex", true }, { RTL_CONSTASCII_STRINGPARAM(".xhp"), "helpex", false }, { RTL_CONSTASCII_STRINGPARAM(".properties"), "propex", false }, { RTL_CONSTASCII_STRINGPARAM(".ui"), "uiex", false }, @@ -328,6 +330,7 @@ void handleFile( bool includeProject(OString const & project) { static OString projects[] = { "accessibility", + "android", "avmedia", "basctl", "basic", diff --git a/l10ntools/source/stringex.cxx b/l10ntools/source/stringex.cxx new file mode 100644 index 000000000000..ed2a935829c6 --- /dev/null +++ b/l10ntools/source/stringex.cxx @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <iostream> +#include "sal/main.h" + +#include "export.hxx" +#include "stringmerge.hxx" + +void WriteUsage() +{ + std::cout + << "Syntax: stringex [-p Prj] [-r Root] -i FileIn -o FileOut" + << " [-m DataBase] [-l l1,l2,...]\n" + << " Prj: Project\n" + << " Root: Path to project root (../.. etc.)\n" + << " FileIn: Source files (strings.xml)\n" + << " FileOut: Destination file (*.*)\n" + << " DataBase: Mergedata (*.po)\n" + << " -l: Restrict the handled languages; l1, l2, ... are elements of" + << " (de, en-US, ...)\n"; +} + + +SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) +{ + HandledArgs aArgs; + if( !Export::handleArguments(argc, argv, aArgs) ) + { + WriteUsage(); + return 1; + } + + StringParser aParser(aArgs.m_sInputFile, Export::sLanguages); + if( !aParser.isInitialized() ) + { + return 1; + } + + if( aArgs.m_bMergeMode || aArgs.m_sPrj.isEmpty() ) + { + aParser.Merge( + aArgs.m_sMergeSrc, aArgs.m_sOutputFile ); + } + else + { + aParser.Extract( + aArgs.m_sOutputFile, aArgs.m_sPrj, aArgs.m_sPrjRoot ); + } + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/l10ntools/source/stringmerge.cxx b/l10ntools/source/stringmerge.cxx new file mode 100644 index 000000000000..71909d9dbe72 --- /dev/null +++ b/l10ntools/source/stringmerge.cxx @@ -0,0 +1,179 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <iostream> +#include <fstream> +#include <cassert> +#include <cstring> + +#include <libxml/tree.h> +#include <libxml/parser.h> +#include <libxml/xmlmemory.h> +#include <libxml/xmlstring.h> + +#include "export.hxx" +#include "common.hxx" +#include "stringmerge.hxx" + + +namespace +{ + //Write out an sdf line + static void lcl_WriteSDF( + std::ofstream &aSDFStream, const OString& rText, const OString& rPrj, + const OString& rActFileName, const OString& rID, const OString& rType ) + { + OString sOutput( rPrj ); sOutput += "\t"; + sOutput += rActFileName; + sOutput += "\t0\t"; + sOutput += rType; sOutput += "\t"; + sOutput += rID; sOutput += "\t\t\t\t0\ten-US\t"; + sOutput += rText; sOutput += "\t\t\t\t"; + aSDFStream << sOutput.getStr() << std::endl; + } + + //Convert xmlChar* to OString + static OString lcl_xmlStrToOString( const xmlChar* pString ) + { + xmlChar* pTemp = xmlStrdup( pString ); + OString sResult = + static_cast<OString>(reinterpret_cast<sal_Char*>( pTemp )); + xmlFree( pTemp ); + return sResult; + } +} + +//Parse strings.xml file +StringParser::StringParser( + const OString& rInputFile, const OString& rLang ) + : m_pSource( 0 ) + , m_sLang( rLang ) + , m_bIsInitialized( false ) +{ + m_pSource = xmlParseFile( rInputFile.getStr() ); + if ( !m_pSource ) { + std::cerr + << "Stringx error: Cannot open source file: " + << rInputFile.getStr() << std::endl; + return; + } + if( !m_pSource->name ) + { + m_pSource->name = new char[strlen(rInputFile.getStr())+1]; + strcpy( m_pSource->name, rInputFile.getStr() ); + } + m_bIsInitialized = true; +} + +StringParser::~StringParser() +{ +} + +//Extract strings form source file +void StringParser::Extract( + const OString& rSDFFile, const OString& rPrj, const OString& rRoot ) +{ + assert( m_bIsInitialized ); + std::ofstream aSDFStream( + rSDFFile.getStr(), std::ios_base::out | std::ios_base::trunc ); + if( !aSDFStream.is_open() ) + { + std::cerr + << "stringex error: Cannot open sdffile for extract: " + << rSDFFile.getStr() << std::endl; + return; + } + + xmlNodePtr pRootNode = xmlDocGetRootElement( m_pSource ); // <resource> + for( xmlNodePtr pCurrent = pRootNode->children->next; + pCurrent; pCurrent = pCurrent->next) + { + if (!xmlStrcmp(pCurrent->name, (const xmlChar*)("string"))) + { + xmlChar* pID = xmlGetProp(pCurrent, (const xmlChar*)("name")); + xmlChar* pText = xmlNodeGetContent(pCurrent); + lcl_WriteSDF( + aSDFStream, + lcl_xmlStrToOString( pText ), + rPrj, + common::pathnameToken( + m_pSource->name, rRoot.getStr()), + lcl_xmlStrToOString( pID ), + OString( "string" )); + + xmlFree( pID ); + xmlFree( pText ); + } + } + + xmlFreeDoc( m_pSource ); + xmlCleanupParser(); + aSDFStream.close(); + m_bIsInitialized = false; +} + +//Merge strings to localized strings.xml file +void StringParser::Merge( + const OString &rMergeSrc, const OString &rDestinationFile ) +{ + assert( m_bIsInitialized ); + + if( (m_sLang == "en-US") || (m_sLang == "qtz") ) + { + return; + } + + MergeDataFile aMergeDataFile( + rMergeSrc, static_cast<OString>( m_pSource->name ), false ); + const std::vector<OString> vLanguages = aMergeDataFile.GetLanguages(); + if( vLanguages.size()>=2 && vLanguages[0] != m_sLang ) + { + std::cerr + << "stringex error: given language conflicts with " + << "language of Mergedata file: " + << m_sLang.getStr() << " - " + << vLanguages[vLanguages[0]=="qtz" ? 0 : 1].getStr() << std::endl; + return; + } + + xmlNodePtr pRootNode = xmlDocGetRootElement( m_pSource ); //<resource> + + for( xmlNodePtr pCurrent = pRootNode->children; + pCurrent; pCurrent = pCurrent->next) + { + if (!xmlStrcmp(pCurrent->name, (const xmlChar*)("string"))) + { + xmlChar* pID = xmlGetProp(pCurrent, (const xmlChar*)("name")); + ResData aResData( + "", lcl_xmlStrToOString( pID ), + static_cast<OString>(m_pSource->name) ); + xmlFree( pID ); + aResData.sResTyp = "string"; + PFormEntrys* pEntrys = + (&aMergeDataFile)->GetPFormEntrys( &aResData ); + if( pEntrys ) + { + OString sNewText; + pEntrys->GetText( sNewText, STRING_TYP_TEXT, m_sLang ); + xmlNodeSetContent( + pCurrent, + xmlEncodeSpecialChars( NULL, + reinterpret_cast<const xmlChar*>( + sNewText.getStr() ))); + } + } + } + + xmlSaveFile( rDestinationFile.getStr(), m_pSource ); + xmlFreeDoc( m_pSource ); + xmlCleanupParser(); + m_bIsInitialized = false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |