l10ntools/Executable_localize.mk   |    1 
 l10ntools/Executable_renewpo.mk    |    1 
 l10ntools/StaticLibrary_transex.mk |    2 
 l10ntools/inc/po.hxx               |   20 ++
 l10ntools/source/po.cxx            |  324 +++++++++++++++++++++++++++++++------
 l10ntools/source/renewpo.cxx       |    4 
 6 files changed, 299 insertions(+), 53 deletions(-)

New commits:
commit 8a8a39c4c129daa3547dce5f0caf20429997e919
Author: Zolnai Tamás <zolnaitamas2...@gmail.com>
Date:   Fri Aug 31 15:09:06 2012 +0200

    Implement more Po method for merge
    
    Implement file oprerations(entire reading
    and rest part of writing)
    Convert text to merge/sdf form
    Plus cleanup
    
    Change-Id: I6bab9bb202fcdc6d0f2a13f6c44d28e22c688e1e
    Reviewed-on: https://gerrit.libreoffice.org/520
    Reviewed-by: Andras Timar <ati...@suse.com>
    Tested-by: Andras Timar <ati...@suse.com>

diff --git a/l10ntools/Executable_localize.mk b/l10ntools/Executable_localize.mk
index 6184a89..e6e7f1f 100644
--- a/l10ntools/Executable_localize.mk
+++ b/l10ntools/Executable_localize.mk
@@ -33,6 +33,7 @@ $(eval $(call gb_Executable_set_include,localize,\
 
 $(eval $(call gb_Executable_use_libraries,localize,\
     sal \
+    i18nregexp \
 ))
 
 $(eval $(call gb_Executable_use_static_libraries,localize,\
diff --git a/l10ntools/Executable_renewpo.mk b/l10ntools/Executable_renewpo.mk
index 4872e8a..5aa036a 100644
--- a/l10ntools/Executable_renewpo.mk
+++ b/l10ntools/Executable_renewpo.mk
@@ -18,6 +18,7 @@ $(eval $(call gb_Executable_set_include,renewpo,\
 
 $(eval $(call gb_Executable_use_libraries,renewpo,\
     sal \
+    i18nregexp \
 ))
 
 $(eval $(call gb_Executable_use_static_libraries,renewpo,\
diff --git a/l10ntools/StaticLibrary_transex.mk 
b/l10ntools/StaticLibrary_transex.mk
index 21f50e5..82e20a0 100644
--- a/l10ntools/StaticLibrary_transex.mk
+++ b/l10ntools/StaticLibrary_transex.mk
@@ -32,6 +32,8 @@ $(eval $(call gb_StaticLibrary_set_include,transex,\
     $$(INCLUDE) \
 ))
 
+$(eval $(call gb_StaticLibrary_use_sdk_api,transex))
+
 $(eval $(call gb_StaticLibrary_add_exception_objects,transex,\
     l10ntools/source/export2 \
     l10ntools/source/merge \
diff --git a/l10ntools/inc/po.hxx b/l10ntools/inc/po.hxx
index c03baf8..df3004c 100644
--- a/l10ntools/inc/po.hxx
+++ b/l10ntools/inc/po.hxx
@@ -31,6 +31,14 @@ public:
                         GenPoEntry();
     virtual             ~GenPoEntry();
 
+    virtual OString     getWhiteSpace() const   { return m_sWhiteSpace; }
+    virtual OString     getExtractCom() const   { return m_sExtractCom; }
+    virtual OString     getReference() const    { return m_sReference; }
+    virtual OString     getContext() const      { return m_sContext; }
+    virtual OString     getUnTransStr() const   { return m_sUnTransStr; }
+    virtual OString     getTransStr() const     { return m_sTransStr; }
+    virtual bool        getFuzzy() const        { return m_bFuzzy; }
+
     virtual void        setWhiteSpace(const OString& rWhiteSpace)
                         { m_sWhiteSpace = rWhiteSpace; }
     virtual void        setExtractCom(const OString& rExtractCom)
@@ -46,7 +54,9 @@ public:
     virtual void        setFuzzy(bool bFuzzy)
                         { m_bFuzzy = bFuzzy; }
     virtual void        genKeyId();
-    virtual void        writeToFile(std::ofstream& io_rOFStream);
+
+    virtual void        writeToFile(std::ofstream& rOFStream);
+    virtual void        readFromFile(std::ifstream& rIFStream);
 };
 
 class PoEntry: public GenPoEntry
@@ -67,13 +77,19 @@ private:
 
 public:
 
+                        PoEntry();
                         PoEntry(const OString& i_rSDFLine,
-                            const TYPE eType = TTEXT);
+                                const TYPE eType = TTEXT);
     virtual             ~PoEntry();
 
+    virtual OString     getUnTransStr() const;
+    virtual OString     getTransStr() const;
     virtual void        setUnTransStr(const OString& rUnTransStr);
     virtual void        setTransStr(const OString& rTransStr);
 
+    virtual void        writeToFile(std::ofstream& rOFStream);
+    virtual void        readFromFile(std::ifstream& rIFStream);
+
 };
 
 class PoHeader: public GenPoEntry
diff --git a/l10ntools/source/po.cxx b/l10ntools/source/po.cxx
index 6848d7e..a82a88b 100644
--- a/l10ntools/source/po.cxx
+++ b/l10ntools/source/po.cxx
@@ -7,11 +7,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#include "po.hxx"
+#include <com/sun/star/util/SearchOptions.hpp>
+#include <com/sun/star/util/SearchFlags.hpp>
+#include <com/sun/star/i18n/XExtendedTransliteration.hpp>
+#include <regexp/reclass.hxx>
+#include <rtl/ustring.hxx>
+
+#include <string>
+#include <cstring>
 #include <ctime>
 #include <vector>
 #include <boost/crc.hpp>
 
+#include "po.hxx"
+
 #define POESCAPED OString("\\n\\t\\r\\\\\\\"")
 #define POUNESCAPED OString("\n\t\r\\\"")
 
@@ -69,17 +78,17 @@ OString ImplUnEscapeText(const OString& rText,
     return sResult;
 }
 
-//Generate msgctxt, msgid and msgstr strings
-OString ImplGenMsgString(const OString& rSource)
+//Convert a normal string to msg/po output string
+OString ImplGenMsgString(const OString& rString)
 {
-    if ( rSource.isEmpty() )
+    if ( rString.isEmpty() )
         return "\"\"";
 
-    OString sResult = "\"" + rSource + "\"";
+    OString sResult = "\"" + ImplEscapeText(rString) + "\"";
     sal_Int32 nIndex = 0;
     while((nIndex=sResult.indexOf("\\n",nIndex))!=-1)
     {
-        if( sResult.copy(nIndex-1,3) != "\\\\n" )
+        if(sResult.copy(nIndex-1,3)!="\\\\n" && nIndex!=sResult.getLength()-3)
            sResult = sResult.replaceAt(nIndex,2,"\\n\"\n\"");
         ++nIndex;
     }
@@ -90,6 +99,18 @@ OString ImplGenMsgString(const OString& rSource)
     return sResult;
 }
 
+//Convert msg string to normal form
+OString ImplGenNormString(const OString& rString)
+{
+    return ImplUnEscapeText(rString.copy(1,rString.getLength()-2));
+}
+
+//Decide whether a string starts with an other string
+bool ImplStartsWith(const OString& rString,const OString& rStart)
+{
+    return rString.copy(0,rStart.getLength())==rStart;
+}
+
 //Default constructor
 GenPoEntry::GenPoEntry()
     : m_sWhiteSpace( OString() )
@@ -115,29 +136,79 @@ void GenPoEntry::genKeyId()
 }
 
 //Write to file
-void GenPoEntry::writeToFile(std::ofstream& io_rOFStream)
+void GenPoEntry::writeToFile(std::ofstream& rOFStream)
 {
     if ( !m_sWhiteSpace.isEmpty() )
-        io_rOFStream << m_sWhiteSpace.getStr();
+        rOFStream << m_sWhiteSpace.getStr();
     if ( !m_sExtractCom.isEmpty() )
-        io_rOFStream << "#. " << m_sExtractCom.getStr() << std::endl;
+        rOFStream << "#. " << m_sExtractCom.getStr() << std::endl;
     if ( !m_sKeyId.isEmpty() )
-        io_rOFStream << "#. " << m_sKeyId.getStr() << std::endl;
+        rOFStream << "#. " << m_sKeyId.getStr() << std::endl;
     if ( !m_sReference.isEmpty() )
-        io_rOFStream << "#: " << m_sReference.getStr() << std::endl;
+        rOFStream << "#: " << m_sReference.getStr() << std::endl;
     if ( m_bFuzzy )
-        io_rOFStream << "#, fuzzy" << std::endl;
+        rOFStream << "#, fuzzy" << std::endl;
     if ( !m_sContext.isEmpty() )
-        io_rOFStream << "msgctxt "
-                     << ImplGenMsgString(m_sContext).getStr() << std::endl;
-    io_rOFStream << "msgid "
-                 << ImplGenMsgString(ImplEscapeText(m_sUnTransStr)).getStr()
-                 << std::endl;
-    io_rOFStream << "msgstr "
-                 << ImplGenMsgString(ImplEscapeText(m_sTransStr)).getStr()
-                 << std::endl;
+        rOFStream << "msgctxt "
+                  << ImplGenMsgString(m_sContext).getStr() << std::endl;
+    rOFStream << "msgid "
+              << ImplGenMsgString(m_sUnTransStr).getStr() << std::endl;
+    rOFStream << "msgstr "
+              << ImplGenMsgString(m_sTransStr).getStr() << std::endl;
 }
 
+//Read from file
+void GenPoEntry::readFromFile(std::ifstream& rIFStream)
+{
+    m_sWhiteSpace = "\n";
+    OString* pLastMsg = 0;
+    std::string sTemp;
+    getline(rIFStream,sTemp);
+    while(!rIFStream.eof())
+    {
+        OString sLine = OString(sTemp.data(),sTemp.length());
+        if (ImplStartsWith(sLine,"#. "))
+        {
+            if (sLine.getLength()==7)
+                m_sKeyId = sLine.copy(3);
+            else
+                m_sExtractCom = sLine.copy(3);
+        }
+        else if (ImplStartsWith(sLine,"#: "))
+        {
+            m_sReference = sLine.copy(3);
+        }
+        else if (ImplStartsWith(sLine,"#, fuzzy"))
+        {
+            m_bFuzzy = true;
+        }
+        else if (ImplStartsWith(sLine,"msgctxt "))
+        {
+            m_sContext = ImplGenNormString(sLine.copy(8));
+            pLastMsg = &m_sContext;
+        }
+        else if (ImplStartsWith(sLine,"msgid "))
+        {
+            m_sUnTransStr = ImplGenNormString(sLine.copy(6));
+            pLastMsg = &m_sUnTransStr;
+        }
+        else if (ImplStartsWith(sLine,"msgstr "))
+        {
+            m_sTransStr = ImplGenNormString(sLine.copy(7));
+            pLastMsg = &m_sTransStr;
+        }
+        else if (ImplStartsWith(sLine,"\"") && pLastMsg)
+        {
+            *pLastMsg += ImplGenNormString(sLine);
+        }
+        else
+            break;
+        getline(rIFStream,sTemp);
+    }
+    if (m_sKeyId.isEmpty())
+        genKeyId();
+ }
+
 //Class PoEntry
 
 //Split string at the delimiter char
@@ -159,8 +230,122 @@ void ImplSplitAt(const OString& rSource, const sal_Char 
nDelimiter,
     o_vParts.push_back(rSource.copy(nLastSplit));
 }
 
+//Unescape sdf string
+OString ImplUnEscapeSDFText(const OString& rText,const bool bHelpText = false)
+{
+    if ( bHelpText )
+        return ImplUnEscapeText(rText,"\\<\\>\\\"\\\\","<>\"\\");
+    else
+        return ImplUnEscapeText(rText,"\\n\\t\\r","\n\t\r");
+}
+
+//Miminize the length of the regular expression result
+void ImplMinimize(const OUString& rText, Regexpr& io_rRegExp, re_registers& 
io_rRegs)
+{
+    re_registers aPrevRegs;
+    const sal_Int32 nStart = io_rRegs.start[0];
+    do
+    {
+        const OUString sTemp = rText.copy(0,io_rRegs.end[0]-1);
+        memcpy(static_cast<void*>(&aPrevRegs), static_cast<void*>(&io_rRegs),
+               sizeof(re_registers));
+        memset(static_cast<void*>(&io_rRegs), 0, sizeof(re_registers));
+        io_rRegExp.set_line(sTemp.getStr(),sTemp.getLength());
+        io_rRegExp.re_search(&io_rRegs,nStart);
+    } while(io_rRegs.num_of_match);
+
+    memcpy(static_cast<void*>(&io_rRegs),static_cast<void*>(&aPrevRegs),
+           sizeof(re_registers));
+    io_rRegExp.set_line(rText.getStr(),rText.getLength());
+}
+
+//Find all special tag in a string using a regular expression
+void ImplFindAllTag(const OString& rText,std::vector<OString>& o_vFoundTags)
+{
+    ::com::sun::star::util::SearchOptions aOptions;
+    aOptions.algorithmType = ::com::sun::star::util::SearchAlgorithms_REGEXP;
+    aOptions.searchFlag = ::com::sun::star::util::SearchFlags::NORM_WORD_ONLY;
+    aOptions.searchString = "<[/]?[a-z_\\-]+(| +[a-z]+=\".*\") *[/]?>";
+    ::com::sun::star::uno::Reference<
+         ::com::sun::star::i18n::XExtendedTransliteration > xTrans;
+
+    Regexpr aRegExp(aOptions,xTrans);
+    const OUString sTemp(OStringToOUString(rText,RTL_TEXTENCODING_UTF8));
+    aRegExp.set_line(sTemp.getStr(),sTemp.getLength());
+
+    re_registers aRegs;
+    memset(static_cast<void*>(&aRegs), 0, sizeof(re_registers));
+    sal_Int32 nStart = 0;
+    o_vFoundTags.resize(0);
+    aRegExp.re_search(&aRegs,nStart);
+    while(aRegs.num_of_match)
+    {
+        ImplMinimize(sTemp,aRegExp,aRegs);
+        o_vFoundTags.push_back(
+                rText.copy(aRegs.start[0],aRegs.end[0]-aRegs.start[0]));
+        nStart = aRegs.end[0];
+        memset(static_cast<void*>(&aRegs), 0, sizeof(re_registers));
+        aRegExp.re_search(&aRegs,nStart);
+    }
+}
+
+//Escape special tags
+OString ImplEscapeTags(const OString& rText)
+{
+    typedef std::vector<OString> StrVec;
+    const StrVec vTagsForEscape =
+                  { "ahelp", "link", "item", "emph", "defaultinline",
+                    "switchinline", "caseinline", "variable",
+                    "bookmark_value", "image", "embedvar", "alt" };
+    StrVec vFoundTags;
+    ImplFindAllTag(rText,vFoundTags);
+    OString sResult = rText;
+    for(StrVec::const_iterator pFound  = vFoundTags.begin();
+        pFound != vFoundTags.end(); ++pFound)
+    {
+        bool bEscapeThis = false;
+        for(StrVec::const_iterator pEscape = vTagsForEscape.begin();
+            pEscape != vTagsForEscape.end(); ++pEscape)
+        {
+            if (ImplStartsWith(*pFound,"<" + *pEscape) ||
+                *pFound == "</" + *pEscape + ">")
+            {
+                bEscapeThis = true;
+                break;
+            }
+        }
+        if (bEscapeThis || *pFound=="<br/>" || *pFound =="<help-id-missing/>")
+        {
+            OString sToReplace = "\\<" + pFound->copy(1,pFound->getLength()-2).
+                                           replaceAll("\"","\\\"") + "\\>";
+            sResult = sResult.replaceAll(*pFound, sToReplace);
+        }
+    }
+    return sResult;
+}
+
+//Escape to get sdf/merge string
+OString ImplEscapeSDFText(const OString& rText,const bool bHelpText = false)
+{
+    if ( bHelpText )
+        return ImplEscapeTags(rText.replaceAll("\\","\\\\"));
+    else
+        return ImplEscapeText(rText,"\n\t\r","\\n\\t\\r");
+}
 
 
+//Default constructor
+PoEntry::PoEntry()
+    : GenPoEntry()
+    , m_sSourceFile( OString() )
+    , m_sGroupId( OString() )
+    , m_sLocalId( OString() )
+    , m_sResourceType( OString() )
+    , m_eType( TTEXT )
+    , m_sHelpText( OString() )
+{
+}
+
 //Construct PoEntry from sdfline
 PoEntry::PoEntry(const OString& rSDFLine, const TYPE eType)
     : m_sSourceFile( OString() )
@@ -168,39 +353,20 @@ PoEntry::PoEntry(const OString& rSDFLine, const TYPE 
eType)
     , m_sLocalId( OString() )
     , m_sResourceType(OString() )
     , m_eType( TTEXT )
+    , m_sHelpText( OString() )
 {
-    setWhiteSpace("\n");
     std::vector<OString> vParts;
     ImplSplitAt(rSDFLine,'\t',vParts);
     if(vParts.size()!=15) throw;
 
     m_sSourceFile = vParts[SOURCEFILE].
                         copy(vParts[SOURCEFILE].lastIndexOf("\\")+1);
-    setReference(m_sSourceFile);
+    m_sResourceType = vParts[RESOURCETYPE];
     m_sGroupId = vParts[GROUPID];
     m_sLocalId = vParts[LOCALID];
-    m_sResourceType = vParts[RESOURCETYPE];
     m_eType = eType;
     m_sHelpText = vParts[HELPTEXT];
-
-    OString sContext = m_sGroupId + "\\n" +
-                       (m_sLocalId.isEmpty() ? "" : m_sLocalId + "\\n") +
-                       m_sResourceType;
-    switch(eType){
-    case TTEXT:
-        sContext += ".text"; break;
-    case TQUICKHELPTEXT:
-        sContext += ".quickhelptext"; break;
-    case TTITLE:
-        sContext += ".title"; break;
-    default:
-        throw; break;
-    }
-    setContext(sContext);
-    setExtractCom(m_sHelpText);
-
     setUnTransStr(vParts[eType]);
-    genKeyId();
 }
 
 //Destructor
@@ -208,16 +374,22 @@ PoEntry::~PoEntry()
 {
 }
 
-//Unescape sdf text
-OString ImplUnEscapeSDFText(const OString& rText,const bool bHelpText = false)
+//Get translation string in sdf/merge format
+OString PoEntry::getUnTransStr() const
 {
-    if ( bHelpText )
-        return ImplUnEscapeText(rText,"\\<\\>\\\"\\\\","<>\"\\");
-    else
-        return ImplUnEscapeText(rText,"\\n\\t\\r","\n\t\r");
+    return ImplEscapeSDFText(GenPoEntry::getUnTransStr(),
+                             m_sSourceFile.endsWith(".xhp"));
+}
+
+//Get translated string in sdf/merge format
+OString PoEntry::getTransStr() const
+{
+    return ImplEscapeSDFText(GenPoEntry::getTransStr(),
+                             m_sSourceFile.endsWith(".xhp"));
+
 }
 
-//Set translation text when input is in sdf format
+//Set translation string when input is in sdf format
 void PoEntry::setUnTransStr(const OString& rUnTransStr)
 {
     GenPoEntry::setUnTransStr(
@@ -225,7 +397,7 @@ void PoEntry::setUnTransStr(const OString& rUnTransStr)
                         rUnTransStr,m_sSourceFile.endsWith(".xhp")));
 }
 
-//Set translated text when input is in sdf format
+//Set translated string when input is in sdf format
 void PoEntry::setTransStr(const OString& rTransStr)
 {
     GenPoEntry::setTransStr(
@@ -233,6 +405,60 @@ void PoEntry::setTransStr(const OString& rTransStr)
                         rTransStr,m_sSourceFile.endsWith(".xhp")));
 }
 
+//Write to file
+void PoEntry::writeToFile(std::ofstream& rOFStream)
+{
+    setWhiteSpace("\n");
+    setExtractCom(m_sHelpText);
+    setReference(m_sSourceFile);
+
+    OString sContext = m_sGroupId + "\n" +
+                       (m_sLocalId.isEmpty() ? "" : m_sLocalId + "\n") +
+                       m_sResourceType;
+    switch(m_eType){
+    case TTEXT:
+        sContext += ".text"; break;
+    case TQUICKHELPTEXT:
+        sContext += ".quickhelptext"; break;
+    case TTITLE:
+        sContext += ".title"; break;
+    default:
+        throw; break;
+    }
+    setContext(sContext);
+    genKeyId();
+    GenPoEntry::writeToFile(rOFStream);
+}
+
+
+//Read from file
+void PoEntry::readFromFile(std::ifstream& rIFStream)
+{
+    GenPoEntry::readFromFile(rIFStream);
+    m_sSourceFile = getReference();
+
+    OString sContext =  getContext();
+    m_sGroupId = sContext.getToken(0,'\n');
+
+    if (sContext.indexOf('\n')==sContext.lastIndexOf('\n'))
+        m_sResourceType = sContext.getToken(1,'\n').getToken(0,'.');
+    else
+    {
+        m_sLocalId = sContext.getToken(1,'\n');
+        m_sResourceType = sContext.getToken(2,'\n').getToken(0,'.');
+    }
+    if (sContext.endsWith(".text"))
+        m_eType = TTEXT;
+    else if (sContext.endsWith(".quickhelptext"))
+        m_eType = TQUICKHELPTEXT;
+    else if (sContext.endsWith(".title"))
+        m_eType = TTITLE;
+    else
+        throw;
+
+    m_sHelpText = getExtractCom();
+}
+
 //Class PoHeader
 
 //Get actual time in "YEAR-MO-DA HO:MI+ZONE" form
diff --git a/l10ntools/source/renewpo.cxx b/l10ntools/source/renewpo.cxx
index a6e1273..7e567f0 100644
--- a/l10ntools/source/renewpo.cxx
+++ b/l10ntools/source/renewpo.cxx
@@ -63,7 +63,7 @@ void HandleLanguage(struct dirent* pLangEntry, const OString& 
rPath,
     //Generate and open sdf
     cout << "Process start with language: " <<  LangEntryName.getStr() << endl;
     system( (rpo2loPath +
-            " -i " + rPath.getStr() + LangEntryName +
+            " -i " + rPath + "/" + LangEntryName +
             " -o " + SDFFileName +
             " -l " + LangEntryName +
             " -t " + rSDFPath).getStr());
@@ -77,7 +77,7 @@ void HandleLanguage(struct dirent* pLangEntry, const OString& 
rPath,
     while(!aSDFInput.eof())
     {
         OString sActUnTrans = sLine;
-        OString sPath = rPath + LangEntryName;
+        OString sPath = rPath + "/"+ LangEntryName;
         OString sActSourcePath = GetPath(sPath,sActUnTrans);
         //Make new po file, copy header with some changes
         if (!aOutPut.is_open())
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to