<% // ----------------------------------------------------------------------- // File: MergeTopicsWithTemplate.hnd.pas // // Author: Jens Kallup - paule32 // Rights: (c) 2023 kallup non-profit. // ----------------------------------------------------------------------- // User Actions required (if they don't exists as Variable): // 1. create Topic, named with "Vorlage", // 2. change the constant "sTemplate" with the name, that you give under // point 1. // 3. in the created Topic, add "sBodyMark" -> this mark will be used, to // sign, where the content of the normal Topic should be appear. // 4. set sOutFiles directory for content output location // ----------------------------------------------------------------------- const sDefaultHndDirectory = 'E:\HelpNDoc\'; // important !!! const sDefaultHndTemplate = 'TestTemplate'; // ... const sDefaultHndOutput = 'Output\MyChm'; // ,,, const sLibFiles = 'E:\Projekte\Temp\'; // default output directory const sTemplate = 'Vorlage'; // the Template topic name const sUserTOC = 'Vorlage_TOC'; // table of context template const sBuildTyp = 'chm'; // the build type // ----------------------------------------------------------------------- // EUA - End of User Actions. // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // @brief Template setting's // ----------------------------------------------------------------------- const TEMPLATE_COUNT = 5; type rTemplateRecord = record _mark: String; // content mark in topic _prop: String; // property name _temp: String; // library item name _cont: String; // content _file: String; // file name, if source is type of file end; var aTemplates : Array of rTemplateRecord = ( (_mark: '[::Template_Head::]'; _prop: 'userLib_Head'; _temp: 'Template_Head'; _cont: ''; _file: 'head.html'), (_mark: '[::Template_Menu::]'; _prop: 'userLib_Menu'; _temp: 'Template_Menu'; _cont: ''; _file: 'menu.html'), (_mark: '[::Template_Body::]'; _prop: 'userLib_Body'; _temp: 'Template_Body'; _cont: ''; _file: 'body.html'), (_mark: '[::Template_Foot::]'; _prop: 'userLib_Foot'; _temp: 'Template_Foot'; _cont: ''; _file: 'foot.html'), (_mark: '[::Template_Copy::]'; _prop: 'userLib_Copy'; _temp: 'Template_Copy'; _cont: ''; _file: 'copy.html')); const sHeadMark = '[::Template_Head::]'; const sMenuMark = '[::Template_Menu::]'; const sBodyMark = '[::Template_Body::]'; const sFootMark = '[::Template_Foot::]'; const sCopyMark = '[::Template_Copy::]'; const HndPTMark = '[::HndProjectTitle::]'; const sReminder = ''; // convert reminder const sDeleteTemp = 'yes'; // delete output folder ? const KIND_SNIPPET = 7; const KIND_HTML = 6; var userLib_BuildType: String; var userLib_Files : String; var userLib_Template : String; var userLib_BodyMark : String; var userLib_Reminder : String; var userLib_DeleteOld: String; var oEditor, oEditorTemp : TObject; var oSnippet : TObject; var oTempMem : TMemoryStream; var oFileNameList : TStringList; var oFileStrings : TStringList; var sTopicID, sRootTopicID: String; var sExternFile: String; var kTopicID: Integer; var sCaptStr, sTempStr, sTmpStr : String; var sTOCid: String; var sHtmlStr : String; var sFileContent : String; var sProjectName : String; var sProjectFolder: String; var sKeywordID : String; var iKeywordLevel : Integer; var sDefaultTopicID : String; var sDefaultBuildID : String; var sDefaultLogFile : String = 'project.log'; var sDefaultIdxFile : String = 'index.hhk'; var sDefaultTocFile : String = 'toc.hhc'; var sDefaultTocFont : String = 'Arial,10,0'; var cssOutput: String; var aTopicList : THndTopicsInfoArray; var aLibItems : THndLibraryItemsInfoArray; var aKeywordList : THndKeywordsInfoArray; var aBuildList : THndBuildInfoArray; var aAssociatedTopics: array of string; var iCounter, opt: Integer; var nBlocLevel: integer = 0; var nCurKeyword, nCurKeywordLevel, nAssociatedTopic: integer; var sCurrentKeyword, sRelativeTopic: string; var aBreadCrumb: array of String; var nCurParent, nTopicKind, nHeaderKind, nFooterKind: integer; var nIconIndex: integer; var sTopicUrl: string; var sTopicHeader: String; var sTopicFooter: String; var sHtmlTemplateStr: String; var ntmp, ntmpcnt, nDif2, nClose2, nCurTopic2: Integer; var nCurTopicLevel2: integer; var stmp, sTOCStr : String; // -------------------------------------------------- // List of generated topic, excluding hidden in TOC // -------------------------------------------------- procedure createTOCcontent; var nCurTopic, nCurTopicLevel: integer; var nDif, nClose: Integer; var sl: TStringList; begin aTopicList := HndTopicsEx.GetTopicListGenerated(True, False); for nCurTopic := 0 to length(aTopicList) - 1 do begin HndGeneratorInfo.CurrentTopic := aTopicList[nCurTopic].id; // Is it hidden in TOC ? if (aTopicList[nCurTopic].Visibility <> 0) then continue; // Topic data nTopicKind := aTopicList[nCurTopic].Kind; nCurTopicLevel := HndTopics.GetTopicLevel(HndGeneratorInfo.CurrentTopic); nIconIndex := HndTopics.GetTopicIconIndex(HndGeneratorInfo.CurrentTopic) + 1; // Close the previous topics if ((nCurTopic > 0) and (nCurTopicLevel < HndTopics.GetTopicLevel(aTopicList[nCurTopic - 1].id))) then begin nDif := HndTopics.GetTopicLevel(aTopicList[nCurTopic - 1].id) - nCurTopicLevel; for nClose := 0 to nDif - 1 do begin stmp := stmp + ''; nBlocLevel := nBlocLevel - 1; end; end; stmp := stmp + '
  • ' + HTMLEncode(HndTopics.GetTopicCaption(HndGeneratorInfo.CurrentTopic)) + '
  • '; if (HndTopicsEx.GetTopicDirectChildrenCountGenerated(HndGeneratorInfo.CurrentTopic, True) > 0) then begin stmp := stmp + ''; nBlocLevel := nBlocLevel - 1; end; end; sTOCStr := stmp; end; // ----------------------------------------------------------------------- // this function check, if the user variables exists, else they will not // be overwrite - because they are already defined on Top of this Code // (at the User-Actions List) ... // ----------------------------------------------------------------------- procedure checkVar(a1,a2,a3: String; var a4: String); begin if not HndTopicsProperties.GetTopicCustomPropertyExists(a1, a2) then HndTopicsProperties.SetTopicCustomPropertyValue (a1, a2, a3); a4 := HndTopicsProperties.GetTopicCustomPropertyValue (a1, a2) ; end; procedure CheckUserVariables(aTopicID: String); const userLib_PropFiles = 'userLib_Files' ; const userLib_PropBuildType = 'userLib_BuildType'; const userLib_PropDeleteOld = 'userLib_DeleteOld'; const userLib_PropTemplate = 'userLib_Template' ; const userLib_PropReminder = 'userLib_Reminder' ; const userLib_PropHeadMark = 'userLib_THead' ; const userLib_PropMenuMark = 'userLib_TMenu' ; const userLib_PropBodyMark = 'userLib_TBody' ; const userLib_PropFootMark = 'userLib_TFoot' ; var dummy: String; begin checkVar(aTopicID, userLib_PropFiles , sLibFiles , dummy); checkVar(aTopicID, userLib_PropBuildType, sBuildTyp , userLib_BuildType); checkVar(aTopicID, userLib_PropDeleteOld, sDeleteTemp, userLib_DeleteOld); checkVar(aTopicID, userLib_PropTemplate , sTemplate , userLib_Template ); checkVar(aTopicID, userLib_PropReminder , sReminder , userLib_Reminder ); checkVar(aTopicID, userLib_PropHeadmark , sHeadMark , dummy ); checkVar(aTopicID, userLib_PropMenumark , sHeadMark , dummy ); checkVar(aTopicID, userLib_PropBodymark , sBodyMark , dummy ); checkVar(aTopicID, userLib_PropFootmark , sFootMark , dummy ); end; function GetCompatibilityModeMeta(): string; var sVersion: string; begin Result := ''; sVersion := HndGeneratorInfo. GetCustomSettingValue('IECompatibilityMode'); if Copy(sVersion, 1, 3) = 'IE=' then result := Format('', [sVersion]); end; function GetCustomCss: string; begin result := HndGeneratorInfo. GetCustomSettingValue('CustomCss'); if (result <> '') then result := ''; end; function GetCustomJs: string; begin result := HndGeneratorInfo.GetCustomSettingValue('CustomJs'); if (result <> '') then result := ''; end; // Returns the footer function GetTemplateHtmlFooter: string; begin result := HndGeneratorInfo.GetCustomSettingValue('Footer'); end; // Returns the description of the topic function GetTopicDescription: string; begin // Get value result := HndTopics.GetTopicDescription(HndGeneratorInfo.CurrentTopic); // Empty ? Use project's description instead if (result = '') then result := HndProjects.GetProjectSummary; end; // ----------------------------------------------------------------------- // @brief replace german umlauts in given text, and return the result. // ----------------------------------------------------------------------- function replaceGermanUmlauts(var s1: String; mode: Integer): String; begin Result := s1; if mode = 1 then begin Result := StringReplace(Result,'ü','ü' ,[rfReplaceAll]); Result := StringReplace(Result,'Ü','Ü' ,[rfReplaceAll]); Result := StringReplace(Result,'ö','ö' ,[rfReplaceAll]); Result := StringReplace(Result,'Ö','Ö' ,[rfReplaceAll]); Result := StringReplace(Result,'ä','ä' ,[rfReplaceAll]); Result := StringReplace(Result,'Ä','Ä' ,[rfReplaceAll]); Result := StringReplace(Result,'ß','ß',[rfReplaceAll]); end else begin Result := StringReplace(Result,'ü','u' ,[rfReplaceAll]); Result := StringReplace(Result,'Ü','U' ,[rfReplaceAll]); Result := StringReplace(Result,'ö','o' ,[rfReplaceAll]); Result := StringReplace(Result,'Ö','O' ,[rfReplaceAll]); Result := StringReplace(Result,'ä','a' ,[rfReplaceAll]); Result := StringReplace(Result,'Ä','A' ,[rfReplaceAll]); Result := StringReplace(Result,'ß','sz',[rfReplaceAll]); end; end; // ----------------------------------------------------------------------- // Entry point of this Pascal-Script ... // ----------------------------------------------------------------------- begin // finally try try // exception try try // Special encoding needs to be done for CHM documentation HndGeneratorInfo.ForceOutputEncoding := True; createTOCcontent; // --------------------------------------------------------------- // first, we look how many Topic exists. If the Template Topic // is in the Project, then we read the contents of this Template, // and insert it to each Topic, we can found ... // --------------------------------------------------------------- aTopicList := HndTopics.GetTopicList(false); for iCounter := 0 to Length(aTopicList) - 1 do begin if aTopicList[iCounter].Caption = sTemplate then begin sTopicID := aTopicList[iCounter].ID; CheckUserVariables(sTopicID); break; end; end; // --------------------------------- // sanity check, if Topic found ... // --------------------------------- if Length(Trim(sTopicID)) < 1 then begin ShowMessage('Error:' + #13#10 + 'Template Topic: ' + sTemplate + '.' + #13#10 + 'does not exists, aborted.'); exit; end; oEditor := HndEditor.CreateTemporaryEditor; oEditorTemp := HndEditor.CreateTemporaryEditor; oTempMem := TMemoryStream.Create; // ----------------------------------------------------- // now, we replace the (Snippet-Content) named "Text" // with the given Library Item content ... // ----------------------------------------------------- aLibItems := HndLibraryItems.GetItemList([6]); if aLibItems.Count - 1 < 0 then begin ShowMessage('Warning:' + #13#10 + 'No Library-Item for replace Text available.'); exit; end; // ---------------------------------------------- // here, we catch the Template Topic content ... // ---------------------------------------------- oTempMem.Clear; oTempMem := HndTopics.GetTopicContent(sTopicID); HndEditor.Clear(oEditor); HndEditor.SetContent(oEditor,oTempMem); sHtmlStr := HndEditor.GetContentAsHtml(oEditor,cssOutput); // --------------------------------------------------------- // before we do something, we check, if the normal Topic // is already merged with Template Topic content ... // --------------------------------------------------------- if Pos(userLib_Reminder,sHtmlStr) > 0 then begin ShowMessage('Warning:' + #13#10 + 'Topic is already merged with Template Topic content.'); exit; end; // --------------------------------------------------------- // for each Snippet, we merge the normal Topic content with // the content of the Template Topic ... // --------------------------------------------------------- oFileStrings := TStringList.Create; for iCounter := 0 to aLibItems.Count - 1 do begin sTopicID := aLibItems[iCounter].ID; sTempStr := aLibItems[iCounter].Caption; kTopicID := aLibItems[iCounter].Kind; if Pos(sTempStr,sHtmlStr) > 0 then begin oTempMem.Clear; case kTopicID of 7: begin oTempMem := HndLibraryItems.GetItemContent(sTopicID); HndEditor.Clear(oEditorTemp); HndEditor.SetContent(oEditorTemp,oTempMem); sTempStr := HndEditor.GetContentAsHtml(oEditorTemp,cssOutput); end; 6: begin if HndLibraryItems.GetItemSource(sTopicID) = 2 then begin sExternFile := sDefaultHndDirectory + 'Templates\chm\' + HndBuilds.GetBuildTemplate( HndGeneratorInfo.CurrentBuildId) + '\' + HndLibraryItems.GetItemUrlFileAbsolute(sTopicID); if not FileExists(sExternFile) then raise Exception.Create('template item file not found.'); oFileStrings.Clear; oFileStrings.LoadFromFile(sExternFile); sTempStr := oFileStrings.Text; end; end; end; sHtmlStr := StringReplace( sHtmlStr,aLibItems[iCounter].Caption, sTempStr,[rfReplaceAll]); end; end; // ------------------------------------------------------------- // now, we have add the Snippet's - we replace the normal Topic // content with "sHtmlStr" -> [::BODY::] ... // ------------------------------------------------------------- sHtmlTemplateStr := sHtmlStr; //---- // todo // sProjectFolder := userLib_Files + ChangeFileExt( // ExtractFileName(HndProjects.GetProjectName),'') + '_html\'; sProjectFolder := Trim(userLib_Files) + 'output\'; // --------------------------------------------------- // depend on DeleteDir, we delete the output folder // before we write the new topic files ... // --------------------------------------------------- if DirectoryExists(sProjectFolder) then begin if CompareStr(LowerCase(userLib_DeleteOld),'yes') = 0 then opt := 1 else if CompareStr(LowerCase(userLib_DeleteOld),'no' ) = 0 then opt := 0 else raise Exception.Create('boolean String: yes/no expected'); if opt = 1 then RemoveDir(sProjectFolder); end; // --------------------------------------------------- // then, we create fresh, empty folder ... // --------------------------------------------------- sProjectFolder := Trim(sProjectFolder); if not DirectoryExists(sProjectFolder) then if not CreateDir(sProjectFolder) then begin raise Exception.Create( 'Project Directory could not be created: ' + #13#10 + sProjectFolder); end; // ---------------------------- // write project file ... // ---------------------------- sDefaultTopicID := HndProjects.GetProjectDefaultTopic(); sDefaultTopicID := HndTopics .GetTopicHelpId(sDefaultTopicId); // -------------------------------------------- // check, if build already present, if so then // delete this build ... // -------------------------------------------- aBuildList := HndBuilds.GetBuildList; for iCounter := 0 to Length(aBuildList) - 1 do begin opt := CompareStr(aBuildList[iCounter].Name,userLib_BuildType + '_build'); if opt == 0 then HndBuilds.DeleteBuild(aBuildList[iCounter].ID); end; sDefaultBuildID := HndBuilds.CreateBuild; HndBuilds.SetBuildKind (sDefaultBuildID,userLib_BuildType); HndBuilds.SetBuildName (sDefaultBuildID,userLib_BuildType + '_build'); if (CompareStr(LowerCase (userLib_BuildType),'chm' ) = 0) then HndBuilds.SetBuildOutput (sDefaultBuildID,Trim(userLib_Files) + 'index.chm') else if (CompareStr(LowerCase (userLib_BuildType),'htm' ) = 0) or (CompareStr(LowerCase (userLib_BuildType),'html') = 0) then HndBuilds.SetBuildOutput (sDefaultBuildID,userLib_Files); HndBuilds.MoveBuildFirst (sDefaultBuildID); HndBuilds.SetBuildTemplate (sDefaultBuildID,sDefaultHndTemplate); HndBuilds.SetBuildEnabled (sDefaultBuildID,true); sDefaultBuildID := HndBuilds.GetBuildOutput(sDefaultBuildID); sDefaultLogFile := sProjectFolder + sDefaultLogFile; sDefaultTocFile := sProjectFolder + sDefaultTocFile; sDefaultIdxFile := sProjectFolder + sDefaultIdxFile; sFileContent := '[OPTIONS]' + #13#10 + 'Compatibility=1.1 or later' + #13#10 + 'Display compile progress=Yes' + #13#10 + 'Full-text search=Yes' + #13#10 + 'Default Font=' + Format('%s', [sDefaultTocFont]) + #13#10 + 'Error log file=' + Format('%s', [sDefaultLogFile]) + #13#10 + 'Contents file=' + Format('%s', [sDefaultTocFile]) + #13#10 + 'Index file=' + Format('%s', [sDefaultIdxFile]) + #13#10 + 'Compiled file=' + Format('%s', [sDefaultBuildID]) + #13#10 + 'Default topic=' + Format('%s.htm', [sDefaultTopicID]) + #13#10 + 'Language=' + Format('0x%.4x', [HndProjects.GetProjectLanguage()]) + #13#10 + 'Title=' + Format('%s', [HndProjects.GetProjectTitle ()]) + #13#10 + '' + #13#10 + '[WINDOWS]' + #13#10 + Format('Main="%s","%s","%s","%s","%s","%s","%s","%s","%s",%s,%d,%s' + ',[%d,%d,%d,%d],0xB0000,,,%d,0,0,0', [ HndProjects.GetProjectTitle, sDefaultTocFile, sDefaultIdxFile, sDefaultTopicID + '.htm', HndBuildsMeta.GetItemMetaStringValue(HndGeneratorInfo.CurrentBuildId, 'WinHomeUrl', sDefaultTopicID + '.htm'), HndBuildsMeta.GetItemMetaStringValue(HndGeneratorInfo.CurrentBuildId, 'WinJump1Url', ''), HndBuildsMeta.GetItemMetaStringValue(HndGeneratorInfo.CurrentBuildId, 'WinJump1Caption', ''), HndBuildsMeta.GetItemMetaStringValue(HndGeneratorInfo.CurrentBuildId, 'WinJump2Url', ''), HndBuildsMeta.GetItemMetaStringValue(HndGeneratorInfo.CurrentBuildId, 'WinJump2Caption', ''), HndBuildsMetaEx.GetChmNavigationPaneStyleHex(HndGeneratorInfo.CurrentBuildId), HndBuildsMeta.GetItemMetaIntValue(HndGeneratorInfo.CurrentBuildId, 'WinTabNavWidth', 200), HndBuildsMetaEx.GetChmButtonVisibilityHex(HndGeneratorInfo.CurrentBuildId), HndBuildsMeta.GetItemMetaIntValue(HndGeneratorInfo.CurrentBuildId, 'WinPosLeft', -1), HndBuildsMeta.GetItemMetaIntValue(HndGeneratorInfo.CurrentBuildId, 'WinPosTop', -1), HndBuildsMeta.GetItemMetaIntValue(HndGeneratorInfo.CurrentBuildId, 'WinPosRight', -1), HndBuildsMeta.GetItemMetaIntValue(HndGeneratorInfo.CurrentBuildId, 'WinPosBottom', -1), Integer(not HndBuildsMeta.GetItemMetaBoolValue(HndGeneratorInfo.CurrentBuildId, 'WinTabNavVisible', True)) ]) + #13#10#13#10; sFileContent := sFileContent + '[FILES]' + #13#10 ; // Topics for iCounter := 0 to Length(aTopicList) - 1 do begin // 1 => Empty topic if aTopicList[iCounter].Kind <> 1 then begin // userLib_Template ? if CompareStr(aTopicList[iCounter].HelpId,userLib_Template) = 0 then continue; sFileContent := sFileContent + Format('%s.htm', [LowerCase(aTopicList[iCounter].HelpId)]) + #13#10; end; end; oFileNameList := TStringList.Create; oFileNameList.WriteBOM := false; oFileNameList.Add(sFileContent); oFileNameList.SaveToFile(sProjectFolder + 'project.hhp'); oFileNameList.Clear; oFileNameList.Free; // Each individual topics generated... aTopicList := HndTopicsEx.GetTopicListGenerated(False, False); for nCurTopic2 := 0 to Length(aTopicList) - 1 do begin iCounter := nCurTopic2; // Notify about the topic being generated HndGeneratorInfo.CurrentTopic := aTopicList[nCurTopic2].id; if (CompareStr(aTopicList[nCurTopic2].Caption,userLib_Template) = 0) or (CompareStr(aTopicList[nCurTopic2].Caption,sUserTOC) = 0) then continue; // Topic kind nTopicKind := aTopicList[nCurTopic2].Kind; if (nTopicKind = 1) then continue; // Empty topic: do not generate anything // Setup the file name HndGeneratorInfo.CurrentFile := HndTopics.GetTopicHelpId(HndGeneratorInfo.CurrentTopic) + '.htm'; // Topic header nHeaderKind := HndTopics.GetTopicHeaderKind(HndGeneratorInfo.CurrentTopic); sTopicHeader := HndTopics.GetTopicHeaderTextCalculated(HndGeneratorInfo.CurrentTopic); // Topic footer nFooterKind := HndTopics.GetTopicFooterKind(HndGeneratorInfo.CurrentTopic); sTopicFooter := HndTopics.GetTopicFooterTextCalculated(HndGeneratorInfo.CurrentTopic); sFileContent := '' + #13#10 + '' + #13#10 + '' + #13#10 + '' + HTMLEncode(HndTopics.GetTopicCaption(HndGeneratorInfo.CurrentTopic)) + '' + #13#10 + '' + #13#10 + GetCompatibilityModeMeta() + #13#10 + '' + #13#10 + '' + #13#10; // Redirect for URL and Files topic if (nTopicKind = 2) then begin sFileContent := sFileContent + Format('', [ HndTopics.GetTopicUrlLink( HndGeneratorInfo.CurrentTopic)]) + #13#10; end else begin sFileContent := sFileContent + '' + #13#10 + '' + #13#10 + '' + #13#10 + '' + #13#10 + '' + #13#10 + GetCustomCss() + #13#10 + '' + #13#10; end; sFileContent := sFileContent + '' + #13#10 + '' + #13#10 ; (* sFileContent := sFileContent + '
    ' + #13#10 + '
    ' + #13#10 + '

    ' + HTMLEncode(sTopicHeader) + '

    ' + #13#10;*) // ----------------------------------------- // here, we catch the user topic content ... // ----------------------------------------- if not Assigned(oTempMem) then oTempMem := TMemoryStream.Create; oTempMem.Clear; oTempMem := HndTopics.GetTopicContent(aTopicList[iCounter].Id); HndEditor.Clear(oEditor); HndEditor.SetContent(oEditor,oTempMem); sHtmlStr := HndEditor.GetContentAsHtml(oEditor,cssOutput); // user html sHtmlStr := StringReplace( sHtmlTemplateStr, userLib_Bodymark,sHtmlStr,[rfReplaceAll]); sFileContent := sFileContent + '
    ' + #13#10 + sHtmlTemplateStr + #13#10; // body oTempMem.Clear; oTempMem := HndTopics.GetTopicContent(HndTopics.GetCurrentTopic); HndEditor.Clear(oEditor); HndEditor.SetContent(oEditor,oTempMem); sHtmlStr := HndEditor.GetContentAsHtml(oEditor,cssOutput); sTempStr := '
    ' + sHtmlStr + '
    '; sTempStr := StringReplace(sFileContent,'[::Template_Body::]', sTempStr,[rfReplaceAll]); sFileContent := sTempStr; // TOC - Table of Content oTempMem.Clear; oTempMem := HndTopics.GetTopicContent(sTOCid); HndEditor.Clear(oEditor); HndEditor.SetContent(oEditor,oTempMem); sHtmlStr := HndEditor.GetContentAsHtml(oEditor,cssOutput); sTempStr := '
    ' + sHtmlStr + '
    '; sTempStr := StringReplace(sFileContent,'[::Template_TOC::]', sTOCStr,[rfReplaceAll]); sFileContent := sTempStr + '
    ' + #13#10; if nFooterKind <> 2 then begin sFileContent := sFileContent + '' + #13#10 ; end; sFileContent := sFileContent + '' + #13#10 + GetCustomJs() + #13#10 ; sFileContent := sFileContent + '' + #13#10 + '' + #13#10 ; // ------------------------------- // convert Hnd mark's ... // ------------------------------- sFileContent := StringReplace( sFileContent,HndPTMark, HndProjects.GetProjectTitle(), [rfReplaceAll]); // ------------------------------- // finally, convert german umlauts // ------------------------------- sFileContent := replaceGermanUmlauts(sFileContent,1); // ------------------------------ // convert file name umlauts ... // ------------------------------ sTmpStr := HndTopics.GetTopicCaption( HndGeneratorInfo.CurrentTopic) + '.htm'; sTmpStr := replaceGermanUmlauts(sTmpStr,2); // ------------------------------ // write the topic.htm file ... // ------------------------------ oFileNameList := TStringList.Create; try oFileNameList.WriteBOM := false; oFileNameList.Add(sFileContent); stmp := sDefaultHndDirectory + sDefaultHndOutput; if not DirectoryExists(stmp) then CreateDir(stmp); oFileNameList.SaveToFile( stmp + '\' + sTmpStr); finally if Assigned(oFileNameList) then begin oFileNameList.Clear; oFileNameList.Free; end; if Assigned(oTempMem) then begin oTempMem.Clear; oTempMem.Free; end; end; end; // ----------------------------------------------- // at the end, we hold a notice of last editing... // ----------------------------------------------- sRootTopicID := HndTopics.GetProjectTopic(); HndTopicsProperties.SetTopicCustomPropertyValue(sRootTopicId, 'Last HTML Generation', FormatDateTime('yyyy-mm-dd hh:nn:ss', Now)); except on E: Exception do begin ShowMessage('Exception:' + #13#10 + E.Message); end; end; finally // --------------------------- // clear, and free objects ... // --------------------------- if Assigned(oTempMem) then begin oTempMem.Clear; oTempMem.Free; end; HndEditor.DestroyTemporaryEditor(oEditorTemp); HndEditor.DestroyTemporaryEditor(oEditor); end; end. %>