28#include <libxslt/transform.h>
38FILE* fopen_impl(
const fs::path& rPath,
const char* szMode)
41 return _wfopen(rPath.native_file_string_w().c_str(), o3tl::toW(OUString::createFromAscii(szMode).getStr()));
59 (
reinterpret_cast<const xmlChar *
>(idxCaptionStylesheet.
native_file_string().c_str()));
61 (
reinterpret_cast<const xmlChar *
>(idxContentStylesheet.
native_file_string().c_str()));
74 std::string_view aOStr_Path(
Path );
75 OUString aOUStr_Path( OStringToOUString
76 ( aOStr_Path, osl_getThreadTextEncoding() ) );
78 osl::File::getFileURLFromSystemPath( aOUStr_Path, aPathURL );
80 ( aPathURL, osl_getThreadTextEncoding() ) );
81 std::string aStdStr_PathURL( aOStr_PathURL );
82 return aStdStr_PathURL;
86 ( xmlDocPtr doc,
const std::string &EncodedDocPath )
88 std::string aStdStr_EncodedDocPathURL =
getEncodedPath( EncodedDocPath );
93 xmlNodePtr pResNodeCaption = resCaption->xmlChildrenNode;
97 FILE* pFile_docURL = fopen_impl( fsCaptionPureTextFile_docURL,
"w" );
100 fprintf( pFile_docURL,
"%s\n", pResNodeCaption->content );
101 fclose( pFile_docURL );
104 xmlFreeDoc(resCaption);
111 xmlNodePtr pResNodeContent = resContent->xmlChildrenNode;
112 if( pResNodeContent )
115 FILE* pFile_docURL = fopen_impl( fsContentPureTextFile_docURL,
"w" );
118 fprintf( pFile_docURL,
"%s\n", pResNodeContent->content );
119 fclose( pFile_docURL );
122 xmlFreeDoc(resContent);
129 std::vector<std::string> _idList;
131 void append(
const std::string &
id)
133 _idList.push_back(
id);
139 for (
auto const& elem : _idList)
149 if( pFile ==
nullptr )
152 unsigned int nKeyLen = aKeyStr.length();
153 unsigned int nValueLen = aValueStr.length();
154 fprintf( pFile,
"%x ", nKeyLen );
157 if (fwrite( aKeyStr.c_str(), 1, nKeyLen, pFile ) != nKeyLen)
158 fprintf(stderr,
"fwrite to db failed\n");
160 if (fprintf( pFile,
" %x ", nValueLen ) < 0)
161 fprintf(stderr,
"fwrite to db failed\n");
164 if (fwrite( aValueStr.c_str(), 1, nValueLen, pFile ) != nValueLen)
165 fprintf(stderr,
"fwrite to db failed\n");
167 if (fprintf( pFile,
"%c", cLF ) < 0)
168 fprintf(stderr,
"fwrite to db failed\n");
176 typedef std::unordered_map<std::string, Data> DataHashtable;
180 void insert(
const std::string &key,
const std::string &
id)
182 Data &data = _hash[key];
186 void dump_DBHelp(
const fs::path& rFileName )
188 FILE* pFile = fopen_impl( rFileName,
"wb" );
189 if( pFile ==
nullptr )
192 for (
auto const& elem : _hash)
203 static std::string
encode(
const std::string &rIn)
205 const char *
const good =
"!$&'()*+,-.=@_";
206 static const char hex[17] =
"0123456789ABCDEF";
211 if (rtl::isAsciiAlphanumeric (
static_cast<unsigned char>(c))
217 result += hex[
static_cast<unsigned char>(c) >> 4];
226 const std::string& fileB,
const std::string& anchorB,
227 const std::string& jarfileB,
const std::string& titleB)
229 HCDBG(std::cerr <<
"HelpLinker::addBookmark " << thishid <<
" " <<
230 fileB <<
" " << anchorB <<
" " << jarfileB <<
" " << titleB << std::endl);
234 int fileLen = fileB.length();
235 if (!anchorB.empty())
236 fileLen += (1 + anchorB.length());
237 int dataLen = 1 + fileLen + 1 + jarfileB.length() + 1 + titleB.length();
239 std::vector<unsigned char> dataB(dataLen);
241 dataB[
i++] =
static_cast<unsigned char>(fileLen);
243 dataB[
i++] =
static_cast<unsigned char>(j);
244 if (!anchorB.empty())
247 for (
char j : anchorB)
250 dataB[
i++] =
static_cast<unsigned char>(jarfileB.length());
251 for (
char j : jarfileB)
254 dataB[
i++] =
static_cast<unsigned char>(titleB.length());
255 for (
char j : titleB)
258 if( pFile_DBHelp !=
nullptr )
260 std::string aValueStr( dataB.begin(), dataB.end() );
285 std::transform (mod.begin(), mod.end(), mod.begin(),
tocharlower);
295 FILE* pFileHelpText_DBHelp = fopen_impl( helpTextFileName_DBHelp,
"wb" );
298 FILE* pFileDbBase_DBHelp = fopen_impl( dbBaseFileName_DBHelp,
"wb" );
302 HelpKeyword helpKeyword;
307 bool bIndexForExtension =
true;
318 const std::string &xhpFileName = helpFile;
320 if (!
bExtensionMode && xhpFileName.rfind(
".xhp") != xhpFileName.length()-4)
324 "ERROR: input list entry '"
326 <<
"' has the wrong extension (only files with extension .xhp are accepted)");
338 xhpFileNameComplete.append(
'/' + xhpFileName );
339 xhpFile =
fs::path( xhpFileNameComplete );
343 langsourceRoot.
append(
"/" );
352 HCDBG(std::cerr <<
"before compile of " << xhpFileName << std::endl);
354 HCDBG(std::cerr <<
"after compile of " << xhpFileName << std::endl);
360 if (documentPath.compare(0, 1,
"/") == 0)
361 documentPath = documentPath.substr(1);
366 if (documentTitle.empty())
367 documentTitle =
"<notitle>";
369 const std::string& fileB = documentPath;
370 const std::string& jarfileB = documentJarfile;
371 std::string& titleB = documentTitle;
374 addBookmark( pFileDbBase_DBHelp, documentPath, fileB, std::string(), jarfileB, titleB);
376 const std::vector<std::string> *hidlist = streamTable.
appl_hidlist.get();
380 for (
auto & elem : *hidlist)
382 std::string thishid = elem;
385 size_t index = thishid.rfind(
'#');
386 if (
index != std::string::npos)
388 anchorB = thishid.substr(1 +
index);
389 thishid = thishid.substr(0,
index);
391 addBookmark( pFileDbBase_DBHelp, thishid, fileB, anchorB, jarfileB, titleB);
397 if (anchorToLL && !anchorToLL->empty())
400 for (
auto const& elemAnchor : *anchorToLL)
402 const std::string &
anchor = elemAnchor.first;
403 addBookmark(pFileDbBase_DBHelp, documentPath, fileB,
404 anchor, jarfileB, titleB);
405 std::string totalId = fakedHid +
"#" +
anchor;
408 for (
auto const& elem : ll)
410 helpKeyword.insert(elem, totalId);
420 for (
auto const& elem : *helpTextHash)
422 std::string helpTextId = elem.first;
423 const std::string& helpTextText = elem.second;
427 if( pFileHelpText_DBHelp !=
nullptr )
436 xmlDocPtr document = streamTable.
appl_doc;
439 std::string temp =
module;
440 std::transform (temp.begin(), temp.end(), temp.begin(),
tocharlower);
451 if( pFileHelpText_DBHelp !=
nullptr )
452 fclose( pFileHelpText_DBHelp );
453 if( pFileDbBase_DBHelp !=
nullptr )
454 fclose( pFileDbBase_DBHelp );
458 if( pFileHelpText_DBHelp !=
nullptr )
459 fclose( pFileHelpText_DBHelp );
460 if( pFileDbBase_DBHelp !=
nullptr )
461 fclose( pFileDbBase_DBHelp );
463 helpKeyword.dump_DBHelp( keyWordFileName_DBHelp);
471 const std::string &additionalFileName = additionalFile.second;
472 const std::string &additionalFileKey = additionalFile.first;
477 const char* pStr = aNativeStr.c_str();
478 std::cerr << pStr << std::endl;
483 fs::copy( fsAdditionalFileName, fsTargetName );
489 std::string
const * pExtensionPath, std::string
const * pDestination,
490 const OUString* pOfficeHelpPath )
495 if ((!
args.empty()) &&
args[0][0] ==
'@')
497 std::vector<std::string> stringList;
498 std::ifstream fileReader(
args[0].substr(1).c_str());
505 stringList.push_back(token);
513 bool bSrcOption =
false;
514 while (
i <
args.size())
519 if (
i >=
args.size())
521 std::stringstream aStrStream;
522 aStrStream <<
"extension source missing" << std::endl;
532 if (
i >=
args.size())
534 std::stringstream aStrStream;
535 aStrStream <<
"extension destination missing" << std::endl;
543 if (
i >=
args.size())
545 std::stringstream aStrStream;
546 aStrStream <<
"sourceroot missing" << std::endl;
555 if (
i >=
args.size())
557 std::stringstream aStrStream;
558 aStrStream <<
"compactStylesheet missing" << std::endl;
567 if (
i >=
args.size())
569 std::stringstream aStrStream;
570 aStrStream <<
"embeddingStylesheet missing" << std::endl;
579 if (
i >=
args.size())
581 std::stringstream aStrStream;
582 aStrStream <<
"idxtemp missing" << std::endl;
591 if (
i >=
args.size())
593 std::stringstream aStrStream;
594 aStrStream <<
"idxcaption stylesheet missing" << std::endl;
603 if (
i >=
args.size())
605 std::stringstream aStrStream;
606 aStrStream <<
"idxcontent stylesheet missing" << std::endl;
615 if (
i >=
args.size())
617 std::stringstream aStrStream;
618 aStrStream <<
"outputfilename missing" << std::endl;
627 if (
i >=
args.size())
629 std::stringstream aStrStream;
630 aStrStream <<
"module name missing" << std::endl;
639 if (
i >=
args.size())
641 std::stringstream aStrStream;
642 aStrStream <<
"language name missing" << std::endl;
655 std::string addFile, addFileUnderPath;
657 if (
i >=
args.size())
659 std::stringstream aStrStream;
660 aStrStream <<
"pathname missing" << std::endl;
664 addFileUnderPath =
args[
i];
666 if (
i >=
args.size())
668 std::stringstream aStrStream;
669 aStrStream <<
"pathname missing" << std::endl;
673 if (!addFileUnderPath.empty() && !addFile.empty())
687 if( (pExtensionPath && pExtensionPath->length() > 0 && pOfficeHelpPath)
700 std::stringstream aStrStream;
701 aStrStream <<
"-extlangdest is missing" << std::endl;
721 std::stringstream aStrStream;
722 aStrStream <<
"-src must not be used together with -extsource missing" << std::endl;
729 std::stringstream aStrStream;
730 aStrStream <<
"no index dir given" << std::endl;
740 std::stringstream aStrStream;
741 aStrStream <<
"no index caption stylesheet given" << std::endl;
748 OUString aIdxCaptionPathFileURL = *pOfficeHelpPath +
"/idxcaption.xsl";
751 ( aIdxCaptionPathFileURL, osl_getThreadTextEncoding() ) );
752 std::string aStdStr_IdxCaptionPathFileURL( aOStr_IdxCaptionPathFileURL );
763 std::stringstream aStrStream;
764 aStrStream <<
"no index content stylesheet given" << std::endl;
772 OUString aIdxContentPathFileURL = *pOfficeHelpPath +
"/idxcontent.xsl";
775 ( aIdxContentPathFileURL, osl_getThreadTextEncoding() ) );
776 std::string aStdStr_IdxContentPathFileURL( aOStr_IdxContentPathFileURL );
782 std::stringstream aStrStream;
783 aStrStream <<
"no embedding resolving file given" << std::endl;
788 std::stringstream aStrStream;
789 aStrStream <<
"no sourceroot given" << std::endl;
794 std::stringstream aStrStream;
795 aStrStream <<
"no output file given" << std::endl;
800 std::stringstream aStrStream;
801 aStrStream <<
"module missing" << std::endl;
806 std::stringstream aStrStream;
807 aStrStream <<
"language missing" << std::endl;
820 std::string aErrorMsg = error->message;
821 std::string aXMLParsingFile;
822 if( error->file !=
nullptr )
823 aXMLParsingFile = error->file;
824 int nXMLParsingLine = error->line;
829 xmlSetStructuredErrorFunc(
nullptr,
nullptr );
847 const OUString& aOfficeHelpPath,
848 std::u16string_view aExtensionName,
849 std::u16string_view aExtensionLanguageRoot,
850 sal_Int32 nXhpFileCount,
const OUString* pXhpFiles,
851 std::u16string_view aDestination,
855 bool bSuccess =
true;
857 std::vector<std::string>
args;
858 args.reserve(nXhpFileCount + 2);
859 args.push_back(std::string(
"-mod"));
860 OString aOExtensionName =
OUStringToOString( aExtensionName, osl_getThreadTextEncoding() );
861 args.push_back(std::string(aOExtensionName));
863 for( sal_Int32 iXhp = 0 ; iXhp < nXhpFileCount ; ++iXhp )
865 OUString aXhpFile = pXhpFiles[iXhp];
868 args.push_back(std::string(aOXhpFile));
871 OString aOExtensionLanguageRoot =
OUStringToOString( aExtensionLanguageRoot, osl_getThreadTextEncoding() );
872 const char* pExtensionPath = aOExtensionLanguageRoot.getStr();
873 std::string aStdStrExtensionPath = pExtensionPath;
874 OString aODestination =
OUStringToOString(aDestination, osl_getThreadTextEncoding());
875 const char* pDestination = aODestination.getStr();
876 std::string aStdStrDestination = pDestination;
883 aHelpLinker.
main(
args, &aStdStrExtensionPath, &aStdStrDestination, &aOfficeHelpPath );
895 o_rHelpProcessingErrorInfo = e;
900 xmlSetStructuredErrorFunc(
nullptr,
nullptr );
906 OUString aTreeFileURL = OUString::Concat(aExtensionLanguageRoot) +
"/help.tree";
907 osl::DirectoryItem aTreeFileItem;
908 osl::FileBase::RC rcGet = osl::DirectoryItem::get( aTreeFileURL, aTreeFileItem );
909 osl::FileStatus aFileStatus( osl_FileStatus_Mask_FileSize );
910 if( rcGet == osl::FileBase::E_None &&
911 aTreeFileItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None &&
912 aFileStatus.isValid( osl_FileStatus_Mask_FileSize ) )
914 sal_uInt64 ret, len = aFileStatus.getFileSize();
915 std::unique_ptr<char[]> s(
new char[
int(len) ]);
916 osl::File aFile( aTreeFileURL );
917 (void)aFile.open( osl_File_OpenFlag_Read );
918 aFile.read( s.get(), len, ret );
921 XML_Parser
parser = XML_ParserCreate(
nullptr );
922 XML_Status parsed = XML_Parse(
parser, s.get(),
int( len ),
true );
924 if (XML_STATUS_ERROR == parsed)
926 XML_Error nError = XML_GetErrorCode(
parser );
928 o_rHelpProcessingErrorInfo.
m_aErrorMsg = OUString::createFromAscii( XML_ErrorString( nError ) );
std::unordered_map< std::string, LinkedList > Hashtable
std::unordered_map< std::string, std::string > Stringtable
std::deque< std::string > LinkedList
static void writeKeyValue_DBHelp(FILE *pFile, const std::string &aKeyStr, const std::string &aValueStr)
static void StructuredXMLErrorFunction(SAL_UNUSED_PARAMETER void *, xmlErrorPtr error)
bool compileExtensionHelp(const OUString &aOfficeHelpPath, std::u16string_view aExtensionName, std::u16string_view aExtensionLanguageRoot, sal_Int32 nXhpFileCount, const OUString *pXhpFiles, std::u16string_view aDestination, HelpProcessingErrorInfo &o_rHelpProcessingErrorInfo)
static const HelpProcessingException * GpXMLParsingException
static std::string getEncodedPath(const std::string &Path)
std::unique_ptr< IndexerPreProcessor > m_pIndexerPreProcessor
fs::path embeddStylesheet
Stringtable additionalFiles
std::string extensionDestination
fs::path compactStylesheet
void initIndexerPreProcessor()
fs::path indexDirParentName
fs::path idxContentStylesheet
std::string extensionPath
std::string extdestination
std::vector< std::string > helpFiles
L10N_DLLPUBLIC void main(std::vector< std::string > &args, std::string const *pExtensionPath=nullptr, std::string const *pDestination=nullptr, const OUString *pOfficeHelpPath=nullptr)
static void addBookmark(FILE *pFile_DBHelp, std::string thishid, const std::string &fileB, const std::string &anchorB, const std::string &jarfileB, const std::string &titleB)
fs::path idxCaptionStylesheet
xsltStylesheetPtr m_xsltStylesheetPtrCaption
fs::path m_fsContentFilesDirName
xsltStylesheetPtr m_xsltStylesheetPtrContent
IndexerPreProcessor(const fs::path &fsIndexBaseDir, const fs::path &idxCaptionStylesheet, const fs::path &idxContentStylesheet)
fs::path m_fsCaptionFilesDirName
void processDocument(xmlDocPtr doc, const std::string &EncodedDocPath)
std::string document_module
std::unique_ptr< Hashtable > appl_keywords
std::string document_path
std::unique_ptr< Stringtable > appl_helptexts
std::unique_ptr< std::vector< std::string > > appl_hidlist
std::string document_title
void append(const char *in)
std::string native_file_string() const
std::string toUTF8() const
#define SAL_WARN(area, stream)
static std::string encode(const std::string &rIn)
OUString getString(const Any &_rAny)
void copy(const fs::path &src, const fs::path &dest)
void create_directory(const fs::path &indexDirName)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
SbxDecimal::CmpResult compare(SAL_UNUSED_PARAMETER const SbxDecimal &, SAL_UNUSED_PARAMETER const SbxDecimal &)
HelpProcessingErrorClass m_eErrorClass
OUString m_aXMLParsingFile
sal_Int32 m_nXMLParsingLine
HelpProcessingErrorInfo & operator=(const struct HelpProcessingException &e)
std::string m_aXMLParsingFile
HelpProcessingErrorClass m_eErrorClass