Forum: wxRuby Using Wx::RichTextCtrl to generate PDF

Posted by Chloro Form (tony44)
on 2010-09-22 16:06
Hi,

I intend to use a RichTextCtrl so the user can edit parts of a PDF that
will be generated using Prawn. Any ideas on how to best render the
user-editable content into the PDF?

I was thinking of parsing the XML output since I'm not sure if it's
possible to easily extend the RichTextFileHandler class from within
Ruby. Or is RichTextPrinting the proper way to start here?

Thanks,
Tony
Posted by Alex Fenton (Guest)
on 2010-09-22 16:40
(Received via mailing list)
Hi

On 22/09/2010 15:06, Tony Meier wrote:
> I intend to use a RichTextCtrl so the user can edit parts of a PDF that
> will be generated using Prawn. Any ideas on how to best render the
> user-editable content into the PDF?
>
> I was thinking of parsing the XML output since I'm not sure if it's
> possible to easily extend the RichTextFileHandler class from within
> Ruby. Or is RichTextPrinting the proper way to start here?

I think probably the XML route. There is a wxWidgets class to print to a
postscript file on any platform, but I have never managed to port it to
Ruby.

I remember writing some code some time ago to parse wxRTC's XML in Ruby,
but I don't have it to hand. I know a guy who uses wxPython who wrote a
library for doing just that which might be a reference, since the XML
language used by RTC isn't that well documented.

http://osdir.com/ml/wxpython-users/2010-02/msg00042.html

alex
Posted by Chloro Form (tony44)
on 2010-09-22 17:19
Hi,

> I think probably the XML route.
> 

Thanks for the hint and the link to the wxpython project. Looks doable 
to me.

So I'll go the XML way then. With my first spike attempts I'm getting 
strange results though. Here's my test class.

Two things

(a) I would expect it to write an XML file to my home dir, which it 
doesn't. Actually I would much rather like it to a string but my first 
attempt (file) fails already

(b) I would expect it to copy the contents of the editor to the 
clipboard, which it doesn't => crashes with NoMethodError: undefined 
method ‘begin’ for #<SWIG::TYPE_p_wxRichTextRange:0x234d2e20>

Any ideas what might be going wrong? Or maybe an idea of what's the best 
way to actually get the XML out of the control in order to parse it?

I'm using wxruby 2.0.1, ruby 1.8.7p174 on OSX 10.6.4

Thanks so much,
Tony

---

#!/usr/bin/env arch -i386 ruby
require 'rubygems'

require "wx"
include Wx

class MyFrame < Wx::Frame

  def initialize
    super(nil, :title => "RichText Example", :pos => [150, 25], :size => 
[800, 500])

    panel = Wx::Panel.new(self)    #Parent = self = this Frame

    @editor = Wx::RichTextCtrl.new(
        panel,  # parent
        ID_ANY,  # ID
        "Initial text",  # value
        [0, 20], # position
        [400, 400] #size
        )

    boldbtn = Wx::Button.new(panel, ID_ANY, "bold",  [0,0], [100,50])
    dumpbtn = Wx::Button.new(panel, ID_ANY, "dump",[100,0], [100,50])

    evt_button(boldbtn) { |evt| @editor.apply_bold_to_selection() }

    evt_button(dumpbtn) { |evt|
      buffer.save_file("/Users/tm/test.xml", Wx::RICHTEXT_TYPE_XML)

      @editor.select_all()
      range = @editor.get_selection_range()
      buffer = @editor.get_buffer()
      buffer.copy_to_clipboard(range)
    }

    show()
  end
end


class MinimalApp < Wx::App
  def on_init
    MyFrame.new
  end
end

MinimalApp.new.main_loop
Posted by Alex Fenton (Guest)
on 2010-09-22 17:41
(Received via mailing list)
On 22/09/2010 16:19, Tony Meier wrote:
> clipboard, which it doesn't =>  crashes with NoMethodError: undefined
> method ‘begin’ for #<SWIG::TYPE_p_wxRichTextRange:0x234d2e20>
>
> Any ideas what might be going wrong? Or maybe an idea of what's the best
> way to actually get the XML out of the control in order to parse it?

This is from memory - I probably should have written it up when I was
working with this a year or two ago - but I think you have to create an
instance of Wx::RichTextXMLHandler

http://wxruby.rubyforge.org/doc/richtextxmlhandler.html

Then you can use handler.save_file(rich_text_ctrl.buffer, file_or_io)

If you want as a string, use a StringIO as the second argument.

hth
alex
Posted by Chloro Form (tony44)
on 2010-09-22 18:00
> hth

it did. Thanks again!
Posted by Chloro Form (tony44)
on 2010-09-27 12:34
Ah, one more thing. Sorry to bother with that.

Exporting to XML works fine now, however, I'd like to depersist the 
content of the editor when it re-opens.

The problem with that is, that the XML handler doesn't seem to import 
what it just exported. Here's my test case:

def store_and_load
    buffer = @editor.get_buffer()
    handler = Wx::RichTextXMLHandler.new
    io = StringIO.new()
    handler.save_file(buffer, io)
    io.rewind()
    handler.load_file(buffer, io)
end

This gives me a dialog box with an XML parsing error 'no element found 
at line 1'.

Dumping the XML, however, yields valid content. The error also persists 
if
a) I remove the first line from the string 'io' or
b) create a new handler (instead of rewinding the existing one)
c) create a new StringIO class

Any hint would be very much appreciated!

Thanks so much,
Tony

---

dumped XML string:
<?xml version="1.0" encoding="UTF-8"?>
<richtext version="1.0.0.0" xmlns="http://www.wxwidgets.org">
  <paragraphlayout textcolor="#000000" fontsize="12" fontstyle="90" 
fontweight="90" fontunderlined="0" fontface="Courier" alignment="1" 
parspacingafter="10" parspacingbefore="0" linespacing="10">
    <paragraph>
      <text>foobar</text>
    </paragraph>
  </paragraphlayout>
</richtext>
Posted by Alex Fenton (Guest)
on 2010-09-28 10:42
(Received via mailing list)
Hi Tony

On 27/09/10 11:34, Tony Meier wrote:
> end
>
> This gives me a dialog box with an XML parsing error 'no element found
> at line 1'.
>    

Haven't run your code, but you might look into whether there's an XML
Byte-Order Mark (BOM) either coming out or going in. Inspect the XML
string byte-wise (it won't show up when dumped) and try either adding a
BOM, if missing, or deleting it, if present.

http://www.opentag.com/xfaq_enc.htm

cheers
alex
Posted by Chloro Form (tony44)
on 2010-09-29 15:06
Hi Alex,

thanks for your reply. Looking at the output string with
   String#bytes.each {|b| p b.chr }
it seems there is no BOM coming out of the RTC, the first byte is the 
opening angle bracket.

Prepending a BOM doesn't change the observed behavior though.

Here's my changed code:

  UTF8BOM = "\xef\xbb\xbf"

  def store_and_load
    buffer = @editor.get_buffer()
    handler = Wx::RichTextXMLHandler.new
    io = StringIO.new()

    handler.save_file(buffer, io)
    s = UTF8BOM + io.string
    io.string = s

    io.rewind()
    handler.load_file(buffer, io) # gives a warning dialog: "No element 
found on line 1"
  end

FWIW, I can repro this on Win7 and OSX.

Thanks again for your time,
Tony


Alex Fenton wrote:
> Hi Tony
> 
> On 27/09/10 11:34, Tony Meier wrote:
>> end
>>
>> This gives me a dialog box with an XML parsing error 'no element found
>> at line 1'.
>>    
> 
> Haven't run your code, but you might look into whether there's an XML
> Byte-Order Mark (BOM) either coming out or going in. Inspect the XML
> string byte-wise (it won't show up when dumped) and try either adding a
> BOM, if missing, or deleting it, if present.
> 
> http://www.opentag.com/xfaq_enc.htm
> 
> cheers
> alex
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.