patsplat / plist

All-purpose Property List manipulation library

Home Page:http://www.rubydoc.info/gems/plist

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

String fields that contain line breaks end up with tabs inserted at the start of every new line

nsforge opened this issue · comments

The plist generation code seems to incorrectly indent the output when writing a string field that has line breaks. Try running the following code:

require 'rubygems'
require 'plist'

hash = {"name"=>"David Smith", "address"=>"123 Smith St\nAnytown 12345"}

hash.save_plist(File.expand_path("~/Test.plist"))

The generated plist has an extra tab character inserted before the "Anytown 12345", which makes the raw plist data "look" like its indented correctly, but actually corrupts the string itself. Here is the generated output:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>address</key>
    <string>123 Smith St
    Anytown 12345</string>
    <key>name</key>
    <string>David Smith</string>
</dict>
</plist>

Whereas the correct output would be:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>address</key>
    <string>123 Smith St
Anytown 12345</string>
    <key>name</key>
    <string>David Smith</string>
</dict>
</plist>

I have been able to create a workaround for this. I'm using Plist with Day One Journal files and this problem seriously impacts formatting.

The code I have in place is

doc = ''
doc = Nokogiri::XML(journal.to_plist.gsub! /\t/, '') {|x| x.noblanks}
doc = doc.to_xml(:indent => 1, :indent_text => "\t")
File.open(fn, 'w') {|f| f.write(doc) }  

Where journal is the plist.

Please note that this breaks the entire thing pretty badly.

here's the workarounds I use till the issues will be fixed:

  plist_string = some_hash.to_plist
  plist_string = plist_string.gsub(/&amp;([a-z0-9]+;)/,'&\1')     #fix double encoding issue
  plist_string = plist_string.gsub("/Apple Computer/","/Apple/")  #fix doctype
  plist_string = plist_string.gsub(/([^>]\n)\t+/,'\1')            #fix spacing issue

Yep, this is definitely a bug. Thanks for the report!

Please see PR #54