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);
Alles anzeigen
Hope I could help :) Sure this is not the best way to build a TOC but it works :P
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