14#include <libxml/tree.h>
15#include <libxml/parser.h>
16#include <libxml/xmlstring.h>
29 void lcl_ExtractLevel(
30 const xmlDocPtr pSource,
const xmlNodePtr pRoot,
31 const xmlChar* pNodeName,
PoOfstream& rPOStream )
33 if( !pRoot->children )
37 for( xmlNodePtr pCurrent = pRoot->children->next;
38 pCurrent; pCurrent = pCurrent->next)
40 if (!xmlStrcmp(pCurrent->name, pNodeName))
42 xmlChar* pID = xmlGetProp(pCurrent,
reinterpret_cast<const xmlChar*
>(
"id"));
44 xmlGetProp(pCurrent,
reinterpret_cast<const xmlChar*
>(
"title"));
54 pSource, pCurrent,
reinterpret_cast<const xmlChar *
>(
"node"),
61 xmlNodePtr lcl_UpdateTopic(
62 const xmlNodePtr pCurrent, std::string_view rXhpRoot )
64 xmlNodePtr pReturn = pCurrent;
65 xmlChar* pID = xmlGetProp(pReturn,
reinterpret_cast<const xmlChar*
>(
"id"));
70 const sal_Int32 nFirstSlash = sID.indexOf(
'/');
74 OString::Concat(sID.subView( 0, nFirstSlash + 1 )) +
75 rXhpRoot.substr( rXhpRoot.rfind(
'/') + 1 ) +
76 sID.subView( sID.indexOf(
'/', nFirstSlash + 1 ) );
78 pReturn,
reinterpret_cast<const xmlChar*
>(
"id"),
79 reinterpret_cast<const xmlChar*
>(sNewID.getStr()));
82 const OString sXhpPath =
83 OString::Concat(rXhpRoot) +
84 sID.subView(sID.indexOf(
'/', nFirstSlash + 1));
85 xmlDocPtr pXhpFile = xmlParseFile( sXhpPath.getStr() );
89 xmlNodePtr pTemp = pReturn;
91 xmlGetProp(pReturn,
reinterpret_cast<const xmlChar*
>(
"id"));
93 xmlStrcat( xmlCharStrdup(
"removed "), sNewID );
94 pReturn = xmlNewComment( sComment );
95 xmlReplaceNode( pTemp, pReturn );
103 xmlNodePtr pXhpNode = xmlDocGetRootElement( pXhpFile );
104 for( pXhpNode = pXhpNode->children;
105 pXhpNode; pXhpNode = pXhpNode->children )
107 while( pXhpNode->type != XML_ELEMENT_NODE )
109 pXhpNode = pXhpNode->next;
111 if(!xmlStrcmp(pXhpNode->name,
reinterpret_cast<const xmlChar *
>(
"title")))
114 xmlNodeListGetString(pXhpFile, pXhpNode->children, 1);
117 replaceAll(
"$[officename]",
"%PRODUCTNAME").
118 replaceAll(
"$[officeversion]",
"%PRODUCTVERSION");
119 xmlChar *xmlString = xmlEncodeSpecialChars(
nullptr,
120 reinterpret_cast<const xmlChar*
>( sNewTitle.getStr() ));
121 xmlNodeSetContent( pReturn, xmlString);
122 xmlFree( xmlString );
130 <<
"Treex error: Cannot find title in "
131 << sXhpPath << std::endl;
134 xmlFreeDoc( pXhpFile );
141 xmlDocPtr io_pSource,
const xmlNodePtr pRoot,
143 const OString& rLang,
const OString& rXhpRoot )
145 if( !pRoot->children )
149 for( xmlNodePtr pCurrent = pRoot->children;
150 pCurrent; pCurrent = pCurrent->next)
152 if( !xmlStrcmp(pCurrent->name, pNodeName) )
154 if( rLang !=
"en-US" )
157 xmlChar* pID = xmlGetProp(pCurrent,
reinterpret_cast<const xmlChar*
>(
"id"));
160 static_cast<OString
>(io_pSource->name) );
169 pEntrys->
GetText( sNewText, rLang );
172 else if( rLang ==
"qtz" )
174 xmlChar* pText = xmlGetProp(pCurrent,
reinterpret_cast<const xmlChar*
>(
"title"));
179 if( !sNewText.isEmpty() )
182 pCurrent,
reinterpret_cast<const xmlChar*
>(
"title"),
183 reinterpret_cast<const xmlChar*
>(sNewText.getStr()));
188 io_pSource, pCurrent,
reinterpret_cast<const xmlChar *
>(
"node"),
189 pMergeDataFile, rLang, rXhpRoot );
191 else if( !xmlStrcmp(pCurrent->name,
reinterpret_cast<const xmlChar *
>(
"topic")) )
193 pCurrent = lcl_UpdateTopic( pCurrent, rXhpRoot );
200 const OString& rInputFile, OString _sLang )
201 : m_pSource( nullptr )
202 , m_sLang(
std::move( _sLang ))
203 , m_bIsInitialized( false )
205 m_pSource = xmlParseFile( rInputFile.getStr() );
208 <<
"Treex error: Cannot open source file: "
209 << rInputFile << std::endl;
214 m_pSource->name =
static_cast<char *
>(xmlMalloc(strlen(rInputFile.getStr())+1));
215 strcpy(
m_pSource->name, rInputFile.getStr() );
234 <<
"Treex error: Cannot open po file for extract: "
235 << rPOFile << std::endl;
239 xmlNodePtr pRootNode = xmlDocGetRootElement(
m_pSource );
241 m_pSource, pRootNode,
reinterpret_cast<const xmlChar *
>(
"help_section"),
251 const OString &rMergeSrc,
const OString &rDestinationFile,
252 const OString &rXhpRoot )
256 const xmlNodePtr pRootNode = xmlDocGetRootElement(
m_pSource );
257 std::unique_ptr<MergeDataFile> pMergeDataFile;
261 rMergeSrc,
static_cast<OString
>(
m_pSource->name ),
false,
false ));
262 const std::vector<OString> vLanguages = pMergeDataFile->
GetLanguages();
263 if( !vLanguages.empty() && vLanguages[0] !=
m_sLang )
266 << (
"Treex error: given language conflicts with language of"
269 << vLanguages[0] << std::endl;
274 m_pSource, pRootNode,
reinterpret_cast<const xmlChar *
>(
"help_section"),
275 pMergeDataFile.get(),
m_sLang, rXhpRoot );
277 pMergeDataFile.reset();
278 xmlSaveFile( rDestinationFile.getStr(),
m_pSource );
Purpose: holds information of data to merge, read from PO file.
MergeEntrys * GetMergeEntrys(ResData *pResData)
std::vector< OString > GetLanguages() const
Purpose: holds information of data to merge.
static OString GetQTZText(const ResData &rResData, std::string_view rOrigText)
Generate QTZ string with ResData For executable which works one language and without PO files.
bool GetText(OString &rReturn, const OString &nLangIndex, bool bDel=false)
Interface to write po entry to files as output streams.
Purpose: holds mandatory data to export a single res.
TreeParser(const OString &rInputFile, OString sLang)
Parse tree file.
void Extract(const OString &rPOFile)
Export strings.
void Merge(const OString &rMergeSrc, const OString &rDestinationFile, const OString &rXhpRoot)
Merge strings to tree file and update reference to help files(xhp)
void writePoEntry(const OString &rExecutable, PoOfstream &rPoStream, const OString &rSourceFile, std::string_view rResType, const OString &rGroupId, const OString &rLocalId, const OString &rHelpText, const OString &rText, const PoEntry::TYPE eType)
Write out a PoEntry with attention to exceptions.
OString xmlStrToOString(const xmlChar *pString)
Convert xmlChar* to OString.