WPCubed Product Support

How do I build TOC and index (Delphi)

Hi
I am in the process of building a book with wptools in Delphi. I have to obtain the contents from various database fields and build it into a book. I need to be able to dynamically create a table of contents and an Index.

Can anyone please tell me how to do this ?

Thanks

David

#1 ♥ 0
23.9k Views 4 users read 18 min

As the built in TOC was too unflexible for me I decided to build up one myself 🙂

Before Building the document add a Paragraph and save a Pointer to it (TOCParagraph)

As I'm only using paragraphs to build my Document I used the TParagraph.Name Property to seperate Headlines from Text

e.g. when building the Document and you got a Headline (In my Document I've only got 2 Levels) name the Paragraph "Head_<Counter>".
each sublevel gets a different prefix (to recognise which format to use)

Like:

A. Big Chapter One! -> Name: Head_1
A.1 Subchapter One! -> Name: Subhead_1_1
and so on

then build your Document

now run through all paragraphs and search the name for the prefixes. Each time you find an specific prefix append a new Paragraph to your saved TOC Paragraph. You can get the Text via the Paragraph.GetText () function.
Mark the appended TOCParagraph with toc_ + Paragrpah.Name (so you later know which Content Entry this TOC Entry is related to)

After doing through the all paragraphs again and search for toc_*. If you find one extract the original paragraph name and run through all paragraphs to determine the page the actual paragraph is on.
Append the pagenr to the TOC paragraph.

et voilá a wonderful TOC which is fully formatable =)

headcounter and subheadcounter are global variables and should be reset each time you rebuild the document.

Appending a Headline:

TParagraph *par;  par = target->LastPar->AppendNewPar(true);  par->ASet(WPAT_Alignment,Integer(paralLeft));  par->ASet(WPAT_IndentLeft,500);  par->ASet(WPAT_ParIsOutline,1);  par->Name = "head_" + IntToStr(++headcounter);  if( NewPage )    par->prop = par->prop <<paprNewPage>SetText(Text,headline);  target->CPPosition = MaxInt;  // Possibility to jump to headline via BookmarkMoveTo();  target->BookmarkInput("head_" + IntToStr(headcounter));

Appending Subheadline:

TParagraph *par;  par = target->LastPar->AppendNewPar(true);  par->ASet(WPAT_Alignment,Integer(paralLeft));  par->ASet(WPAT_IndentLeft,500);  par->ASet(WPAT_ParIsOutline,1);  par->Name = "subhead_" + IntToStr(headcounter) + "_" + IntToStr(++subheadcounter);  par->SetText(Text,subheadline);  target->CPPosition = MaxInt;  target->BookmarkInput("subhead_" + IntToStr(headcounter) + "_" + IntToStr(subheadcounter));

Building Document and TOC

TVirtualNode *Category = tv_Teststeps->GetFirst()->FirstChild;

  TParagraph *par, *parPre, *parTOC;
  TWPTextObj *link;
  int isOutline;
  Cardinal style;

  AnsiString parText, searchPar;

  rt_Document->ClearEx(true,true,true);
  rt_Document->ClearBody();

  InitialiseStyles();

  SetHeaderFooter(rt_Document);

  par = rt_Document->FirstPar;
  parTOC = AppendTextToDocument(rt_Document,"");

  while(Category)
  {
    //BuildCategory builds part of the document in rt_Preview
    rt_Preview->ClearEx(true,true,true);
    BuildCategory(Category, true);
    rt_Document->CPPosition = MaxInt;
    rt_Document->SelectionAsString = rt_Preview->AsString;
    Category = Category->NextSibling;
  }

  rt_Document->ReformatAll(true,true);

  par = rt_Document->FirstPar;

  parPre = rt_Preview->FirstPar;

  while(par)
  {
    if(par->Name.SubString(1,5) == "head_")
    {
      // Add Headline to TOC
      parTOC = parTOC->AppendNewPar(true);
      parTOC->Name = "toc_" + par->Name;
      parTOC->ASet(WPAT_Alignment,Integer(paralLeft));
      parTOC->ASet(WPAT_IndentLeft,500);
      parTOC->TabstopAdd(10000,tkRight,tkDots);
      parText = par->GetText(false,false);
      while(parText.Pos("\n") > 0)
        parText = parText.Delete(parText.Pos("\n"),1);
      parTOC->SetText(parText,toc_category);
    }

    if(par->Name.SubString(1,8) == "subhead_")
    {
      // Add Subheadline to TOC
      parTOC = parTOC->AppendNewPar(true);
      parTOC->Name = "toc_" + par->Name;
      parTOC->ASet(WPAT_Alignment,Integer(paralLeft));
      parTOC->ASet(WPAT_IndentLeft,550);
      parTOC->TabstopAdd(10000,tkRight,tkDots);
      parText = par->GetText(false,false);
      while(parText.Pos("\n") > 0)
        parText = parText.Delete(parText.Pos("\n"),1);
      parTOC->SetText(parText,toc_subcategory);
    }

    par = par->NextPar;

  }

  rt_Document->ReformatAll(true,true);

  parTOC = rt_Document->FirstPar;

  while(parTOC)
  {
    if(parTOC->Name.SubString(1,9) == "toc_head_" || parTOC->Name.SubString(1,12) == "toc_subhead_" )
    {
      searchPar = parTOC->Name.Delete(1,4);

      par = rt_Document->FirstPar;

      while(par)
      {
        if( par->Name == searchPar )
        {
          parText = parTOC->GetText(false,false);
          parTOC->SetText("");

          if(parTOC->Name.SubString(1,9) == "toc_head_")
            style = toc_category;
          else
            style = toc_subcategory;

          link = parTOC->AppendNewObjectPair(wpobjHyperlink,parText + "\t" + IntToStr(par->pagenr+1),style);
          link->Source = parTOC->Name.Delete(1,4);
          break;
        }

        par = par->NextPar;
      }
    }

    parTOC = parTOC->NextPar;
  }
  rt_Document->ReformatAll(true,true);

Hope I could help 🙂 Sure this is not the best way to build a TOC but it works 😛

P.S.: Oups just saw that you asked for an Delphi example... well I hope it should be no Problem to translate my example to Delphi. Functions and important Member Names are the same is in Delphi

#2 ♥ 0

Thanks for that reply. I will certainly give it a shot. No problem about the C++ code.. all pretty much the same anyway.

You said there is a built in TOC too?? i have not found that in the documentation ..

Regards

David

#3 ♥ 0

Check out the CreateTableOfContents function in WPTools Help (not WPToolsManual) 🙂

#4 ♥ 0

Got it thanks...
The documentation is rather sparse isnt it..!!
I tried using it but the page numbers are all at 1!!!

I also tried your code, but it does not seem to work.. I get one table of contents entry and thats it... perhaps I have translated it incorrectly to delphi, but I dont think so...

Any thoughts??

Thanks
David

#5 ♥ 0
support

Many thanks to fanderlf for the help!

I have now the possibility to add some comments:

Yes, CreateTableOfContents is a good way to start. It can be seen as an example implementation, too.

It implements one possibility to create a TOC by using a certain attribute of the paragraphs. If you have trouble to find an information in the HLP file pleasye don't mind to check out the source code. (I do not think the refrence is "sparse", for technical reasons it has a lot of nodes though. The PDF does not talk about any of the 1000 aspects WPTools has)

Esspecially the unit WPCtrRich and WPCtrMemo implement high level routines and should be mostly readable. A must-read is the method OnToolbarIconSelection in WPCtrRich.

CreateTableOfContents uses this modes:

TWPCreateTableOfContentsMode = set of (
    wptocAlsoProcessTables, // Also look in tables for marked paragraphs. Only the first paragraph of a cell is checked!
    wptocCreateHyperlinks, // Create hyperlinks for the headlines
    wptocLocateTextAfterBookmark, // use the text after bookmarks as headline
    wptocUseParIsOutline, // only use paragraphs which use the WPAT_ParIsOutline attribute
    wptocCreateOutlineBookmarks, // if WPAT_ParIsOutline then create bookmark if not existing
    wptocCreateHyperlinkNumbers // Place the page numbers in hyperlinks
    );

CreateTableOfContents is documented in the HLP and online:

(You can google it!)

This code can be used to mark a paragraph which should be used as headline:

WPRichText1.ActiveParagraph.ASet(WPAT_ParIsOutline,1);

Since
par.AGetInherited(WPAT_ParIsOutline, outl)

is used to check it, the flag can be also applied to a paragraph stylewhich has been assigned to a paragraph!

Julian

#6 ♥ 0

Hi Julian
thanks for your response.
When I said the documentation is sparce, I am meaning the explanation of HOW to do things, and in many cases the help file simply gives the name of the property/method withiout any explanation of how to use it. Often you have methods with parameters such as ASet which do not explain properly what values are to go in the Value parameter.

With regards to the TOC..
I am now getting a TOC to appear, but am still not being able to get it formatted nicely at all. It is essential for me to be able to have a properly formatted book. This project is a very high level government project with the result being a book which is distributed to every doctor in the country.
I wish to have a nicely formatted table of contents but when I have tried to apply a style to the paragraph, I see no change at all. I seem to have no control over the TOC. I am also not quite sure of the following :
If I apply a par.ASet(WPAT_ParIsOutline,1) to my paragraph, what does it do? Does this make it a header? And I am assuming that by header it is a single line which will preceed the main paragraph. Does this have to be a paragraph on its own followed by the body paragraph?

I also need to be able to generate an index. Is this possible?
Thanks..

David

#7 ♥ 0
support

If I apply a par.ASet(WPAT_ParIsOutline,1) to my paragraph, what does it do? Does this make it a header? And I am assuming that by header it is a single line which will preceed the main paragraph. Does this have to be a paragraph on its own followed by the body paragraph?

It simply markes it. In the CreateTableOfContents method it collects all those paragraphs and creates new text from it. That text is inserted in a certaion field to make it possible to update.

I believe you should check out that source code and create your TOX yourself. You see how it connects the reference objects to bookmark names in the code, too.

Julian

#8 ♥ 0

Hi
I am having endless problems trying to get the TOC to work properly despite all your efforts to provide help!

I am loading a block of text (rtf format) and a title from a database field. I am using the title as the headline of the paragraph and then adding the rtf as the subsequent paragraph for it.
I require the headline tobe part of the TOC.

When I run it sometimes I only get the LAST headline in my TOC and nothing else. Other times it works but when I try and provide a specific formatting for the TOC it does nothing at all.
I am doing the following : Any help appreciated

Thanks
David

contSty := WPRichText1.parStyles.Addstyle('Contents');
contSty.ASetFontName('Times New Roman');
contSty.ASet(WPAT_CharFontSize,😎;

TOCParagraph := WPRichText1.ActiveParagraph;
TOCParagraph.ABaseStyle := contSty;
WPRichText1.reformatall(true,true);
WPRichText1.InputMergeField(WPTOC_FIELDNAME,'TOC Created here');
WPRichText1.InputString(#12#13);

for x := 0 to 10 do
Begin
buildheader(dmDataConverter.qryGetNotesTITLE.AsString);
dmDataConverter.qryGetNotes.next;
End;

if WPRichText1.FieldExists(WPTOC_FIELDNAME) then
begin
i := WPRichText1.TextCursor.DropMarker;
WPRichText1.CreateTableOfContents('','_Toc', [wptocUseParIsOutline,
wptocCreateOutlineBookmarks,wptocCreateHyperlinkNumbers],
nil,'');
WPRichText1.TextCursor.GotoMarker(i);
//trying to set the TOC style!!! Doesnt work...
currpar := WPRichText1.ActiveParagraph;
currpar.ABaseStyle := contSty;
WPRichText1.reformatall(true,true);
end;

WPRichText1.reformatall(true,true);
WPRichText1.invalidate;
end;

Procedure TfrmDataConverter.buildheader(text : String);
Var
par : TParagraph;
begin
par := WPRichText1.LastPar.AppendNewPar(true);
par.ASet(WPAT_ParIsOutline,1);
par.loadfromstring(text,[wploadpar_UseWritingAttr] );
WPRichText1.CPPosition := MaxInt;
end;

#9 ♥ 0
support

Hi,

a)

//trying to set the TOC style!!! Doesnt work...
currpar := WPRichText1.ActiveParagraph;
currpar.ABaseStyle := contSty;
WPRichText1.reformatall(true,true);

This should work if the text itself does not use a character attribute, which is probably does. If it does the attribute from the style is not used.

par.ClearCharAttr clears the attributes and so a paragraph style can be used. Outher options are available though par.SetStyle

b)

par := WPRichText1.LastPar.AppendNewPar(true);
par.ASet(WPAT_ParIsOutline,1);
par.loadfromstring(text,[wploadpar_UseWritingAttr] );
WPRichText1.CPPosition := MaxInt;

Here you are overwriteing the attribute. I would use

par.SetText( text ) for your title.

If you then need to add a text blob use

WP.InputString(#13)
WP.SelectionAsString := stringdata

Normally par.loadfromstring is notr used. It has its special poppose for nested paragraphs.

#10 ♥ 0

Hi . Thanks for your post, however it still does not work.
When I use settext to set the header, thats fine, and shows the header, however if I then use

currpar := WPRichText1.ActiveParagraph;
currpar := WPRichText1.ActiveParagraph.AppendNewPar(true);
WPRichText1.InputString(#13); WPRichText1.selectionasString :=dmDataConverter.qryGetNotesRTFDESCRIPTION.AsString;

to add the contents of the blob field (Which is RTF), then the contents uses the first line of this text AND the header line I have created to build the TOC. (The header line comes from a plain text field, not RTF)

I also STILL cannot get the style of the TOC to work.
I have done the following : How do I know which paragraph is the TOC paragraph>? Whould this be the correct way fo doing it?

Is there any "standard" templates for TOCs, like in word for example?
How can I get the sub headings indented ?

if WPRichText1.FieldExists(WPTOC_FIELDNAME) then
begin
i := WPRichText1.TextCursor.DropMarker;
currpar := WPRichText1.ActiveParagraph;
Currpar.ClearCharAttr;
currpar.ABaseStyle := contSty;
WPRichText1.CreateTableOfContents('','_Toc',
[wptocUseParIsOutline,wptocCreateOutlineBookmarks,wptocCreateHyperlinkNumbers],
nil,'Contents');
WPRichText1.TextCursor.GotoMarker(i);
WPRichText1.reformatall(true,true);
end;

Thanks

David

#11 ♥ 0
support

to add the contents of the blob field (Which is RTF), then the contents uses the first line of this text AND the header line I have created to build the TOC. (The header line comes from a plain text field, not RTF)

CPPosition := MaxInt

is probably missing.

#12 ♥ 0

Nope... I have that line in

par.ASet(WPAT_ParIsOutline,1);
par.settext(text );
WPRichText1.CPPosition := MaxInt;

and then

currpar := WPRichText1.ActiveParagraph;
currpar := WPRichText1.ActiveParagraph.AppendNewPar(true);
(dmDataConverter.qryGetNotesRTFDESCRIPTION.AsString );
WPRichText1.InputString(#13); WPRichText1.selectionasString :=dmDataConverter.qryGetNotesRTFDESCRIPTION.AsString;

#13 ♥ 0

a small hint from my side, which made the work much easier (at least for me 🙂)

try to build the text only using AppendNewPar and par->SetText(). I often had trouble mixing the direct input (WPRichtText1.Insert(...)) with paragraph input (par->SetText).

I've built myself some functions like:

TParagraph * __fastcall Tfrm_TestspecData::AppendTextToDocument(TWPRichText *target, AnsiString Text){  TParagraph *par;  par = target->LastPar->AppendNewPar(false);  par->ASet(WPAT_Alignment,Integer(paralLeft));  par->ASet(WPAT_IndentLeft,500);  par->SetText(Text,txtplain);  return par;}

of for formated text:

void __fastcall Tfrm_TestspecData::AppendFormatedTextToDocument(TWPRichText *target, AnsiString Text, bool BreakBefore)
{
  TParagraph *par;
  AnsiString temp;

  temp = SetIndent(Text,500);

  if(!temp.IsEmpty())
  {
    if(BreakBefore)
      AppendTextToDocument(target, " ");

    par = target->LastPar->AppendNewPar(true);
    target->SelectParagraph(par);
    target->SelectionAsString = temp;

    AppendTextToDocument(target," ");
  }
}

SetIndent sets the leftindent + 500 from the formated text to append (WPRichtText->AsString saved to blob field in DB), because I'm painting a border arround my document 🙂

#14 ♥ 0

I think I am doing something similar to what you are trying to do. When building a final report, I add chapter headings and topic headings followed by the actual rtf text. Chapter headings, Topic headings, and rtf body text are all pulled from the database separately and then assembled. I automatically insert code to make both the chapter and topic headings show up in the TOC, and will be hyperlinkable if then output to a PDF file using wPDF. Example code snippets that might help follow. I modified Julian's CreateTableOfContents code to fit my needs, including honoring the margins and indents of where the TOC tag was inserted in the master template and providing for indentation of Chapters vs. Topics and unique font, size and color for each.

The snippets might not be complete, but hopefully it will help in some way.

Adding a chapter heading bookmark for TOC creation:

with WPRichText1 do      begin        TextCursor.GetCharAttr;        BookmarkInput( '_Toc_' + TNavFolder(node.Data).ID, true );        ActiveParagraph.ASet(WPAT_ParIsOutline,1);        CurrAttr.Size := 1.0; // WPTools 5.20.6 bug "getaround"        InputString(nodeDesc);      end;

Adding a topic heading bookmark for TOC creation:

with WPRichText1 do            begin              TextCursor.GetCharAttr;              BookmarkInput( '_Toc_' + TNavDocument(node.Data).ID, true );              ActiveParagraph.ASet(WPAT_ParIsOutline,2);              CurrAttr.Size := 1.0; // WPTools 5.20.6 bug "getaround"              InputString(nodeDesc);            end;

Then I call the TOC creation once the report has been assemled:

if WPRichText_Rpt.FieldExists(WPTOC_FIELDNAME) then    begin      preTOCPageCnt := WPRichText_Rpt.PageCount;      MyCreateTableOfContents( '', '_Toc_',                                [ wptocUseParIsOutline,                                  wptocCreateHyperlinks ],                                nil, '', nil);

And then of course the long table of contents creation code:

// Based on CreateTableOfContents from WPCTRMemo.pas of WPTools 5.20.5

function TFPrintReport_Main.MyCreateTableOfContents(
  const AName: string = '';
  const BookMarkId: string = '_Toc';
  Mode: TWPCreateTableOfContentsMode = [];
  StopPar: PTParagraph = nil;
  const TitleText: string = '';
  myFirstPar: PTParagraph = nil): Integer; // wptocRecreateAllBookmarks

var ResultPar: TParagraph;
  ResultPosInPar: Integer;
  bobj, bobje: TWPTextObj;

var s: WideString;
  outl, i, iCurrCharAttr: Integer;
  tocobje, tocobj, hyperobj, beobj: TWPTextObj;
  FNeedCr: Boolean;
  sty: TWPTextStyle;
  uniqueid: Cardinal;

var
  curFontName: TFontName;
  curCharSet: Integer;
  curFontSize: Single;
  curFontStyle: WrtStyle;
  curColor, curBkColor: Integer;
  curAlignment: TParAlign;
  curLeftIndent, curRightIndent: Integer;

  procedure Process(par: TParagraph);

    procedure AppendParText;
    var i: Integer;
      c: WideChar;
    begin
      with WPRichText_Rpt do
      begin
        for i := 0 to par.CharCount-1 do
        begin
          c := par.CharItem[i];
          if (Integer(c) > 9) and
            ((Integer(c) > 32) or (ActiveParagraph.CharCount > 0))
          then
            ActiveParagraph.AppendChar(c, 0);
        end;
      end;
    end;

  begin
    with WPRichText_Rpt do
    begin
      if (wptocUseParIsOutline in Mode) and
         ((par.AGetInherited(WPAT_ParIsOutline, outl)) and (outl > 0)) then
      begin
        // If the paragraph uses a style we can use the number level
        // WPAT_ParIsOutline can come from style OR paragraph!
        sty := par.ABaseStyle;
        if (sty <nil> 0) then
          outl := i;
        bobj := BookmarkFirstObjInPar(par);
        if (wptocCreateOutlineBookmarks in Mode) and (bobj = nil) then
        begin
          bobj := par.InsertNewObject(0, wpobjBookmark, true, false, iCurrCharAttr);
          bobj.Name := BookMarkId + IntToStr(uniqueid);
          inc(uniqueid);
          bobje := par.InsertNewObject(par.CharCount, wpobjBookmark, true, true, iCurrCharAttr);
          bobje.SetTag(bobj.NewTag);
        end;
      end else if not (wptocUseParIsOutline in Mode) then
        bobj := BookmarkFirstObjInPar(par)
      else
        bobj := nil;

      if (bobj <nil> 0)) then
      begin
        if FNeedCr then InputString(#13);
          // Create Hyperklink START
        if wptocCreateHyperlinks in Mode then
        begin
          hyperobj := InputNewObject(wpobjHyperlink, false, false, iCurrCharAttr);
          hyperobj.Source := bobj.Name;
          hyperobj.Mode := [wpobjUsedPairwise, wpobjIsOpening];
        end else
          hyperobj := nil;

        if (outl = 1) or (tocIndent = 0) then
          ActiveParagraph.ASet( WPAT_IndentLeft, curLeftIndent )
        else
          ActiveParagraph.ASet( WPAT_IndentLeft, curLeftIndent + ((tocIndentFactor + 1) * 360) );
        ActiveParagraph.ADel(WPAT_IndentFirst);

        if wptocLocateTextAfterBookmark in Mode then
        begin
          par := par.NextPar;
          AppendParText;
        end else
        begin
          // This is the usual code which uses the embedded text
          s := bobj.EmbeddedText;
          if outl = 1 then
          begin
            CurrAttr.Size := tocChapterFontSize;
            CurrAttr.SetFontCharset( tocChapterFont, DEFAULT_CHARSET );
            CurrAttr.Style := tocChapterFontStyle;
            CurrAttr.Color := CurrAttr.ColorToNr( tocChapterFontColor );
            CurrAttr.BKColor := CurrAttr.ColorToNr( tocChapterBkColor );
          end else
          begin
            CurrAttr.Size := tocTopicFontSize;
            CurrAttr.SetFontCharset( tocTopicFont, DEFAULT_CHARSET );
            CurrAttr.Style := tocTopicFontStyle;
            CurrAttr.Color := CurrAttr.ColorToNr( tocTopicFontColor );
            CurrAttr.BKColor := CurrAttr.ColorToNr( tocTopicBkColor );
          end;
          InputString(s);
          CurrAttr.Size := curFontSize;
          CurrAttr.SetFontCharset( curFontName, curCharSet );
          CurrAttr.Style := curFontStyle;
          CurrAttr.Color := curColor;
          CurrAttr.BKColor := curBkColor;
          beobj := bobj.EndTag;
          if beobj <> nil then
            par := beobj.ParentPar;
        end;
        inc(Result);
          // Create hyperlink closing
        if hyperobj <> nil then
        begin
          with InputNewObject(wpobjHyperlink, false, false, iCurrCharAttr) do
          begin
            hyperobj.CParam := WPHYPER_BOOKMARKLINK;
            SetTag(hyperobj.NewTag); // Link together
            Mode := [wpobjUsedPairwise, wpobjIsClosing];
          end;
          hyperobj := nil;
        end;

        InputString(#9);

        // Create Hyperklink START
        if (hyperobj = nil) and (wptocCreateHyperlinkNumbers in Mode) then
        begin
          hyperobj := InputNewObject(wpobjHyperlink, false, false, iCurrCharAttr);
          hyperobj.Source := bobj.Name;
          hyperobj.Mode := [wpobjUsedPairwise, wpobjIsOpening];
        end;

        ActiveParagraph.TabstopAdd( Header.PageWidth -
          ActivePar.CurrentSection.LeftMargin - ActivePar.CurrentSection.RightMargin -
          curRightIndent,// - 360,
          tkRight, tkDots );
        InputNewObject(wpobjReference, false, false, iCurrCharAttr).Name_Spaces := bobj.Name;

        // Create hyperlink closing
        if hyperobj <> nil then
        begin
          with InputNewObject(wpobjHyperlink, false, false, iCurrCharAttr) do
          begin
            hyperobj.CParam := WPHYPER_BOOKMARKLINK;
            SetTag(hyperobj.NewTag); // Link together
            Mode := [wpobjUsedPairwise, wpobjIsClosing];
          end;
        end;
        FNeedCr := TRUE;
      end;
    end;
  end;

var
  par, rpar, cpar: TParagraph;
begin
  with WPRichText_Rpt do
  begin
    Result := 0;
    uniqueid := GetTickCount;
  {$IFDEF ALLOWUNDO}
    if wpActivateUndo in EditOptions then
    begin
      Memo.RTFData.UndoStreamStart(wputInsertObject);
      Memo.RTFData.UndoDisable;
    end;
  {$ENDIF}
    try
      if CodeLocate(ResultPar, ResultPosInPar, WPTOC_FIELDNAME, wpobjMergefield,
                    [wpobjIsOpening],
                    [wpCompareName{, wpCompareSource}], AName) then
      begin
        ActiveParagraph := ResultPar;
        ActivePosInPar := ResultPosInPar;
        TextCursor.GetCharAttr;
        iCurrCharAttr := TextCursor.WritingTextAttr.CharAttr;
        tocobj := nil;
      end else
      begin
        HideSelection;
        iCurrCharAttr := TextCursor.WritingTextAttr.CharAttr;
        tocobj := InputSingleCode(wpobjMergeField, WPTOC_FIELDNAME, AName);
        tocobj.Mode := [wpobjUsedPairwise, wpobjIsOpening];
        ResultPar := ActiveParagraph;
        ResultPosInPar := ActivePosInPar;
      end;
      tocStartPage := CPPage;
      // -------------------------
      if (tocobj <> nil) or SelectFieldAtCP(false, true) then
      begin
        ClearSelection(true);
        ResultPar := ActiveParagraph;
        ResultPar.TabstopClear;
        InputString(TitleText);
        FNeedCr := TitleText <> '';
        if myFirstPar = nil then
          par := FirstPar
        else
          par := myFirstPar;
        curFontName := CurrAttr.FontName;
        curCharSet := CurrAttr.CharSet;
        curFontSize := CurrAttr.Size;
        curFontStyle := CurrAttr.Style;
        curColor := CurrAttr.Color;
        curBkColor := CurrAttr.BKColor;
        curAlignment := CurrAttr.Alignment;
        CurrAttr.Alignment := parAlLeft;
        curLeftIndent := ActiveParagraph.indentleft;
        curRightIndent := ActiveParagraph.indentright;
        try
          while par <> nil do
          begin
            if (wptocAlsoProcessTables in Mode) and (par.ParagraphType = wpIsTable) then
            begin
              rpar := par.ChildPar;
              while rpar <> nil do
              begin
                cpar := rpar.ChildPar;
                while cpar <> nil do
                begin
                  Process(cpar);
                  cpar := cpar.NextPar;
                end;
                rpar := rpar.NextPar;
              end;
            end else
              Process(par);
            if par = StopPar then
              break;
            par := par.NextPar;
          end;
          if FNeedCr then
            InputString(#13);
          if tocobj <> nil then
          begin
            tocobje := InputSingleCode(wpobjMergeField, WPTOC_FIELDNAME, AName);
            tocobje.Mode := [wpobjUsedPairwise, wpobjIsClosing];
            tocobje.SetTag(tocobj.NewTag);
          end;
        finally
          CurrAttr.Alignment := curAlignment;
        end;
        ReformatAll(true);
        tocEndPage := CPPage;
      end;
    finally
  {$IFDEF ALLOWUNDO}
      if wpActivateUndo in EditOptions then
      begin
        Memo.RTFData.UndoStreamEnd;
        Memo.RTFData.UndoEnable;
      end;
  {$ENDIF}
    end;
  end;
end;
#15 ♥ 0
This category is archived. No new posts are possible.