Tidy binding using DL

After reading the recent post re: Ruby's DL functions I decided to see if I
could come up with a Tidy binding. So far I have it setting/getting options,
doing CleanAndRepair and optionally saving to a file. However I'm not sure
how to get it to save to a string to be returned. The function in question
is tidyStringSave:

http://tidy.sourceforge.net/docs/api/group__Save.html#a3
int tidySaveString(TidyDoc tdoc, tmbstr buffer, uint * buflen)

I had envisioned it originally working like this:

output = String.new
Tidylib.tidySaveString(@tdoc, output)

But it's looking for a buffer object not a regular string. It's the last 2
parameters that I'm unsure of. What Ruby objects would I need to create/pass
to make this work?

Try the following code, since 'tmbstr' in tidy header files is
considered as 'char *' or 'const char *'.

This runs without errors, but returns a value of 68, with the "out" string
remaining unchanged.

Try the following code, since 'tmbstr' in tidy header files is
considered as 'char *' or 'const char *'

Go it. The extern statement was correct, but the buffer string still wasn't
big enough to hold the results. The following takes care of it:

    buffer = String.new # string buffer
    8192.times { buffer << ' ' } # must be long enough to hold results
    Tidylib.tidySaveString(@doc, buffer, buffer.length)
    output = buffer.strip

Kevin Howe said:

This runs without errors, but returns a value of 68, with the "out" string
remaining unchanged.

I corrected that as follows.

require 'dl/import'

module Tidylib
  extend DL::Importable

  dlload "libtidy.so"

  extern "void *tidyCreate()"
  extern "int tidyParseString(void*, char*)"
  extern "int tidyCleanAndRepair(void*)"
  extern "int tidySaveString(void*, char*, unsigned int ref)"
  extern "int tidySaveStdout(void*)"
  extern "int tidyRunDiagnostics(void*)"

  module_function

  def create()
    tidyCreate()
  end

  def parse_string(doc, str)
    tidyParseString(doc, str)
  end

  def clean_and_repair(doc)
    tidyCleanAndRepair(doc)
  end

  def save_string(doc)
    str = " " * 1024
    ret = tidySaveString(doc, str, str.size)
    len = @args[2]
    str = @args[1]
    str[0,len]
  end

  def save_stdout(doc)
    tidySaveStdout(doc)
  end

  def run_diagnostics(doc)
    tidyRunDiagnostics(doc)
  end
end

doc = Tidylib.create()
Tidylib.parse_string(doc, <<EOS)
<title></title>
EOS
Tidylib.clean_and_repair(doc)
Tidylib.run_diagnostics(doc)
puts Tidylib.save_string(doc)

ยทยทยท

--
Takaaki Tateishi <ttate@ttsky.net>