Line numbering for text frames

From Scribus Wiki
Revision as of 14:49, 28 November 2015 by Gpittman (talk | contribs) (linenumber.py)
Jump to: navigation, search
This article is part of the Scripts series.

Here is an idea that comes from a feature request, specifically http://bugs.scribus.net/view.php?id=1975

As you can see this was filed back in 2005, so it's mostly been gathering dust, or whatever bug reports do over the years. Kunda wondered if this might be scriptable, so I began to see what I could do. Consider this a work in progress.

What the filer wanted was the ability to have numbering of lines present on a proof of some document, so that this numbering scheme could be used when one person is recommending an edit to be done by someone else in some particular frame on some particular page. Later, the numbering would eliminated or turned off for the final product. Kunda dug up this bug, and thought that it seemed an interesting concept, and might be useful for other purposes, purposes unknown as of yet.

linenumber.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# File: linenumber.py
# © 2015.11.25 Gregory Pittman
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
"""
USAGE



"""
import scribus

if scribus.haveDoc():
    linecount = 1
    textnumbers = ""
else:
    scribus.messageBox('Usage Error', 'You need a Document open', icon=0, button1=1)
    sys.exit(2)

if scribus.selectionCount() == 0:
    scribus.messageBox('Scribus - Usage Error',
        "There is no object selected.\nPlease select a text frame and try again.",
        scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(2)
if scribus.selectionCount() > 1:
    scribus.messageBox('Scribus - Usage Error',
        "You have more than one object selected.\nPlease select one text frame and try again.", scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(2)
textbox = scribus.getSelectedObject()
ftype1 = scribus.getObjectType(textbox)
if (ftype1 != "TextFrame"):
    scribus.messageBox('Object Type', "Selected object must be a text frame",
                       scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(2)
    
frameW, frameH = scribus.getSize(textbox)
textlines = scribus.getTextLines(textbox)
linespace = scribus.getLineSpacing(textbox)
xframe, yframe = scribus.getPosition(textbox)
font_size = scribus.getFontSize(textbox)
#scribus.messageBox("Font Size",str(font_size),icon=scribus.ICON_NONE,button1=scribus.BUTTON_OK) # here to debug getFontSize()

while (linecount <= textlines):          # here we create a customized column of numbers, just enough for the lines of text
    textnumbers = textnumbers + str(linecount) + "\n"
    linecount = linecount + 1
newframe = scribus.createText(xframe - font_size * 1.5, yframe, font_size * 1.5, frameH)
scribus.selectObject(newframe)
scribus.insertText(textnumbers, 0, newframe)
scribus.setFontSize(font_size, newframe)
scribus.setLineSpacing(linespace, newframe)
if (scribus.scribus_version_info[:3] >= (1,5,0)):
    scribus.setLineSpacingMode(1, newframe)

scribus.setRedraw(1)
scribus.docChanged(1)
endmessage = 'Successfully ran script!' # Change this message to your liking
scribus.messageBox("Finished", endmessage,icon=scribus.ICON_NONE,button1=scribus.BUTTON_OK)

Notes

At this point, it only works on a single selected text frame, by getting information about the frame size and position, font size, linespacing, number of lines of text, then creates a small text frame just to the left of the original, which it fills with a column of numbers, created with a loop based on the number of lines of text. In case you wondered, the getTextLines() command only gets the number of lines you see in the frame. If the text overflows, it only counts those you see. One potential error is that the linespacing mode is set to Automatic. This comes from the problem that even though there is a command to set the mode, you cannot get the mode from the original frame. If the original text is in fixed linespacing, you may need to switch for the line numbering frame.

One thing I found as I began this was that there was a bug in the getFontSize() command, in that it would not return a decimal value. A font 14.4 points returned 14.0. I looked this up in the C++ code, found it was being assigned a long integer value instead of a double precision float. Fixed that, and with Craig Bradney's blessing committed it fix this bug and the script's behavior.

Getting back to the original usage envisioned, next I'd like to create a new layer, and put this text frame on that instead of the same layer as the original text. This way, the new layer could be made invisible and/or nonprintable (and therefore not exporting to PDF).

Finally, the last element would be to run this on all the text frames in a document. This has pros and cons, but at least a starting point for variants. After that, perhaps other bells and whistles, like adjusting the font or font color, transparency, who knows.