diff options
author | Zolnai Tamás <zolnaitamas2000@gmail.com> | 2012-11-01 13:39:43 +0100 |
---|---|---|
committer | Zolnai Tamás <zolnaitamas2000@gmail.com> | 2012-11-03 23:40:30 +0100 |
commit | 0fd7f81ec6765133bc2a964afd832631cd1bbf31 (patch) | |
tree | 5766461871b043c8e4ffab58f133f7fc42feee42 /l10ntools/source/treemerge.cxx | |
parent | ef941c6e78cbab5d9d25b1fe57e483deead03a32 (diff) |
Implement new treex executable
Which localize and update help tree files
instead of update_tree.pl.
Use it to update extensions' help.
Next step: use it with general help.
Change-Id: Ife9696bdd8b973ef3cf30626533e38720408179b
Diffstat (limited to 'l10ntools/source/treemerge.cxx')
-rw-r--r-- | l10ntools/source/treemerge.cxx | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/l10ntools/source/treemerge.cxx b/l10ntools/source/treemerge.cxx new file mode 100644 index 000000000000..12e931c6d221 --- /dev/null +++ b/l10ntools/source/treemerge.cxx @@ -0,0 +1,304 @@ +/* -*- 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 "treemerge.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; + } + + //Extract strings from nodes on all level recursively + static void lcl_ExtractLevel( + const xmlDocPtr pSource, const xmlNodePtr pRoot, + const xmlChar* pNodeName, std::ofstream& rSDFStream, + const OString& rPrj, const OString& rRoot ) + { + if( !pRoot->children ) + { + return; + } + for( xmlNodePtr pCurrent = pRoot->children->next; + pCurrent; pCurrent = pCurrent->next) + { + if (!xmlStrcmp(pCurrent->name, pNodeName)) + { + xmlChar* pID = xmlGetProp(pCurrent, (const xmlChar*)("id")); + xmlChar* pText = + xmlGetProp(pCurrent, (const xmlChar*)("title")); + lcl_WriteSDF( + rSDFStream, + lcl_xmlStrToOString( pText ), + rPrj, + common::pathnameToken( + pSource->name, rRoot.getStr()), + lcl_xmlStrToOString( pID ), + lcl_xmlStrToOString( pNodeName )); + + xmlFree( pID ); + xmlFree( pText ); + + lcl_ExtractLevel( + pSource, pCurrent, (const xmlChar *)("node"), + rSDFStream, rPrj, rRoot ); + } + } + } + + //Update id and content of the topic + static xmlNodePtr lcl_UpdateTopic( + const xmlNodePtr pCurrent, const OString& rXhpRoot ) + { + xmlNodePtr pReturn = pCurrent; + xmlChar* pID = xmlGetProp(pReturn, (const xmlChar*)("id")); + const OString sID = + lcl_xmlStrToOString( pID ); + xmlFree( pID ); + + const sal_Int32 nFirstSlash = sID.indexOf("/"); + //Update id attribute of topic + { + OString sNewID = + sID.copy( 0, nFirstSlash + 1 ) + + rXhpRoot.copy( rXhpRoot.lastIndexOf("/") + 1 ) + + sID.copy( sID.indexOf( "/", nFirstSlash + 1 ) ); + xmlSetProp( + pReturn, (const xmlChar*)("id"), + reinterpret_cast<const xmlChar*>(sNewID.getStr())); + } + + const OString sXhpPath = + rXhpRoot + + sID.copy(sID.indexOf("/", nFirstSlash + 1)); + xmlDocPtr pXhpFile = xmlParseFile( sXhpPath.getStr() ); + //if xhpfile is missing than we put this topic into comment + if ( !pXhpFile ) + { + xmlNodePtr pTemp = pReturn; + xmlChar* sNewID = + xmlGetProp(pReturn, (const xmlChar*)("id")); + xmlChar* sComment = + xmlStrcat( xmlCharStrdup("removed "), sNewID ); + pReturn = xmlNewComment( sComment ); + xmlReplaceNode( pTemp, pReturn ); + xmlFree( pTemp ); + xmlFree( sNewID ); + xmlFree( sComment ); + } + //update topic's content on the basis of xhpfile's title + else + { + xmlNodePtr pXhpNode = xmlDocGetRootElement( pXhpFile ); + for( pXhpNode = pXhpNode->children; + pXhpNode; pXhpNode = pXhpNode->children ) + { + while( pXhpNode->type != XML_ELEMENT_NODE ) + { + pXhpNode = pXhpNode->next; + } + if(!xmlStrcmp(pXhpNode->name, (const xmlChar *)("title"))) + { + xmlChar* sTitle = + xmlNodeListGetString(pXhpFile, pXhpNode->children, 1); + OString sNewTitle = + lcl_xmlStrToOString( sTitle ). + replaceAll("$[officename]","%PRODUCTNAME"). + replaceAll("$[officeversion]","%PRODUCTVERSION"); + xmlNodeSetContent( + pReturn, + reinterpret_cast<const xmlChar*>( sNewTitle.getStr() )); + xmlFree( sTitle ); + break; + } + } + if( !pXhpNode ) + { + std::cerr + << "Treex error: Cannot find title in " + << sXhpPath.getStr() << std::endl; + return 0; + } + xmlFree( pXhpFile ); + xmlCleanupParser(); + } + return pReturn; + } + //Localize title attribute of help_section and node tags + static void lcl_MergeLevel( + xmlDocPtr io_pSource, const xmlNodePtr pRoot, + const xmlChar * pNodeName, MergeDataFile* pMergeDataFile, + const OString& rLang, const OString& rXhpRoot ) + { + if( !pRoot->children ) + { + return; + } + for( xmlNodePtr pCurrent = pRoot->children; + pCurrent; pCurrent = pCurrent->next) + { + if( !xmlStrcmp(pCurrent->name, pNodeName) ) + { + if( pMergeDataFile ) + { + xmlChar* pID = xmlGetProp(pCurrent, (const xmlChar*)("id")); + ResData aResData( + "", lcl_xmlStrToOString( pID ), + static_cast<OString>(io_pSource->name) ); + xmlFree( pID ); + aResData.sResTyp = lcl_xmlStrToOString( pNodeName ); + PFormEntrys* pEntrys = + pMergeDataFile->GetPFormEntrys( &aResData ); + if( pEntrys ) + { + OString sNewText; + pEntrys->GetText( sNewText, STRING_TYP_TEXT, rLang ); + xmlSetProp( + pCurrent, (const xmlChar*)("title"), + (const xmlChar*)(sNewText.getStr())); + } + } + lcl_MergeLevel( + io_pSource, pCurrent, (const xmlChar *)("node"), + pMergeDataFile, rLang, rXhpRoot ); + } + else if( !xmlStrcmp(pCurrent->name, (const xmlChar *)("topic")) ) + { + pCurrent = lcl_UpdateTopic( pCurrent, rXhpRoot ); + } + } + } +} + +//Parse tree file +TreeParser::TreeParser( + 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 + << "Treex 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; +} + +TreeParser::~TreeParser() +{ +} + +//Extract strings form source file +void TreeParser::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 + << "Treex error: Cannot open sdffile for extract: " + << rSDFFile.getStr() << std::endl; + return; + } + + xmlNodePtr pRootNode = xmlDocGetRootElement( m_pSource ); + lcl_ExtractLevel( + m_pSource, pRootNode, (const xmlChar *)("help_section"), + aSDFStream, rPrj, rRoot ); + + xmlFreeDoc( m_pSource ); + xmlCleanupParser(); + aSDFStream.close(); + m_bIsInitialized = false; +} + +//Merge strings to tree file and update reference to help files(xhp) +void TreeParser::Merge( + const OString &rMergeSrc, const OString &rDestinationFile, + const OString &rXhpRoot ) +{ + assert( m_bIsInitialized ); + + const xmlNodePtr pRootNode = xmlDocGetRootElement( m_pSource ); + if( m_sLang == "en-US" ) + { + lcl_MergeLevel( + m_pSource, pRootNode, (const xmlChar *)("help_section"), + 0, m_sLang, rXhpRoot ); + } + else + { + MergeDataFile aMergeDataFile( + rMergeSrc, static_cast<OString>( m_pSource->name ), false ); + + if( aMergeDataFile.GetLanguages()[0] != m_sLang ) + { + std::cerr + << "Treex error: given language conflicts with " + << "language of Mergedata file: " + << m_sLang.getStr() << " - " << rMergeSrc.getStr() << std::endl; + return; + } + + lcl_MergeLevel( + m_pSource, pRootNode, (const xmlChar *)("help_section"), + &aMergeDataFile, m_sLang, rXhpRoot ); + } + + xmlSaveFile( rDestinationFile.getStr(), m_pSource ); + xmlFreeDoc( m_pSource ); + xmlCleanupParser(); + m_bIsInitialized = false; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |