0

I use this command-line to tidy the XML content of an SVG file:

Winapi.ShellAPI.ShellExecute(Handle, 'open', 'cmd.exe', '/K tidy.exe -q -xml input.svg', nil, SW_SHOWNORMAL);

However, I have the XML content in a string variable. So I have to save the string variable to "input.svg" before executing the above command-line.

How can I pass the string variable DIRECTLY as a parameter for TIDY instead of having to save the string variable to "input.svg" file?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
user1580348
  • 5,721
  • 4
  • 43
  • 105
  • If tidy support XML input from standard input, then you can run tidy.exe having redirected his standard input to a pipe into which you write the xml. Much less easier than using a file. – fpiette Feb 08 '21 at 14:38
  • The question has nothing to do with Delphi at all. It's just about what command line parameters tidy.exe accepts. – Delphi Coder Feb 08 '21 at 14:55
  • @DelphiCoder When you look at the comment of fpiette then you realize that the question HAS to do with Delphi. – user1580348 Feb 08 '21 at 15:16
  • @fpiette Could you provide a Delphi example about how to redirect the standard input of tidy to a pipe? – user1580348 Feb 08 '21 at 15:20
  • @user1580348 I don't think so, that's something you can do with almost any programming language! – Delphi Coder Feb 08 '21 at 15:47
  • Look at my old blog post there: http://francois-piette.blogspot.com/2013/04/inter-process-communication-using-pipes.html – fpiette Feb 08 '21 at 20:09

2 Answers2

2

The manual right away mentions:

If no input file is specified, Tidy reads the standard input. If no output file is specified, Tidy writes the tidied markup to the standard output.

How to operate with pipes is unbound to Delphi - it's basically calling CreateProcess() and I'm sure there are lots of examples to find. If you're stuck then ask a new question about your particular problem.

HTML Tidy also comes with a DLL that might be even better than launching new processes again and again. Or involving the command line which is not needed in any way.

AmigoJack
  • 5,234
  • 1
  • 15
  • 31
  • Thank you for mentioning the TIDY DLL. What would the equivalent DLL function(s) of the command-line in my question? – user1580348 Feb 09 '21 at 19:12
  • As per **\include\tidy.h** the `tidyOptSet*()`, `tidyParse*()` and `tidySave*()` functions look promising. – AmigoJack Feb 09 '21 at 19:58
0

Using tidyobj.pas as a wrapper for libtidy.dll, I used this code:

Tidy := TTidy.Create(nil);
try
  Tidy.LoadConfigFile('tidy_xml_settings.txt');
  s := Tidy.ParseString(Memo1.Lines.Text);
  Memo2.Lines.Text := s;
finally
  Tidy.Free;
end;

...where tidy_xml_settings.txt defines these tidy options:

input-xml: yes
output-xml: yes
indent-attributes: yes

It works well as it allows to pass the XML as a string as required.

Input XML was:

<svg version="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" enable-background="new 0 0 48 48">
    <path fill="#37474F" d="M41,38H7c-2.2,0-4-1.8-4-4V14c0-2.2,1.8-4,4-4h34c2.2,0,4,1.8,4,4v20C45,36.2,43.2,38,41,38z"/>
    <path fill="#F3E5F5" d="M6,14v20c0,0.6,0.4,1,1,1h34c0.6,0,1-0.4,1-1V14c0-0.6-0.4-1-1-1H7C6.4,13,6,13.4,6,14z"/>
    <polygon fill="#9C27B0" points="26,15 20.1,22 31.9,22"/>
    <path fill="#9C27B0" d="M24,21v6c0,1.1-0.9,2-2,2s-2-0.9-2-2v-2h-4v2c0,3.3,2.7,6,6,6s6-2.7,6-6v-6H24z"/>
</svg>

And TIDY created this valid output XML:

<svg version="1"
     xmlns="http://www.w3.org/2000/svg"
     viewBox="0 0 48 48"
     enable-background="new 0 0 48 48">
<path fill="#37474F"
      d="M41,38H7c-2.2,0-4-1.8-4-4V14c0-2.2,1.8-4,4-4h34c2.2,0,4,1.8,4,4v20C45,36.2,43.2,38,41,38z" />
<path fill="#F3E5F5"
      d="M6,14v20c0,0.6,0.4,1,1,1h34c0.6,0,1-0.4,1-1V14c0-0.6-0.4-1-1-1H7C6.4,13,6,13.4,6,14z" />
<polygon fill="#9C27B0"
         points="26,15 20.1,22 31.9,22" />
<path fill="#9C27B0"
      d="M24,21v6c0,1.1-0.9,2-2,2s-2-0.9-2-2v-2h-4v2c0,3.3,2.7,6,6,6s6-2.7,6-6v-6H24z" />
</svg>
user1580348
  • 5,721
  • 4
  • 43
  • 105