Forum: Ruby Markaby -> Nokogiri Issue

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Thomas Sawyer (7rans)
on 2009-01-12 18:14
(Received via mailing list)
I was using:

    Markaby::Builder.new(&block)

And it was working fine except it wouldn't let me use non-standard
attributes on an img tag, which blows. I couldn't find any way to
deactivate this strictness, so I decided to try Nokogiri instead:

        Nokogiri::HTML::Builder.new(&block)

Unfortunately this doesn't work at all, b/c it turns out Nokogiri does
not seem to be using #instance_eval on the block. Without doing so I
don't see how it can be at all useful. For example in my case I have
method called #body:

    def body(&block)
        Nokogiri::HTML::Builder.new do
          body(&block)
        end
    end

By not using instance_eval Nokogiri doesn't recognize 'body' as a tag,
but tries to call the method again, resulting in an infinite loop. So
I think this is a bug in Nokogiri's builder.

In the mean time, can anyone offer a work around? Or is there a way to
turn off "strict-mode" for Markaby.

Thanks,
T.
Be30361bb0b0c495e3077db43ad84b56?d=identicon&s=25 Aaron Patterson (Guest)
on 2009-01-13 02:28
(Received via mailing list)
On Tue, Jan 13, 2009 at 02:13:13AM +0900, Trans wrote:
> Unfortunately this doesn't work at all, b/c it turns out Nokogiri does
> not seem to be using #instance_eval on the block. Without doing so I
> don't see how it can be at all useful. For example in my case I have
> method called #body:
>
>     def body(&block)
>         Nokogiri::HTML::Builder.new do
>           body(&block)
>         end
>     end

It does use instance_eval, but it also checks the context in which it
was instantiated to see if it responds to that method before creating a
new node.  That way your builder can have access to methods outside of
the builder.

> By not using instance_eval Nokogiri doesn't recognize 'body' as a tag,
> but tries to call the method again, resulting in an infinite loop. So
> I think this is a bug in Nokogiri's builder.

No.  This was a requested feature.  I gladly accept patches though!  :-)

> In the mean time, can anyone offer a work around? Or is there a way to
> turn off "strict-mode" for Markaby.

You should be able to do this:

  def body(&block)
    Nokogiri::HTML::Builder.new do
      insert(Nokogiri::XML::Node.new('body', @doc), &block)
    end
  end

Hope that helps!
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Thomas Sawyer (7rans)
on 2009-01-13 03:17
(Received via mailing list)
On Jan 12, 8:27 pm, Aaron Patterson <aa...@tenderlovemaking.com>
wrote:
>
>
> It does use instance_eval, but it also checks the context in which it
> was instantiated to see if it responds to that method before creating a
> new node.  That way your builder can have access to methods outside of
> the builder.
>
> > By not using instance_eval Nokogiri doesn't recognize 'body' as a tag,
> > but tries to call the method again, resulting in an infinite loop. So
> > I think this is a bug in Nokogiri's builder.
>
> No.  This was a requested feature.  I gladly accept patches though!  :-)

Ah, I see. I'm used to Markaby --when I needed to access an outside
method I first assign it to a local variable, then use the local var
in the block. I can see the advantage of accessing methods directly,
but it's also one of those things that can be a little worrisome b/c
if I add a method to the same scope, for instance say I add a 'def pre
()' or include a module, I may inadvertently cause unexpected markup.
That seems to me a bit too fragile. If you agree, I am willing to take
a look at making a patch.


> > In the mean time, can anyone offer a work around? Or is there a way to
> > turn off "strict-mode" for Markaby.
>
> You should be able to do this:
>
>   def body(&block)
>     Nokogiri::HTML::Builder.new do
>       insert(Nokogiri::XML::Node.new('body', @doc), &block)
>     end
>   end

Thanks! Looks like that'll go it.

T.
This topic is locked and can not be replied to.