Font Find and replace added to the Text dialog

Bug #171007 reported by Irisson
6
Affects Status Importance Assigned to Milestone
Inkscape
Fix Released
Wishlist
Unassigned

Bug Description

It would be useful to be able to quickly replace all
instance of font X with font Y, keeping the styke
(bold, text size) when possible.

Tags: ui object-text
nightrow (jb-benoit)
Changed in inkscape:
importance: Undecided → Wishlist
Revision history for this message
Ryan Lerch (ryanlerch) wrote :

Thank you for taking the time to report this feature request and helping to make Inkscape better. You requested this feature a long while ago and there hasn't been any activity in it recently. We were wondering; is this still on your wishlist? Can you try with latest Inkscape release and see if recent improvements have obsoleted your request? Thanks in advance.

Changed in inkscape:
status: New → Incomplete
Ryan Lerch (ryanlerch)
Changed in inkscape:
status: Incomplete → Invalid
Revision history for this message
Alexandre Prokoudine (alexandre-prokoudine) wrote :

That's a valid request. Updating it to Confirmed.

Changed in inkscape:
status: Invalid → Confirmed
Revision history for this message
Craig Marshall (craig9-deactivatedaccount) wrote :

I've just written an extension to do this.

Instructions here:

http://www.craigmarshall.org/archives/19

Please give it a go and let me know whether it works for you.

Revision history for this message
su_v (suv-lp) wrote :

@Craig - tested with simple example in Inkscape 0.47 and 0.48(+devel), here are some of the issues I encountered [1]:

1) style inheritance
The extension fails to detect the font of most text objects, unless the user has explicitly assign a font to a highlighted part of a text object because the relevant style information is stored in the parent <text> object and not in the <tspan> object (which inherits the style from the parent). AFAICT both elements (text, tspan) need to be searched for the font name.

There are two attributes used to store the font name: 'font-family' and '-inkscape-font-specification'. I don't know details about how they inter-depend and whether a simple 'Find&Replace' gives the correct or expected result in all cases.

2) parser error
If the extension can't find a match (because the font names are stored in the <text> style attribute), or apparently as soon as it parses a <tspan> element which doesn't have a style attribute, it fails with this message:

Traceback (most recent call last):
  File "/Users/suv/.config/inkscape/extensions/replace_font-LeWitt.py", line 73, in <module>
    e.affect()
  File "/Volumes/blue/src/Inkscape/Inkscape-0.47-1.LEOPARD+/Inkscape-047-1.app/Contents/Resources/extensions/inkex.py", line 207, in affect
    self.effect()
  File "/Users/suv/.config/inkscape/extensions/replace_font-LeWitt.py", line 57, in effect
    style = el.attrib['style']
  File "lxml.etree.pyx", line 1984, in lxml.etree._Attrib.__getitem__ (src/lxml/lxml.etree.c:43068)
KeyError: 'style'

[1] There have been some changes to how text is stored in the source and other enhancements of the text tool in 0.48. Considering that 0.48 src is released (and packages imminent to be officially announced 'released') I focused on using the extension with 0.48 and current devel builds.

Revision history for this message
su_v (suv-lp) wrote :

3) partial match
It replaces partial matches which can result in invalid or non-existing font names:
 Arial -> Georgia
 Arial Narrow -> Georgia Narrow (doesn't exist)

Revision history for this message
su_v (suv-lp) wrote :

4) Flowed Text
Can't detect fonts used in 'Flowed Text'.

Revision history for this message
Craig Marshall (craig9-deactivatedaccount) wrote :

Okay - I'll get to work on fixing these bugs. Thanks for find them out for me.

Revision history for this message
Craig Marshall (craig9-deactivatedaccount) wrote :

Here is an updated version of the font replacer extension. It now checks in text, tspan, flowRoot and flowPara elements, and it uses the simplestyle module for correct parsing/access to style attributes. All the test cases now pass on my machine (currently using Ubuntu 10.10 alpha 3, Inkscape 0.47). (If it's broken in 0.48 I will soon see, as you say, because 0.48 is just coming out).

There are two new features, presented as tickboxes on the dialog, one allows you to replace all fonts in the document, regardless of the contents of the find box, the second allows you to list all fonts used in the document (Could be useful if there are fonts chosen on another computer, and those fonts don't exist on the current computer).

I had a comment on my blog suggesting that I allow the user to switch fonts only in selected items, which sounds like it could be very useful. I will look into doing this in the next couple of days.

Revision history for this message
su_v (suv-lp) wrote :

@Craig - the examples I used to illustrate my previous comments now all work without error - many thx :)

The option to list all fonts (instead of replacing) is great - that would have been my next proposal (a companion extension that helps with font management, by listing all fonts referenced in the file). The same applies to the option to replace in the current selection only.

New questions:
1) Possibly the reported number of replacements is confusing for regular users (who do not need to know details about the font style information stored in the 'style' attribute): Is there any way to obtain the number of changed text objects/tspans/flowRoots (i.e. not counting both 'font-name' and '-inkscape-font-specification' string replacements)?
2) Have you had the chance to test it with imported PDF/EPS files or SVG files created by other applications (AI, gnuplot, MatLab, etc.)? (I haven't yet, need to search for good test cases first ;-) )

Revision history for this message
su_v (suv-lp) wrote :

3) Using 'List all fonts used' dirties the document even if the extension dialog is closed without replacing any font - can this be solved similarly to the proposed fix for the 'Draw Handles' extension?

Revision history for this message
Craig Marshall (craig9-deactivatedaccount) wrote :

That's great.

I have just been updating the extension to handle replacements within selections only. Here are some answers to your questions:

1) Despite my saying that replacements for the font-family and -inkscape-font-specification were made independently, i.e. it will replace none, either or both, regardless of the other. It *should* be that it counts any replacement for each element (either or both style attributes) as just the one replacement. If this is not what you're seeing, could you post an svg file for me to test with and I'll see what's going wrong? thanks.

Of course for tspan elements and other text objects that can be nested, it will always look like one replacement per element, even if there are many elements per line (entirely possible). Perhaps this is what's happening for you, if you're seeing more replacements than there should be? I'm not sure of the best way around this, I think if it's something I can't improve on much, it might be a case of removing the substitution count altogether, bad information is worse than no information.

2) I just tried importing a PDF file that was created elsewhere (a DHL shipping label), and it replaced the text successfully. With the caveat that it was full of manual kerns, as documented at this bug: https://bugs.launchpad.net/inkscape/+bug/188794

I also tried page 1 of the PDF ebook "The Joy of Clojure", again text replacement worked fine - apart from kerning issues.

Sorry - I don't have any AI or other files to test, just PDF at the moment.

3) I've updated the code so that actions that have no effect (listing all fonts, replacing specific fonts where there were none of that font found) do not dirty the document.

PS: I found another text element that can be styled: flowSpan

Revision history for this message
Craig Marshall (craig9-deactivatedaccount) wrote :

Previous version was failing on some fonts with leading and trailing spaces. It now ignores these, and the searching is now case independent.

Revision history for this message
Craig Marshall (craig9-deactivatedaccount) wrote :

I've started a project page where you can report bugs and always download the latest version (rather than abusing/littering a single bug thread by trying to do the whole thing here):

Download:
http://code.google.com/p/inkscape-replace-font/downloads/list
(The version 0.5 that's there at the moment is the same as the latest version available here, so there's no reason to download from there yet)

Main project page:
http://code.google.com/p/inkscape-replace-font

Revision history for this message
Craig Marshall (craig9-deactivatedaccount) wrote :

I feel that it's ready to commit now, but before I do that, I'd like to make sure with everyone that's testing that all the issues are resolved. Is it now working as you'd expect?

Revision history for this message
su_v (suv-lp) wrote :

Tested in Inkscape 0.48+devel on OS X 10.5.8: the known issues (most of them discussed in the previous comments, others on irc) have been fixed in the latest version (Replace Font 0.8).

Revision history for this message
jazzynico (jazzynico) wrote :

Looks good on Ubuntu 10.04.

Some UI/cosmetic comments:
1. The option group has no label.
2. The comment in the List tab should end with a period.
3. The python strings are not translatable.

Attached is a proposal for these minor issues (I used an enum list because minimal option groups have an alignment problem).

A remaining small bug: the message dialog return an error when "Find this font" is empty:
---
Traceback (most recent call last):
  File "replace_font.py", line 253, in <module>
    e.affect()
  File "/usr/local/share/inkscape/extensions/inkex.py", line 216, in affect
    self.effect()
  File "replace_font.py", line 241, in effect
    find = self.options.fr_find.strip().lower()
AttributeError: 'NoneType' object has no attribute 'strip'
---

Revision history for this message
su_v (suv-lp) wrote :

Another small issue (testing with JazzyNico's updated version):

Replace all Fonts:
if the input field is empty, the font names are replaced with the literal string 'None'

Expected result would be:
- no font names are replaced
- or - alternatively - all font name definitions in the style attribute are removed ('Unset' -> inheritance rules) (?)
- or - alternatively - all font name definitions are reset to the default 'Sans' (?)

Revision history for this message
Craig Marshall (craig9-deactivatedaccount) wrote :

Thanks for making those changes, I've merged those along with some whitespace fixing (tabs to spaces) and also the bugfix for the empty find box that you highlighted.

Here's the patch, I've updated the po stuff and the makefile too, just like you did for my guillotine extension.

I guess I can commit this myself now? (These are the only changes in the source tree.)

Revision history for this message
Craig Marshall (craig9-deactivatedaccount) wrote :

Oops - should have reloaded the page first. I will see what I can do about those problems su-v.

Revision history for this message
Craig Marshall (craig9-deactivatedaccount) wrote :

Can this patch be tested please to make sure it satisfies all the above requirements?

Thanks,
Craig

Revision history for this message
jazzynico (jazzynico) wrote :

> I guess I can commit this myself now?

Yes. Since this is a trunk commit, we'll have time to test it again before 0.49 is out ;)

Revision history for this message
su_v (suv-lp) wrote :

Patch from comment #20 tests ok in Inkscape 048+devel r9788 on OS X 10.5.8.

Revision history for this message
Craig Marshall (craig9-deactivatedaccount) wrote :

Replace font extension commited in the trunk, revision 9789.

Please continue to test it though.

Changed in inkscape:
assignee: nobody → Craig Marshall (craig9)
status: Confirmed → In Progress
Changed in inkscape:
status: In Progress → Fix Committed
su_v (suv-lp)
Changed in inkscape:
milestone: none → 0.49
Bryce Harrington (bryce)
Changed in inkscape:
status: Fix Committed → Fix Released
Revision history for this message
Bart Van Audenhove (bart-vanaudenhove) wrote :

I have a feature request concerning this extension (thumbs up for the extension itself by the way, great work).

I would like the "Find font" and "Replace with" fields to be drop-down boxes? The first would be populated with used fonts in the file, the second with existing fonts on the system (same as fonts you can choose with the text tool).
Same for the "Replace all fonts with" : pre-populated with existing fonts on the system.

I suppose this would imply that on opening the extension it would automatically run "list all fonts" immediately, making this tab obsolete then.
If necessary, a progression bar could be running while scanning for fonts, or just a popup like "Looking for fonts, please wait..." or something. (At least something that informs the user that all is going well and he just needs to wait a bit).

Revision history for this message
su_v (suv-lp) wrote :

@Bart - neither of the requested features are implementable with the current extension system (the extension dialog cannot be populated live with information extracted from the current SVG document, or with any other information not already hard-coded in the INX definition file for the dialog). Related feature requests to re-design the extension system and teh Auto-GUI for the options dialog are tracked elsewhere (they are not specific to an individual extension, and known limitations of the current system).

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Related blueprints

Remote bug watches

Bug watches keep track of this bug in other bug trackers.