fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / l10ntools / source / treemerge.cxx
blob049f272b53358440ecae6c3ea5943a27f67d923f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <iostream>
11 #include <fstream>
12 #include <cassert>
13 #include <cstring>
15 #include <libxml/tree.h>
16 #include <libxml/parser.h>
17 #include <libxml/xmlmemory.h>
18 #include <libxml/xmlstring.h>
20 #include "export.hxx"
21 #include "helper.hxx"
22 #include "common.hxx"
23 #include "po.hxx"
24 #include "treemerge.hxx"
27 namespace
29 // Extract strings from nodes on all level recursively
30 static void lcl_ExtractLevel(
31 const xmlDocPtr pSource, const xmlNodePtr pRoot,
32 const xmlChar* pNodeName, PoOfstream& rPOStream )
34 if( !pRoot->children )
36 return;
38 for( xmlNodePtr pCurrent = pRoot->children->next;
39 pCurrent; pCurrent = pCurrent->next)
41 if (!xmlStrcmp(pCurrent->name, pNodeName))
43 xmlChar* pID = xmlGetProp(pCurrent, reinterpret_cast<const xmlChar*>("id"));
44 xmlChar* pText =
45 xmlGetProp(pCurrent, reinterpret_cast<const xmlChar*>("title"));
47 common::writePoEntry(
48 "Treex", rPOStream, pSource->name, helper::xmlStrToOString( pNodeName ),
49 helper::xmlStrToOString( pID ), OString(), OString(), helper::xmlStrToOString( pText ));
51 xmlFree( pID );
52 xmlFree( pText );
54 lcl_ExtractLevel(
55 pSource, pCurrent, reinterpret_cast<const xmlChar *>("node"),
56 rPOStream );
61 // Update id and content of the topic
62 static xmlNodePtr lcl_UpdateTopic(
63 const xmlNodePtr pCurrent, const OString& rXhpRoot )
65 xmlNodePtr pReturn = pCurrent;
66 xmlChar* pID = xmlGetProp(pReturn, reinterpret_cast<const xmlChar*>("id"));
67 const OString sID =
68 helper::xmlStrToOString( pID );
69 xmlFree( pID );
71 const sal_Int32 nFirstSlash = sID.indexOf('/');
72 // Update id attribute of topic
74 OString sNewID =
75 sID.copy( 0, nFirstSlash + 1 ) +
76 rXhpRoot.copy( rXhpRoot.lastIndexOf('/') + 1 ) +
77 sID.copy( sID.indexOf( '/', nFirstSlash + 1 ) );
78 xmlSetProp(
79 pReturn, reinterpret_cast<const xmlChar*>("id"),
80 reinterpret_cast<const xmlChar*>(sNewID.getStr()));
83 const OString sXhpPath =
84 rXhpRoot +
85 sID.copy(sID.indexOf('/', nFirstSlash + 1));
86 xmlDocPtr pXhpFile = xmlParseFile( sXhpPath.getStr() );
87 // if xhpfile is missing than put this topic into comment
88 if ( !pXhpFile )
90 xmlNodePtr pTemp = pReturn;
91 xmlChar* sNewID =
92 xmlGetProp(pReturn, reinterpret_cast<const xmlChar*>("id"));
93 xmlChar* sComment =
94 xmlStrcat( xmlCharStrdup("removed "), sNewID );
95 pReturn = xmlNewComment( sComment );
96 xmlReplaceNode( pTemp, pReturn );
97 xmlFree( pTemp );
98 xmlFree( sNewID );
99 xmlFree( sComment );
101 // update topic's content on the basis of xhpfile's title
102 else
104 xmlNodePtr pXhpNode = xmlDocGetRootElement( pXhpFile );
105 for( pXhpNode = pXhpNode->children;
106 pXhpNode; pXhpNode = pXhpNode->children )
108 while( pXhpNode->type != XML_ELEMENT_NODE )
110 pXhpNode = pXhpNode->next;
112 if(!xmlStrcmp(pXhpNode->name, reinterpret_cast<const xmlChar *>("title")))
114 xmlChar* sTitle =
115 xmlNodeListGetString(pXhpFile, pXhpNode->children, 1);
116 OString sNewTitle =
117 helper::xmlStrToOString( sTitle ).
118 replaceAll("$[officename]","%PRODUCTNAME").
119 replaceAll("$[officeversion]","%PRODUCTVERSION");
120 xmlNodeSetContent(
121 pReturn,
122 xmlEncodeSpecialChars( NULL,
123 reinterpret_cast<const xmlChar*>(
124 sNewTitle.getStr() )));
125 xmlFree( sTitle );
126 break;
129 if( !pXhpNode )
131 std::cerr
132 << "Treex error: Cannot find title in "
133 << sXhpPath.getStr() << std::endl;
134 return 0;
136 xmlFree( pXhpFile );
137 xmlCleanupParser();
139 return pReturn;
141 // Localize title attribute of help_section and node tags
142 static void lcl_MergeLevel(
143 xmlDocPtr io_pSource, const xmlNodePtr pRoot,
144 const xmlChar * pNodeName, MergeDataFile* pMergeDataFile,
145 const OString& rLang, const OString& rXhpRoot )
147 if( !pRoot->children )
149 return;
151 for( xmlNodePtr pCurrent = pRoot->children;
152 pCurrent; pCurrent = pCurrent->next)
154 if( !xmlStrcmp(pCurrent->name, pNodeName) )
156 if( rLang != "en-US" )
158 OString sNewText;
159 xmlChar* pID = xmlGetProp(pCurrent, reinterpret_cast<const xmlChar*>("id"));
160 ResData aResData(
161 helper::xmlStrToOString( pID ),
162 static_cast<OString>(io_pSource->name) );
163 xmlFree( pID );
164 aResData.sResTyp = helper::xmlStrToOString( pNodeName );
165 if( pMergeDataFile )
167 MergeEntrys* pEntrys =
168 pMergeDataFile->GetMergeEntrys( &aResData );
169 if( pEntrys )
171 pEntrys->GetText( sNewText, STRING_TYP_TEXT, rLang );
174 else if( rLang == "qtz" )
176 xmlChar* pText = xmlGetProp(pCurrent, reinterpret_cast<const xmlChar*>("title"));
177 const OString sOriginText = helper::xmlStrToOString(pText);
178 xmlFree( pText );
179 sNewText = MergeEntrys::GetQTZText(aResData, sOriginText);
181 if( !sNewText.isEmpty() )
183 xmlSetProp(
184 pCurrent, reinterpret_cast<const xmlChar*>("title"),
185 reinterpret_cast<const xmlChar*>(sNewText.getStr()));
189 lcl_MergeLevel(
190 io_pSource, pCurrent, reinterpret_cast<const xmlChar *>("node"),
191 pMergeDataFile, rLang, rXhpRoot );
193 else if( !xmlStrcmp(pCurrent->name, reinterpret_cast<const xmlChar *>("topic")) )
195 pCurrent = lcl_UpdateTopic( pCurrent, rXhpRoot );
201 TreeParser::TreeParser(
202 const OString& rInputFile, const OString& rLang )
203 : m_pSource( 0 )
204 , m_sLang( rLang )
205 , m_bIsInitialized( false )
207 m_pSource = xmlParseFile( rInputFile.getStr() );
208 if ( !m_pSource ) {
209 std::cerr
210 << "Treex error: Cannot open source file: "
211 << rInputFile.getStr() << std::endl;
212 return;
214 if( !m_pSource->name )
216 m_pSource->name = static_cast<char *>(xmlMalloc(strlen(rInputFile.getStr())+1));
217 strcpy( m_pSource->name, rInputFile.getStr() );
219 m_bIsInitialized = true;
222 TreeParser::~TreeParser()
226 void TreeParser::Extract( const OString& rPOFile )
228 assert( m_bIsInitialized );
229 PoOfstream aPOStream( rPOFile, PoOfstream::APP );
230 if( !aPOStream.isOpen() )
232 std::cerr
233 << "Treex error: Cannot open po file for extract: "
234 << rPOFile.getStr() << std::endl;
235 return;
238 xmlNodePtr pRootNode = xmlDocGetRootElement( m_pSource );
239 lcl_ExtractLevel(
240 m_pSource, pRootNode, reinterpret_cast<const xmlChar *>("help_section"),
241 aPOStream );
243 xmlFreeDoc( m_pSource );
244 xmlCleanupParser();
245 aPOStream.close();
246 m_bIsInitialized = false;
249 void TreeParser::Merge(
250 const OString &rMergeSrc, const OString &rDestinationFile,
251 const OString &rXhpRoot )
253 assert( m_bIsInitialized );
255 const xmlNodePtr pRootNode = xmlDocGetRootElement( m_pSource );
256 MergeDataFile* pMergeDataFile = 0;
257 if( m_sLang != "qtz" && m_sLang != "en-US" )
259 pMergeDataFile = new MergeDataFile(
260 rMergeSrc, static_cast<OString>( m_pSource->name ), false, false );
261 const std::vector<OString> vLanguages = pMergeDataFile->GetLanguages();
262 if( vLanguages.size()>=1 && vLanguages[0] != m_sLang )
264 std::cerr
265 << ("Treex error: given language conflicts with language of"
266 " Mergedata file: ")
267 << m_sLang.getStr() << " - "
268 << vLanguages[0].getStr() << std::endl;
269 delete pMergeDataFile;
270 return;
273 lcl_MergeLevel(
274 m_pSource, pRootNode, reinterpret_cast<const xmlChar *>("help_section"),
275 pMergeDataFile, m_sLang, rXhpRoot );
277 delete pMergeDataFile;
278 xmlSaveFile( rDestinationFile.getStr(), m_pSource );
279 xmlFreeDoc( m_pSource );
280 xmlCleanupParser();
281 m_bIsInitialized = false;
285 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */