xref: /trunk/main/l10ntools/source/xrmmerge.cxx (revision a893be29)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_l10ntools.hxx"
26 #include <stdio.h>
27 #include <tools/string.hxx>
28 #include <tools/fsys.hxx>
29 
30 // local includes
31 #include "export.hxx"
32 #include "xrmmerge.hxx"
33 #include "utf8conv.hxx"
34 #include "tokens.h"
35 #include <iostream>
36 #include <vector>
37 
38 using namespace std;
39 
40 extern "C" { int yyerror( char * ); }
41 extern "C" { int YYWarning( char * ); }
42 
43 // defines to parse command line
44 #define STATE_NON  		0x0001
45 #define STATE_INPUT		0x0002
46 #define STATE_OUTPUT	0x0003
47 #define STATE_PRJ		0x0004
48 #define STATE_ROOT		0x0005
49 #define STATE_MERGESRC	0x0006
50 #define STATE_ERRORLOG	0x0007
51 #define STATE_UTF8		0x000B
52 #define STATE_LANGUAGES	0x000C
53 #define STATE_ISOCODE99	0x000D
54 
55 // set of global variables
56 sal_Bool bEnableExport;
57 sal_Bool bMergeMode;
58 sal_Bool bErrorLog;
59 sal_Bool bUTF8;
60 ByteString sPrj;
61 ByteString sPrjRoot;
62 ByteString sInputFileName;
63 ByteString sActFileName;
64 ByteString sOutputFile;
65 ByteString sMergeSrc;
66 String sUsedTempFile;
67 XRMResParser *pParser = NULL;
68 
69 extern "C" {
70 // the whole interface to lexer is in this extern "C" section
71 
72 /*****************************************************************************/
GetOutputFile(int argc,char * argv[])73 extern char *GetOutputFile( int argc, char* argv[])
74 /*****************************************************************************/
75 {
76 	bEnableExport = sal_False;
77 	bMergeMode = sal_False;
78 	bErrorLog = sal_True;
79 	bUTF8 = sal_True;
80 	sPrj = "";
81 	sPrjRoot = "";
82 	sInputFileName = "";
83 	sActFileName = "";
84 	Export::sLanguages = "";
85 	sal_uInt16 nState = STATE_NON;
86 	sal_Bool bInput = sal_False;
87 
88 	// parse command line
89 	for( int i = 1; i < argc; i++ ) {
90 		if ( ByteString( argv[ i ] ).ToUpperAscii() == "-I" ) {
91 			nState = STATE_INPUT; // next token specifies source file
92 		}
93 		else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-O" ) {
94 			nState = STATE_OUTPUT; // next token specifies the dest file
95 		}
96 		else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-P" ) {
97 			nState = STATE_PRJ; // next token specifies the cur. project
98 		}
99 		else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-R" ) {
100 			nState = STATE_ROOT; // next token specifies path to project root
101 		}
102 		else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-M" ) {
103 			nState = STATE_MERGESRC; // next token specifies the merge database
104 		}
105         else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-E" ) {
106 			nState = STATE_ERRORLOG;
107 			bErrorLog = sal_False;
108 		}
109 		else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-UTF8" ) {
110 			nState = STATE_UTF8;
111 			bUTF8 = sal_True;
112 		}
113 		else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-NOUTF8" ) {
114 			nState = STATE_UTF8;
115 			bUTF8 = sal_False;
116 		}
117 		else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-L" ) {
118 			nState = STATE_LANGUAGES;
119 		}
120 		else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-ISO99" ) {
121 			nState = STATE_ISOCODE99;
122 		}
123 		else {
124 			switch ( nState ) {
125 				case STATE_NON: {
126 					return NULL;	// no valid command line
127 				}
128 				case STATE_INPUT: {
129 					sInputFileName = argv[ i ];
130 					bInput = sal_True; // source file found
131 				}
132 				break;
133 				case STATE_OUTPUT: {
134 					sOutputFile = argv[ i ]; // the dest. file
135 				}
136 				break;
137 				case STATE_PRJ: {
138 					sPrj = ByteString( argv[ i ]);
139 				}
140 				break;
141 				case STATE_ROOT: {
142 					sPrjRoot = ByteString( argv[ i ]); // path to project root
143 				}
144 				break;
145 				case STATE_MERGESRC: {
146 					sMergeSrc = ByteString( argv[ i ]);
147 					bMergeMode = sal_True; // activate merge mode, cause merge database found
148 				}
149 				break;
150 				case STATE_LANGUAGES: {
151 					Export::sLanguages = ByteString( argv[ i ]);
152 				}
153 				break;
154 			}
155 		}
156 	}
157 
158 	if ( bInput ) {
159 		// command line is valid
160 		bEnableExport = sal_True;
161 		char *pReturn = new char[ sOutputFile.Len() + 1 ];
162 		strcpy( pReturn, sOutputFile.GetBuffer());  // #100211# - checked
163 		return pReturn;
164 	}
165 
166 	// command line is not valid
167 	return NULL;
168 }
removeTempFile()169 void removeTempFile(){
170     if( !sUsedTempFile.EqualsIgnoreCaseAscii( "" ) ){
171         DirEntry aTempFile( sUsedTempFile );
172         aTempFile.Kill();
173     }
174 }
175 /*****************************************************************************/
InitXrmExport(char * pOutput,char * pFilename)176 int InitXrmExport( char *pOutput , char* pFilename)
177 /*****************************************************************************/
178 {
179 	// instanciate Export
180 	ByteString sOutput( pOutput );
181 	ByteString sFilename( pFilename );
182     Export::InitLanguages( false );
183 
184 	if ( bMergeMode )
185         pParser = new XRMResMerge( sMergeSrc, sOutputFile, sFilename );
186   	else if ( sOutputFile.Len()) {
187 		pParser = new XRMResExport( sOutputFile, sPrj, sActFileName );
188 	}
189 
190 	return 1;
191 }
192 
193 /*****************************************************************************/
EndXrmExport()194 int EndXrmExport()
195 /*****************************************************************************/
196 {
197 	delete pParser;
198 	return 1;
199 }
getFilename()200 extern const char* getFilename()
201 {
202 	return sInputFileName.GetBuffer();
203 }
204 /*****************************************************************************/
GetXrmFile()205 extern FILE *GetXrmFile()
206 /*****************************************************************************/
207 {
208     FILE *pFile = 0;
209     // look for valid filename
210 	if ( sInputFileName.Len()) {
211         if( Export::fileHasUTF8ByteOrderMarker( sInputFileName ) ){
212             DirEntry aTempFile = Export::GetTempFile();
213             DirEntry aSourceFile( String( sInputFileName , RTL_TEXTENCODING_ASCII_US ) );
214             aSourceFile.CopyTo( aTempFile , FSYS_ACTION_COPYFILE );
215             String sTempFile = aTempFile.GetFull();
216             Export::RemoveUTF8ByteOrderMarkerFromFile( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ) );
217             pFile = fopen( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ).GetBuffer(), "r" );
218             sUsedTempFile = sTempFile;
219         }else{
220 		    // able to open file?
221 		    pFile = fopen( sInputFileName.GetBuffer(), "r" );
222             sUsedTempFile = String::CreateFromAscii("");
223         }
224 		if ( !pFile ){
225 			fprintf( stderr, "Error: Could not open file %s\n",
226 				sInputFileName.GetBuffer());
227         }
228         else {
229 			// this is a valid file which can be opened, so
230 			// create path to project root
231 			DirEntry aEntry( String( sInputFileName, RTL_TEXTENCODING_ASCII_US ));
232 			aEntry.ToAbs();
233 			ByteString sFullEntry( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );
234 			aEntry += DirEntry( String( "..", RTL_TEXTENCODING_ASCII_US ));
235 			aEntry += DirEntry( sPrjRoot );
236 			ByteString sPrjEntry( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );
237 
238 			// create file name, beginning with project root
239 			// (e.g.: source\ui\src\menue.src)
240 			sActFileName = sFullEntry.Copy( sPrjEntry.Len() + 1 );
241 
242 
243 			sActFileName.SearchAndReplaceAll( "/", "\\" );
244 
245 			return pFile;
246 		}
247 	}
248 	// this means the file could not be opened
249 	return NULL;
250 }
251 
252 /*****************************************************************************/
WorkOnTokenSet(int nTyp,char * pTokenText)253 int WorkOnTokenSet( int nTyp, char *pTokenText )
254 /*****************************************************************************/
255 {
256 	//printf("Typ = %d , text = '%s'\n",nTyp , pTokenText );
257     pParser->Execute( nTyp, pTokenText );
258 
259 	return 1;
260 }
261 
262 /*****************************************************************************/
SetError()263 int SetError()
264 /*****************************************************************************/
265 {
266 	pParser->SetError();
267 	return 1;
268 }
269 }
270 
271 extern "C" {
272 /*****************************************************************************/
GetError()273 int GetError()
274 /*****************************************************************************/
275 {
276 	return pParser->GetError();
277 }
278 }
279 
280 //
281 // class XRMResParser
282 //
283 
284 
285 /*****************************************************************************/
XRMResParser()286 XRMResParser::XRMResParser()
287 /*****************************************************************************/
288 				: bError( sal_False ),
289 		        bText( sal_False )
290 {
291     aLanguages = Export::GetLanguages();
292 }
293 
294 /*****************************************************************************/
~XRMResParser()295 XRMResParser::~XRMResParser()
296 /*****************************************************************************/
297 {
298 }
299 
300 /*****************************************************************************/
Execute(int nToken,char * pToken)301 int XRMResParser::Execute( int nToken, char * pToken )
302 /*****************************************************************************/
303 {
304 	ByteString rToken( pToken );
305 
306 	switch ( nToken ) {
307 		case XRM_README_START:
308 			sLID = "";
309 			sGID = GetAttribute( rToken, "name" );
310 		break;
311 
312 		case XRM_README_END:
313 			sGID = "";
314 		break;
315 
316 		case XRM_SECTION_START:
317 			sLID = "";
318 			sGID += ".";
319 			sGID += GetAttribute( rToken, "id" );
320 			//sLocalized = "1";
321 
322             //sLocalized = "X:";
323             sLocalized = true;
324 		break;
325 
326 		case XRM_SECTION_END:
327 			sGID = sGID.GetToken( 0, '.' );
328 			break;
329 
330 		case XRM_PARAGRAPH_START:
331 			sLID = "";
332 			sGID += ".";
333 			sGID += GetAttribute( rToken, "id" );
334 //			if ( GetAttribute( rToken, "localized" ) == "false" )
335 //				sLocalized += "0";
336 //                sLocalized = false;
337 //			else
338 //				sLocalized += "1";
339                 sLocalized = true;
340 		break;
341 
342 		case XRM_PARAGRAPH_END: {
343 			if ( sLID.Len())
344 				EndOfText( sCurrentOpenTag, sCurrentCloseTag );
345 			ByteString sTmp = sGID;
346 			sGID = "";
347 			for ( sal_uInt16 i = 0; i + 1 < sTmp.GetTokenCount( '.' ); i++ ) {
348 				if ( sGID.Len())
349 					sGID += ".";
350 				sGID += sTmp.GetToken( i, '.' );
351 			}
352 			//sLocalized = sLocalized.Copy( 0, sLocalized.Len() - 1 );
353 	   	}
354 		break;
355 
356 		case XRM_TEXT_START:{
357                 //printf("->XRM_TEXT_START\n");
358                 ByteString sNewLID = GetAttribute( rToken, "id" );
359 				if ( sNewLID != sLID ) {
360 					//EndOfText( sCurrentOpenTag, sCurrentCloseTag );
361 					sLID = sNewLID;
362 				}
363 				bText = sal_True;
364 				sCurrentText = "";
365 				sCurrentOpenTag = rToken;
366 				Output( rToken );
367                 //printf("<-XRM_TEXT_START\n");
368 			}
369 		break;
370 
371 		case XRM_TEXT_END: {
372 				sCurrentCloseTag = rToken;
373                 //printf("->XRM_TEXT_END\n");
374 				ByteString sLang = GetAttribute( sCurrentOpenTag, "xml:lang" );
375 				WorkOnText( sCurrentOpenTag, sCurrentText );
376 				Output( sCurrentText );
377                 EndOfText( sCurrentOpenTag, sCurrentCloseTag );// <---
378 				bText = sal_False;
379                 rToken = ByteString("");
380                 sCurrentText  = ByteString("");
381                 //printf("<-XRM_TEXT_END");
382 		}
383 		break;
384 
385 		case XRM_LIST_START:
386 			sLID = "";
387 		break;
388 
389 		case XRM_LIST_END:
390 			if ( sLID.Len())
391 				EndOfText( sCurrentOpenTag, sCurrentCloseTag );
392 		break;
393 
394 		default:
395 			if ( bText ) {
396 				sCurrentText += rToken;
397 			}
398 		break;
399 	}
400 
401 	if ( !bText )
402     {
403         Output( rToken );
404     }
405 	return 0;
406 }
407 
408 /*****************************************************************************/
GetAttribute(const ByteString & rToken,const ByteString & rAttribute)409 ByteString XRMResParser::GetAttribute( const ByteString &rToken, const ByteString &rAttribute )
410 /*****************************************************************************/
411 {
412 	ByteString sTmp( rToken );
413 	sTmp.SearchAndReplaceAll( "\t", " " );
414 
415 	ByteString sSearch( " " );
416 	sSearch += rAttribute;
417 	sSearch += "=";
418 	sal_uInt16 nPos = sTmp.Search( sSearch );
419 
420 	if ( nPos != STRING_NOTFOUND ) {
421 		sTmp = sTmp.Copy( nPos );
422 		ByteString sId = sTmp.GetToken( 1, '\"' );
423 		return sId;
424 	}
425 	return "";
426 }
427 
428 
429 /*****************************************************************************/
Error(const ByteString & rError)430 void XRMResParser::Error( const ByteString &rError )
431 /*****************************************************************************/
432 {
433 	yyerror(( char * ) rError.GetBuffer());
434 }
435 
436 /*****************************************************************************/
ConvertStringToDBFormat(ByteString & rString)437 void XRMResParser::ConvertStringToDBFormat( ByteString &rString )
438 /*****************************************************************************/
439 {
440 	ByteString sResult;
441     do {
442 		sResult = rString;
443 		rString.EraseLeadingChars( _LF );
444 	//	rString.EraseLeadingChars( ' ' );
445 		rString.EraseLeadingChars( '\t' );
446 	//	rString.EraseTrailingChars( ' ' );
447 		rString.EraseTrailingChars( '\t' );
448 	} while ( sResult != rString );
449 
450 	rString.SearchAndReplaceAll( "\t", "\\t" );
451 }
452 
453 /*****************************************************************************/
ConvertStringToXMLFormat(ByteString & rString)454 void XRMResParser::ConvertStringToXMLFormat( ByteString &rString )
455 /*****************************************************************************/
456 {
457 	rString.SearchAndReplaceAll( "\\t", "\t" );
458 }
459 
460 
461 
462 //
463 // class XRMResOutputParser
464 //
465 
466 /*****************************************************************************/
XRMResOutputParser(const ByteString & rOutputFile)467 XRMResOutputParser::XRMResOutputParser ( const ByteString &rOutputFile )
468 /*****************************************************************************/
469 {
470 	aLanguages = Export::GetLanguages();
471     pOutputStream =
472 		new SvFileStream(
473 			String( rOutputFile, RTL_TEXTENCODING_ASCII_US ),
474 			STREAM_STD_WRITE | STREAM_TRUNC
475 		);
476     pOutputStream->SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
477 	if ( !pOutputStream->IsOpen()) {
478 		ByteString sError( "Unable to open output file: " );
479 		sError += rOutputFile;
480 		Error( sError );
481 		delete pOutputStream;
482 		pOutputStream = NULL;
483 	}
484 }
485 
486 /*****************************************************************************/
~XRMResOutputParser()487 XRMResOutputParser::~XRMResOutputParser()
488 /*****************************************************************************/
489 {
490 	if ( pOutputStream ) {
491 		pOutputStream->Close();
492 		delete pOutputStream;
493 	}
494 }
495 
496 //
497 // class XMLResExport
498 //
499 
500 /*****************************************************************************/
XRMResExport(const ByteString & rOutputFile,const ByteString & rProject,const ByteString & rFilePath)501 XRMResExport::XRMResExport(
502 	const ByteString &rOutputFile, const ByteString &rProject,
503 	const ByteString &rFilePath )
504 /*****************************************************************************/
505 				: XRMResOutputParser( rOutputFile ),
506 				pResData( NULL ),
507 				sPrj( rProject ),
508 				sPath( rFilePath )
509 {
510     aLanguages = Export::GetLanguages();
511 }
512 
513 /*****************************************************************************/
~XRMResExport()514 XRMResExport::~XRMResExport()
515 /*****************************************************************************/
516 {
517 	delete pResData;
518 }
519 
Output(const ByteString & rOutput)520 void XRMResExport::Output( const ByteString& rOutput )
521 {
522     // Dummy to suppress warnings caused by poor class design
523     (void) rOutput;
524 }
525 
526 /*****************************************************************************/
WorkOnText(const ByteString & rOpenTag,ByteString & rText)527 void XRMResExport::WorkOnText(
528 	const ByteString &rOpenTag,
529 	ByteString &rText
530 )
531 /*****************************************************************************/
532 {
533 	ByteString sLang( GetAttribute( rOpenTag, "xml:lang" ));
534 
535 		if ( !pResData ) {
536 			ByteString sPlatform( "" );
537 			pResData = new ResData( sPlatform, GetGID() );
538 			pResData->sId = GetLID();
539 		}
540 
541         pResData->sText[ sLang ] = rText;
542         ConvertStringToDBFormat( pResData->sText[ sLang ] );
543 }
544 
545 /*****************************************************************************/
EndOfText(const ByteString & rOpenTag,const ByteString & rCloseTag)546 void XRMResExport::EndOfText(
547 	const ByteString &rOpenTag,
548 	const ByteString &rCloseTag
549 )
550 /*****************************************************************************/
551 {
552 
553     (void) rOpenTag;        // FIXME
554     (void) rCloseTag;       // FIXME
555 
556     if ( pResData && pOutputStream ) {
557 
558 		char cSearch = 0x00;
559 		ByteString sSearch( cSearch );
560 
561  	//	if ( !pResData->sText[ ByteString("en-US") ].Len() )
562     //        pResData->sText[ ByteString("en-US") ] = pResData->sText[ ByteString("de") ];
563 
564 		Export::FillInFallbacks( pResData );
565 
566 		ByteString sTimeStamp( Export::GetTimeStamp());
567         ByteString sCur;
568         for( unsigned int n = 0; n < aLanguages.size(); n++ ){
569             sCur = aLanguages[ n ];
570 
571             ByteString sAct = pResData->sText[ sCur ];
572 				//Export::UnquotHTML( sAct );
573 				sAct.EraseAllChars( 0x0A );
574 
575 				ByteString sOutput( sPrj ); sOutput += "\t";
576 				sOutput += sPath;
577 				sOutput += "\t0\t";
578 				sOutput += "readmeitem\t";
579 				sOutput += pResData->sId;
580                 // USE LID AS GID OR MERGE DON'T WORK
581                 //sOutput += pResData->sGId;
582                 sOutput += "\t";
583                 sOutput += pResData->sId;
584                 sOutput += "\t\t\t0\t";
585                 sOutput += sCur;
586                 sOutput += "\t";
587 
588                 sOutput += sAct; sOutput += "\t\t\t\t";
589 				sOutput += sTimeStamp;
590 
591 				sOutput.SearchAndReplaceAll( sSearch, "_" );
592                 //if( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && !Export::isMergingGermanAllowed( sPrj ) ) )
593 			    if( sAct.Len() > 1 )
594                     pOutputStream->WriteLine( sOutput );
595 			}
596 	}
597 	delete pResData;
598 	pResData = NULL;
599 }
600 
601 //
602 // class XRMResMerge
603 //
604 
605 /*****************************************************************************/
XRMResMerge(const ByteString & rMergeSource,const ByteString & rOutputFile,ByteString & rFilename)606 XRMResMerge::XRMResMerge(
607 	const ByteString &rMergeSource, const ByteString &rOutputFile,
608 	ByteString &rFilename)
609 /*****************************************************************************/
610 				: XRMResOutputParser( rOutputFile ),
611 				pMergeDataFile( NULL ),
612 				sFilename( rFilename ) ,
613 				pResData( NULL )
614 {
615     if ( rMergeSource.Len())
616 		pMergeDataFile = new MergeDataFile(
617 			rMergeSource, sInputFileName , bErrorLog, RTL_TEXTENCODING_MS_1252);//, bUTF8 );
618     if( Export::sLanguages.EqualsIgnoreCaseAscii("ALL") ){
619         Export::SetLanguages( pMergeDataFile->GetLanguages() );
620         aLanguages = pMergeDataFile->GetLanguages();
621     }
622     else aLanguages = Export::GetLanguages();
623 }
624 
625 /*****************************************************************************/
~XRMResMerge()626 XRMResMerge::~XRMResMerge()
627 /*****************************************************************************/
628 {
629 	delete pMergeDataFile;
630 	delete pResData;
631 }
632 
633 /*****************************************************************************/
WorkOnText(const ByteString & rOpenTag,ByteString & rText)634 void XRMResMerge::WorkOnText(
635 	const ByteString &rOpenTag,
636 	ByteString &rText
637 )
638 /*****************************************************************************/
639 {
640 	ByteString sLang( GetAttribute( rOpenTag, "xml:lang" ));
641 
642 	if ( pMergeDataFile ) {
643 		if ( !pResData ) {
644 			ByteString sPlatform( "" );
645 //			pResData = new ResData( sPlatform, GetGID() , sFilename );
646 			pResData = new ResData( sPlatform, GetLID() , sFilename );
647             pResData->sId = GetLID();
648 
649 			pResData->sResTyp = "readmeitem";
650 		}
651 
652         PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrys( pResData );
653 			if ( pEntrys ) {
654                 ByteString sContent;
655 				if ( Export::isAllowed( sLang ) &&
656                     ( pEntrys->GetText(
657                         sContent, STRING_TYP_TEXT, sLang )) &&
658 					( sContent != "-" ) && ( sContent.Len()))
659 
660 				{
661                     rText = sContent;
662                     ConvertStringToXMLFormat( rText );
663 					//Export::QuotHTMLXRM( rText );
664 				}
665 			}
666 	}
667 }
668 
669 /*****************************************************************************/
Output(const ByteString & rOutput)670 void XRMResMerge::Output( const ByteString& rOutput )
671 /*****************************************************************************/
672 {
673     //printf("W: %s\n",rOutput.GetBuffer());
674     if ( pOutputStream && rOutput.Len() > 0 )
675 		pOutputStream->Write( rOutput.GetBuffer(), rOutput.Len());
676 }
677 
678 /*****************************************************************************/
EndOfText(const ByteString & rOpenTag,const ByteString & rCloseTag)679 void XRMResMerge::EndOfText(
680 	const ByteString &rOpenTag,
681 	const ByteString &rCloseTag
682 )
683 /*****************************************************************************/
684 {
685 
686     Output( rCloseTag );
687     if ( pMergeDataFile && pResData ) {
688 		PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrys( pResData );
689 		if ( pEntrys ) {
690             ByteString sCur;
691             for( unsigned int n = 0; n < aLanguages.size(); n++ ){
692                 sCur = aLanguages[ n ];
693 				ByteString sContent;
694                 if ( !sCur.EqualsIgnoreCaseAscii("en-US")  &&
695 					( pEntrys->GetText(
696                         sContent, STRING_TYP_TEXT, sCur, sal_True )) &&
697 					( sContent != "-" ) && ( sContent.Len()))
698 				{
699                     ByteString sText( sContent );
700 					//Export::QuotHTMLXRM( sText );
701 
702 					ByteString sAdditionalLine( "\t" );
703 					sAdditionalLine += rOpenTag;
704 					ByteString sSearch = "xml:lang=\"";
705 					ByteString sReplace( sSearch );
706 
707 					sSearch += GetAttribute( rOpenTag, "xml:lang" );
708                     sReplace += sCur;
709 
710 					sAdditionalLine.SearchAndReplace( sSearch, sReplace );
711 
712 					sAdditionalLine += sText;
713 					sAdditionalLine += rCloseTag;
714 					sAdditionalLine += "\n";
715 
716 					for ( sal_uInt16 i = 0; i + 1 < GetGID().GetTokenCount( '.' ); i++ )
717 						sAdditionalLine += "\t";
718 
719 					Output( sAdditionalLine );
720 				}
721 			}
722 		}
723 	}
724 	delete pResData;
725 	pResData = NULL;
726 }
727 
728