View Issue Details

IDProjectCategoryView StatusLast Update
0005975ScribusStory Editor / Text Framespublic2019-04-09 08:57
Reportermecirt Assigned To 
Status newResolutionopen 
PlatformAMD64OSLinuxOS VersionOpenSuSE 10.2
Product Version1.3.4 
Summary0005975: Wish: generate TOC from paragraph styles
DescriptionThe current TOC editor unfortunately isn't very useful for me. I want to use Scribus to create book layouts, where text may flow between frames as adjustments are made. Thus, text headings (which appear in the TOC) can also flow from one frame to another, and marking a frame as a TOC item is not sufficient, because I do not know which frame a heading will end up in.

Therefore, I'd like to see the TOC generator functionality extended to be able to extract TOC information from paragraph styles - in particular, to be able to mark a particular paragraph style as "include in TOC", and then all paragraphs that get assigned this particular style (a Heading one) would get added to the TOC, with their page number included.

To my understanding, the current TOC generator is not able to do this.

/ Tomas
TagsNo tags attached.


related to 0004484 assignedcezaryece TOC generation: Several issues 
related to 0001371 assignedcezaryece Considering writing plugin to generate TOCs, Indexes, and "Continued on pg ... " messages 
related to 0001773 closedcbradney Extra attributes on frames and documents 
parent of 0015049 confirmed Numbered Headings in different Text-Frames, when opening the document ... 
has duplicate 0008796 assignedcezaryece [feature request] more usable TOC 
has duplicate 0015640 closedjghali Wish: generate TOC from paragraph styles 
Not all the children of this issue are yet resolved or closed.



2008-01-18 21:03

reporter   ~0018651

Last edited: 2008-01-18 21:04

This is my most wanted feature too.
A Programm without Style-Based TOC-Generation is almost useless for longer or structured Publications.


2008-01-19 06:27

reporter   ~0018652

I agree that it would be a great feature.


2008-01-19 14:59

developer   ~0018656

Great idea!

Same could apply to Index, through character style (word style?). What do you think?

I guess that from the programming point of view, once we have that tag possibility set for paragraph style, the path is cleared for extending the similar feature to other kinds of styles. Right?


2008-01-20 10:07

reporter   ~0018670

Yes indeed. It also would be handy if you can use other kind of styles in your TOC.


2008-01-27 16:35

reporter   ~0018744

Once we have a function to locate specific styles on a page, it should be no problem to generate indexes too.
The problem is: The feature seems to be not planned. Endnotes and index is "acknowledged", but it is not clear, if "our" feature (status "new")is coming, although I think that the index-Feature-functions should make a style-based TOC possible as well.
TOC is mentioned in the Scribus-Roadmap (1.3.9) but it is "done" (so it is the one we have now)
It would be good if someone could find out if a style-based TOC-generation is planned. (maybe for the 1.3.9 ?)


2011-01-06 23:24

reporter   ~0025303

Here is a Scripter script that could be adapted to do a TOC. I wrote it to search for string across the entire document.


2011-01-06 23:24



2011-01-10 11:03

developer   ~0025320

Style based TOC is under construction, see


2017-11-29 19:04

developer   ~0044677

Thaddeus, your script hangs on scribus 1.5.3
It runs, messages "Finished" "All Done. Total hits found = 25" but never comes back to me.
I have to kill scribus.

Do you have a possible fix or an idea of what is the issue ?


2017-11-29 19:23

developer   ~0044678

Last edited: 2017-11-29 19:23

OK i fixed the issue.
Here is updated script.
It runs for scribus 1.5.4 svn.
As is, it's far from being user friendly, but it's a possible start point to create an index builder. And there is more to do to create a TOC. (6,398 bytes)   
#!/usr/bin/env python
# -*- coding: utf-8 -*-

  Find and report occurrences of a search-for string by using regular
  expressions. On the first run it creates a text frame
  (TxtFrameFind_Tfm) on first page if it does not exist elsewhere.
  By Thaddeus Koehller (a94e94c3e89ba4ff457ff6599d1aab295ba4be43)

import string, re

   from scribus import *
except ImportError:
   print "This script only runs from within Scribus."

PgIdx_int=1;                PgQty_int=0;                             TxtFrameCnt_int=0;        TxtHitCnt_int=0; i=-1;
PageItems_lst=[];           PgItem_lst=[];                           FramesContent_lst=[];     RegExRes_lst = [];
FrameContent_str="";        TxtFrameFind_str='TxtFrameFind_Tfm';
UserRegEx_str='';           RegExRes_str='';
TxtFrameFind_obj = None;

UserRegEx_str = valueDialog('Enter Regular Expression','Examples:\n\d{1,4}\sof\s\d{1,4}\n\s\s.+?\s\s\n.*__\n', '\s{3}.+?\s{3}');

if len(UserRegEx_str)<=0:
   statusMessage('Nothing to Do...')
   messageBox("Finished", 'Nothing to Do...', icon=scribus.ICON_NONE, button1=scribus.BUTTON_OK);

# RegExPatt_obj = re.compile(r'\d{1,4}\sof\s\d{1,4}',re.I) # look for a string ending with underscores, like BlaBla____
RegExPatt_obj = re.compile(UserRegEx_str,re.I)

# RE Flag 	Meaning
# DOTALL, S 	Make . match any character, including newlines
# IGNORECASE, I 	Do case-insensitive matches
# LOCALE, L 	Do a locale-aware match
# MULTILINE, M 	Multi-line matching, affecting ^ and $
# VERBOSE, X 	Enable verbose REs, which can be organized more cleanly and understandably.
# UNICODE, U 	Makes several escapes like \w, \b, \s and \d dependent on the Unicode character database.

# Python´┐Żs raw string notation for regular expressions; backslashes are not handled in any special way in a string literal prefixed with 'r'
if haveDoc():


   statusMessage("Running script...");

   PgQty_int = pageCount();
   while (PgIdx_int <= PgQty_int):
   #........................ START - LOOP THRU PAGES .....................
      PageItems_lst = getPageItems();

      for PgItem_lst in PageItems_lst:
      #**************** START - LOOP THRU ITEMS WITHIN A PAGE ***************
        if ( (PgItem_lst[1] == 4) and              # It is a Text Frame
             ((PgItem_lst[0] <> TxtFrameFind_str)) # Not our own Frame with the results.
            TxtFrameCnt_int += 1;
            #messageBox('Testing...',str(PgItem_lst[0]), icon=scribus.ICON_WARNING, button1=scribus.BUTTON_OK);
            FrameContent_str = getText(PgItem_lst[0]); # getText changes paragraph marks (<para/>) with blank spaces (\s).
            RegExRes_lst = RegExPatt_obj.findall(FrameContent_str);
            for RegExRes_str in RegExRes_lst:
               TxtHitCnt_int += 1;
               #  FramesContent_lst.append( [PgIdx_int, FrameContent_str] );
               FramesContent_lst.append( [PgIdx_int, RegExRes_str, PgItem_lst[0]] );
               #if (len(MetafileContent_lst)>0) and not(MetafileContent_lst[-1].endswith('\n')): MetafileContent_lst.append('\n');

      #**************** END - LOOP THRU ITEMS WITHIN A PAGE *****************
      PgIdx_int += 1;
   #........................ END - LOOP THRU PAGES .......................

   #~~~~~~~~~~~~~~~~~~~~~~~~~~ START - PRINT RESULTS ~~~~~~~~~~~~~~~~~~~~~
   TxtFrameFind_obj = TxtFrameFind_str if objectExists(TxtFrameFind_str) else createText(0.75, 0.75, 10, 6, TxtFrameFind_str);

   selectText(0, getTextLength(TxtFrameFind_obj), TxtFrameFind_obj);
   #insertText(str(TxtFrameCnt_int) + '\n' + str(TxtHitCnt_int), -1, TxtFrameFind_obj);

   insertText('----------------------------------------------------------------------\nReg. Expression = ' + UserRegEx_str + '\nTotal Frames Found = ' + str(TxtHitCnt_int) + '\n----------------------------------------------------------------------', -1, TxtFrameFind_obj);
   for i in range(len(FramesContent_lst)):
       insertText('\n--------------------Page ' + str(FramesContent_lst[i][0]) + ', Frame "' + FramesContent_lst[i][2] + '"--------------------\n' + FramesContent_lst[i][1], -1, TxtFrameFind_obj);
   insertText('\n----------------------------------  ----------------------------------' , -1, TxtFrameFind_obj);

   #setText(str(TxtFrameCnt_int) + '\n' + str(TxtHitCnt_int), TxtFrameFind_obj);


   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~ END - PRINT RESULTS ~~~~~~~~~~~~~~~~~~~~~

   statusMessage('All Done.')
   messageBox("Finished", 'All Done.' + '\nTotal Hits Found = ' + str(TxtHitCnt_int), icon=scribus.ICON_NONE, button1=scribus.BUTTON_OK);

   messageBox('Error in FindInTxtFrames', 'You Need an Open Document.', icon=scribus.ICON_WARNING, button1=scribus.BUTTON_OK)
#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ (6,398 bytes)   


2017-11-30 07:32

reporter   ~0044681

JLuc, nice start. For a TOC, a regular expression on a style would be the thing to have. Is there documentation around on how styles are coded into the files?


2017-11-30 08:42

developer   ~0044682

Last edited: 2017-11-30 08:45

You're right.
Scribus .SLA files are XML-like files : open with a plain text editor and spot the place where a style is used.

The output of the script, as is, is not friendly and has to be totaly manualy reworked each time.
I've had an idea to improve this :
the user could provide, on the first page, a special frame with a dedicated Id "IndexTemplate" or "TOCTemplate".
That frame would contain a one-line paragraph with user-choosen styles and with place holders like
- %P for page number,
- %T for text (or title)
- %F for frame name (in case it's usefull for somebody),
Then the script would read that IndexTemplate frame,
find the paragraph text,
replace the place holders with the found values for each found occurence
and paste the result at the end of the result frame.

Then some more refinement would be required :
- For indexes, duplicate pages numbers should only be placed once
- For TOC, not only 1 but several styles should be searched, each corresponding to a title level of the document, and there should be also one paragragh in the TOCTemplate for each TOC level (= for each searched style).
Not sure but it could be this would benefit of enriching the Template frame syntax.

That would provide a general yet powerfull way of creating TOCs and Indexes


2017-11-30 09:25

reporter   ~0044683

Just looked into the XML:
                <DefaultStyle NumerationName="<local block>"/>
                <ITEXT CH="Introduction"/>
                <para PARENT="Header1" NumerationName="<local block>"/>

Header1 is my style for a H1 title. That could be linked automatic/manually. Manual entry is error probe, but ok for a start I guess.

Shouldn't be hard to find this; only thing to notice is that the actual text is in a previous block from the Header1 definition.
Another thing I notice: the numbering is done somewhere else. For a TOC this should be replicated exactly.

For automation: The styles could be found from the doc with loadStylesFromFile(...) ?
I don't see a predefined API call in the documentation to simply get the style of a paragraph from the text.

Formatting the TOC:
The TOC entries would probably have a style applied per level within the TOC. For a start it wouldn't be too bad to do this manually after the TOC entries are placed into the frame.
Setting a style on the generated TOC entry could be done with setStyle() ? (if objects are also the strings generated)

There is an open bug (0015049) on the creation of the numbering throughout the document. Probably that same function should be called for the TOC creation?


2017-11-30 10:10

developer   ~0044684

Last edited: 2017-11-30 10:11

Ouch : Not all titles have numbering, but knowing the final numbering could be a blocker when required. It reminds me of 0014605 about knowing mark's page numbers .


2017-12-02 16:15

manager   ~0044699 will probably make some progress very soon...

it's based on the one mentioned by cezary, but "simpler".

as far as i know (as far as i recall) it's not "easy" to do it in python, since you cannot know on which page a bunch of text (a paragraph) is...


2019-04-08 22:54

reporter   ~0046093

Any word on this one? It seems it was added in cezaryece's custom branch, which is on Git. Is this going to be added into the main build any time soon?


2019-04-09 08:00

manager   ~0046095

cezary's version was a bit "weak".

my "version" -- while being somehow based on cezaary's work --is simpler and more solid... but i'm building it upon a new scripter API that i'm creating "for it".
so it takes time...

collaboration is welcome.

Issue History

Date Modified Username Field Change
2007-07-05 11:05 mecirt New Issue
2007-07-05 15:04 christoph_s Relationship added related to 0004484
2007-07-05 15:04 christoph_s Relationship added related to 0001371
2007-07-05 15:04 christoph_s Relationship added related to 0001773
2008-01-18 21:03 janD Note Added: 0018651
2008-01-18 21:04 janD Note Edited: 0018651
2008-01-19 06:27 rdevries Note Added: 0018652
2008-01-19 14:59 louisdesjardins Note Added: 0018656
2008-01-20 10:07 rdevries Note Added: 0018670
2008-01-27 16:35 janD Note Added: 0018744
2008-02-05 18:06 christoph_s Status new => acknowledged
2010-03-16 15:01 mhanski Relationship added has duplicate 0008796
2011-01-06 23:24 Thaddeus Note Added: 0025303
2011-01-06 23:24 Thaddeus File Added: FindInTxtFrames Script &
2011-01-10 11:03 cezaryece Note Added: 0025320
2012-06-18 20:13 ale Assigned To => cezaryece
2012-06-18 20:13 ale Status acknowledged => assigned
2015-09-17 20:08 Kunda Category Story Editor / Text Frames => Story Ed/Txt Frames
2015-09-17 20:12 Kunda Category Story Ed/Txt Frames => Story Editor / Text Frames
2017-11-29 18:54 JLuc Assigned To cezaryece =>
2017-11-29 18:54 JLuc Status assigned => new
2017-11-29 18:54 JLuc Patch => No
2017-11-29 19:04 JLuc Note Added: 0044677
2017-11-29 19:23 JLuc File Added:
2017-11-29 19:23 JLuc Note Added: 0044678
2017-11-29 19:23 JLuc Note Edited: 0044678
2017-11-30 07:32 michelv Note Added: 0044681
2017-11-30 08:42 JLuc Note Added: 0044682
2017-11-30 08:45 JLuc Note Edited: 0044682
2017-11-30 09:25 michelv Note Added: 0044683
2017-11-30 10:05 JLuc Relationship added parent of 0015049
2017-11-30 10:10 JLuc Note Added: 0044684
2017-11-30 10:11 JLuc Note Edited: 0044684
2017-12-02 16:15 ale Note Added: 0044699
2019-04-08 22:54 izaius Note Added: 0046093
2019-04-09 02:47 izaius Issue cloned: 0015640
2019-04-09 02:47 izaius Relationship added parent of 0015640
2019-04-09 08:00 ale Note Added: 0046095
2019-04-09 08:57 jghali Relationship replaced has duplicate 0015640