[rig3] r446 committed - Add support for encoding. Switch to explicit UTF-8 by default.

1 view
Skip to first unread message

ri...@googlecode.com

unread,
Aug 30, 2010, 12:21:00 AM8/30/10
to rig3-d...@googlegroups.com
Revision: 446
Author: ralfoide
Date: Sun Aug 29 21:19:47 2010
Log: Add support for encoding. Switch to explicit UTF-8 by default.
http://code.google.com/p/rig3/source/detail?r=446

Modified:
/trunk/rig3serv/.settings/org.eclipse.core.resources.prefs
/trunk/rig3serv/misc/TaskList.txt
/trunk/rig3serv/src/rig/parser/izu_parser.py
/trunk/rig3serv/src/rig/site/site_default.py
/trunk/rig3serv/src/rig/sites_settings.py
/trunk/rig3serv/src/rig/source_item.py
/trunk/rig3serv/src/rig/source_reader.py
/trunk/rig3serv/src/rig/version.py
/trunk/rig3serv/src/tests/parser/test_izu_parser.py
/trunk/rig3serv/src/tests/site/test_site_defaut.py
/trunk/rig3serv/src/tests/test_sites_settings.py
/trunk/rig3serv/testdata/album/blog1/2007-10-07_Folder 1/index.izu
/trunk/rig3serv/testdata/album/blog1/file_items/2007-09-09 Izu File
Item.izu

=======================================
--- /trunk/rig3serv/.settings/org.eclipse.core.resources.prefs Sun Apr 4
23:37:44 2010
+++ /trunk/rig3serv/.settings/org.eclipse.core.resources.prefs Sun Aug 29
21:19:47 2010
@@ -1,7 +1,8 @@
-#Sun Apr 04 23:33:08 PDT 2010
+#Sun Aug 29 21:16:09 PDT 2010
eclipse.preferences.version=1
encoding//src/rig/parser/izu_parser.py=iso-8859-1
encoding//src/rig/parser/utf8_accents.py=utf-8
encoding//src/tests/parser/test_izu_parser.py=iso-8859-1
encoding//testdata/album/blog1/2007-10-07_Folder\ 1/index.izu=ISO-8859-1
+encoding//testdata/album/blog1/file_items/2007-09-09\ Izu\ File\
Item.izu=UTF-8
instance/org.eclipse.core.net/org.eclipse.core.net.hasMigrated=true
=======================================
--- /trunk/rig3serv/misc/TaskList.txt Sun Apr 4 23:37:44 2010
+++ /trunk/rig3serv/misc/TaskList.txt Sun Aug 29 21:19:47 2010
@@ -38,6 +38,10 @@

---- Done Version 0.4 ----

+20100829 Engine: Add support for encoding. Switch to explicit UTF-8 by
default.
+20100828 Engine: Experimental old izu blog reader, continued
+20100827 Engine: Experimental old izu blog reader
+
20100404 Izu: UTF8-to-HTML conversion of upper case accents
20100404 Izu: Implement legacy Izumi [table] and [izu:image] tags
20100404 Engine: Add option to exclude some categories from the 'all
index' page
=======================================
--- /trunk/rig3serv/src/rig/parser/izu_parser.py Sun Aug 29 18:53:21 2010
+++ /trunk/rig3serv/src/rig/parser/izu_parser.py Sun Aug 29 21:19:47 2010
@@ -23,11 +23,13 @@
"""
__author__ = "ralfoide at gmail com"

-import re
-import os
+import codecs
import fnmatch
-import urllib
+import os
+import re
import subprocess
+import sys
+import urllib
from datetime import datetime
from StringIO import StringIO

@@ -142,7 +144,11 @@
"""
line = None
if self._file:
- line = self._file.readline()
+ try:
+ line = self._file.readline()
+ except UnicodeDecodeError, e:
+ raise Exception("Failed to read line from %s" %
self._filename,
+ "UnicodeDecodeError: " + str(e))
if not line:
self._file = None
line = None
@@ -183,11 +189,14 @@
self._tag_handlers = { "cat" : self._CatHandler,
"date" : self._DateHandler }

- def RenderFileToHtml(self, filestream):
+ def RenderFileToHtml(self, filestream, encoding):
"""
Parses the file 'filename' and returns an HTML snippet for it.
Renders a <div> section, not a full single HTML file.

+ Encoding must be the desired text file encoding, e.g. "utf-8"
+ or "iso-8859-1", as supported by the codecs.open() method.
+
If source is a string or a RelPath/RelFile, it is considered a
path to
be opened as read-only text.

@@ -206,15 +215,17 @@
try:
rel_file = None
if isinstance(filestream, (str, unicode)):
- f = file(filestream, "rU", 1) # 1=line buffered, universal
+ # open with 1=line buffered, U=universal end-of-lines
+ f = codecs.open(filestream, mode="rU", buffering=1,
encoding=encoding)
filename = filestream
elif isinstance(filestream, RelPath):
filename = filestream.abs_path
rel_file = filestream
- f = file(filename, "rU", 1) # 1=line buffered, universal
+ # open with 1=line buffered, U=universal end-of-lines
+ f = codecs.open(filename, mode="rU", buffering=1,
encoding=encoding)
else:
f = filestream
- filename = "<unknown stream>"
+ filename = "<internal stream>"

state = _State(f, filename, rel_file)
self._ParseStream(state)
@@ -225,17 +236,20 @@
self._log.Exception("Read-error for %s" % filestream)
return result

- def RenderStringToHtml(self, source):
+ def RenderStringToHtml(self, source, encoding):
"""
- Renders an Izu source to HTML.
+ Renders an Izu string to HTML.
This is an utility wrapper that actually calls RenderFileToHtml.
+
+ Encoding must be the desired text file encoding, e.g. "utf-8"
+ or "iso-8859-1", as supported by the codecs.open() method.
"""
f = StringIO(source)
- return self.RenderFileToHtml(f)
+ return self.RenderFileToHtml(f, encoding)

def ParseFirstLine(self, source):
"""
- Parses the *first* line of a string -- the string is actual
content,
+ Parses the *first* line of a *string* -- the string is actual
content,
not a filename. It returns any Izu tags found on the line.

This is mostly an utility method to parse izu tags embedded in the
@@ -247,9 +261,27 @@
a = source.find("\r")
if a != -1:
source = source[:a]
- tags, sections = self.RenderStringToHtml(source)
+ tags, sections = self.RenderStringToHtml(source, encoding=None)
#@UnusedVariable
return tags

+ def ParseFileFirstLine(self, filename, encoding):
+ """
+ Parses the *first* line of a *file*, using the given optional
encoding.
+
+ This is a wrapper to open the file, extract the first line and
+ return the result of ParseFirstLine on it.
+ """
+ f = None
+ try:
+ if isinstance(filename, RelPath):
+ filename = filename.abs_path
+ f = codecs.open(filename, mode="rU", buffering=1,
encoding=encoding)
+ line = f.readline()
+ return self.ParseFirstLine(line)
+ finally:
+ if f:
+ f.close()
+
def _ParseStream(self, state):
is_block = None
state.SetCurrSection("en",
@@ -920,7 +952,10 @@
ret = p.wait()
if ret != 0:
self._log.Error("Image Gen Script failed. Ret=%d, Args=%s",
ret, repr(env))
- sys.exit(2)
+ if abs_dir != "@test@":
+ # Don't do a sys.exit during unit-tests :-)
+ sys.exit(2)
+ return None

result = output
if output.find("<img ") == -1:
=======================================
--- /trunk/rig3serv/src/rig/site/site_default.py Sun Aug 29 03:05:15 2010
+++ /trunk/rig3serv/src/rig/site/site_default.py Sun Aug 29 21:19:47 2010
@@ -770,14 +770,22 @@
self._site_settings.public_name,
izu_file)

+ if source_item.source_settings.encoding:
+ encoding = source_item.source_settings.encoding
+ else:
+ encoding = self._site_settings.encoding
+
p = IzuParser(self._log,
keywords["rig_base"],
keywords["img_gen_script"])
if html_file == "@content":
tags = source_item.tags
- _, sections = p.RenderStringToHtml(source_item.content)
+ _, sections = p.RenderStringToHtml(source_item.content,
encoding)
else:
- tags, sections = p.RenderFileToHtml(izu_file)
+ tags = p.ParseFileFirstLine(izu_file, encoding)
+ if "encoding" in tags:
+ encoding = tags["encoding"]
+ tags, sections = p.RenderFileToHtml(izu_file, encoding)

for k, v in sections.iteritems():
if isinstance(v, (str, unicode)):
=======================================
--- /trunk/rig3serv/src/rig/sites_settings.py Sun Apr 4 12:11:03 2010
+++ /trunk/rig3serv/src/rig/sites_settings.py Sun Aug 29 21:19:47 2010
@@ -223,6 +223,8 @@
- enable_sharing(bool): When true, add links to share posts to
Facebook, twitter, etc.
- index_exclude(str): An inclusion-exclusion list of categories to
exclude from
the generic "all recents items" page.
+ - encoding(str): Encoding of Izu/HTML text files. Default is UTF-8.
+ Can be overridden per source.
"""
def __init__(self,
public_name="",
@@ -263,7 +265,8 @@
youtube_sx="640",
youtube_sy="385",
enable_sharing=False,
- index_exclude=IncludeExclude(IncludeExclude.ALL, None)
+ index_exclude=IncludeExclude(IncludeExclude.ALL, None),
+ encoding="utf-8"
):
# Note: this is *always* called using the default values defined
in the
# constructor. If you need to change a setting loaded from an RC
file,
@@ -306,6 +309,7 @@
self.youtube_sy = youtube_sy
self.enable_sharing = self.ParseBool(enable_sharing)
self.index_exclude = index_exclude;
+ self.encoding = encoding

def AsDict(self):
"""
=======================================
--- /trunk/rig3serv/src/rig/source_item.py Sun Aug 29 03:05:15 2010
+++ /trunk/rig3serv/src/rig/source_item.py Sun Aug 29 21:19:47 2010
@@ -29,10 +29,17 @@
class SourceSettings(Hashable):
"""
Settings attached to a specific source.
+
+ Current settings that can be overridden per source:
+ - rig_base(str): Base URL for rig1 for generating rig1 image links.
+ - encoding(str): Text encoding of Izu/HTML files for the source.
+ When set, overrides the global settings' encoding
+ (which is utf-8 by default).
"""
- def __init__(self, rig_base=None):
+ def __init__(self, rig_base=None, encoding=None):
super(SourceSettings, self).__init__()
self.rig_base = rig_base
+ self.encoding = encoding

def AsDict(self):
"""
=======================================
--- /trunk/rig3serv/src/rig/source_reader.py Sun Aug 29 18:53:21 2010
+++ /trunk/rig3serv/src/rig/source_reader.py Sun Aug 29 21:19:47 2010
@@ -186,23 +186,23 @@

SEP = "----"

+ if self._source_settings.encoding:
+ encoding = self._source_settings.encoding
+ else:
+ encoding = self._site_settings.encoding
+
# First line must have some izu tags
- tags = {}
+ tags = IzuParser(self._log, None, None).ParseFileFirstLine(f,
encoding)
+
+ # If we find an encoding tag, reparse the tags using that encoding
+ if "encoding" in tags:
+ tags = IzuParser(self._log, None, None).ParseFileFirstLine(f,
encoding)
+
+ f = codecs.open(rel_file.abs_path, mode="rU", encoding=encoding)
+ # Skip to the first section
for line in f:
if line.strip() == SEP:
break
- if not tags and line:
- tags = IzuParser(self._log, None,
None).ParseFirstLine(line)
-
- # If we find an encoding tag, reopen the file using that encoding
- encoding = tags.get("encoding", None)
- if encoding:
- f.close()
- f = codecs.open(rel_file.abs_path, mode="rU",
encoding=encoding)
- # Skip the tag section
- for line in f:
- if line.strip() == SEP:
- break

# Use the category based on the filename if there's no override in
the file tags
if not "cat" in tags:
=======================================
--- /trunk/rig3serv/src/rig/version.py Sun Apr 4 23:37:44 2010
+++ /trunk/rig3serv/src/rig/version.py Sun Aug 29 21:19:47 2010
@@ -13,7 +13,7 @@
To enable substitutions, do something like this:
$ svn propset svn:keywords "Date Author Revision HeadURL Id" version.py

-----
+-----

Part of Rig3.
Copyright (C) 2007-2009 ralfoide gmail com
=======================================
--- /trunk/rig3serv/src/tests/parser/test_izu_parser.py Sun Aug 29 18:53:21
2010
+++ /trunk/rig3serv/src/tests/parser/test_izu_parser.py Sun Aug 29 21:19:47
2010
@@ -92,11 +92,11 @@
self.m = None

def _Render(self, text, section="en"):
- tags, sections = self.m.RenderStringToHtml(text) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml(text, encoding=None)
#@UnusedVariable
return sections.get("en", None)

def _Tags(self, text):
- tags, sections = self.m.RenderStringToHtml(text) #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml(text, encoding=None)
#@UnusedVariable
return tags

def testEscapes(self):
@@ -327,68 +327,68 @@
self._Render("first
line\nfoo[!html:<blah1>\n<blah2>\n\ntoto</blah2>--]bar\nend"))

def testSection(self):
- tags, sections = self.m.RenderStringToHtml("default section is
en") #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("default section is
en", encoding=None) #@UnusedVariable
self.assertEquals('<span class="izu">\ndefault section is
en</span>',
sections.get("en", None))
self.assertEquals(None, sections.get("fr", None))

- tags, sections = self.m.RenderStringToHtml("line 1[s:en]line 2")
#@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("line 1[s:en]line 2",
encoding=None) #@UnusedVariable
self.assertEquals('<span class="izu">\nline 1\nline 2</span>',
sections.get("en", None))
self.assertEquals(None, sections.get("fr", None))

- tags, sections = self.m.RenderStringToHtml("line 1\n[s:en]line 2")
#@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("line 1\n[s:en]line 2",
encoding=None) #@UnusedVariable
self.assertEquals('<span class="izu">\nline 1\nline 2</span>',
sections.get("en", None))
self.assertEquals(None, sections.get("fr", None))

- tags, sections = self.m.RenderStringToHtml("section
1\n[s:fr]section 2") #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("section
1\n[s:fr]section 2", encoding=None) #@UnusedVariable
self.assertEquals('<span class="izu">\nsection 1</span>',
sections.get("en", None))
self.assertEquals('<span class="izu">\nsection 2</span>',
sections.get("fr", None))

- tags, sections = self.m.RenderStringToHtml("[s:en]section
1\n[s:fr]section 2") #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[s:en]section
1\n[s:fr]section 2", encoding=None) #@UnusedVariable
self.assertEquals('<span class="izu">\nsection 1</span>',
sections.get("en", None))
self.assertEquals('<span class="izu">\nsection 2</span>',
sections.get("fr", None))

- tags, sections = self.m.RenderStringToHtml("[s:fr]section
1\n[s:en]section 2") #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[s:fr]section
1\n[s:en]section 2", encoding=None) #@UnusedVariable
self.assertEquals('<span class="izu">\nsection 1</span>',
sections.get("fr", None))
self.assertEquals('<span class="izu">\nsection 2</span>',
sections.get("en", None))

# Empty sections generate *really* nothing, not even the wrapping
div (since
# there's nothing to wrap)
- tags, sections =
self.m.RenderStringToHtml("\n\n\n\n[s:en]\n\n\n\n\n[s:fr]\n\n\n\n")
#@UnusedVariable
+ tags, sections =
self.m.RenderStringToHtml("\n\n\n\n[s:en]\n\n\n\n\n[s:fr]\n\n\n\n",
encoding=None) #@UnusedVariable
self.assertEquals('', sections.get("en", None))
self.assertEquals('', sections.get("fr", None))

# A section before EOF generates nothing
- tags, sections = self.m.RenderStringToHtml("[s:fr]section
1[s:en]") #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[s:fr]section
1[s:en]", encoding=None) #@UnusedVariable
self.assertEquals('<span class="izu">\nsection 1</span>',
sections.get("fr", None))
self.assertEquals('', sections.get("en", None))

- tags, sections = self.m.RenderStringToHtml("[s:fr]section
1\n[s:en]") #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[s:fr]section
1\n[s:en]", encoding=None) #@UnusedVariable
self.assertEquals('<span class="izu">\nsection 1</span>',
sections.get("fr", None))
self.assertEquals('', sections.get("en", None))

# Sole section tags do not count as a white line that would
generate a <p>
- tags, sections = self.m.RenderStringToHtml("\n[s:en]\nline
1\n\n[s:fr]\nline 2\n\n") #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("\n[s:en]\nline
1\n\n[s:fr]\nline 2\n\n", encoding=None) #@UnusedVariable
self.assertEquals('<span class="izu">\nline 1</span>',
sections.get("en", None))
self.assertEquals('<span class="izu">\nline 2</span>',
sections.get("fr", None))

def testIzuTags(self):
- tags, sections = self.m.RenderStringToHtml("[izu:author:ralf]")
#@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[izu:author:ralf]",
encoding=None) #@UnusedVariable
self.assertDictEquals({ "author": "ralf" }, tags)

- tags, sections = self.m.RenderStringToHtml("[izu:date:2006-05-28
17:18:05]") #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[izu:date:2006-05-28
17:18:05]", encoding=None) #@UnusedVariable
self.assertDictEquals({ "date": datetime(2006, 5, 28, 17, 18, 5)
}, tags)

- tags, sections = self.m.RenderStringToHtml("[izu:date:2006:05:28
17:18:22]") #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[izu:date:2006:05:28
17:18:22]", encoding=None) #@UnusedVariable
self.assertDictEquals({ "date": datetime(2006, 5, 28, 17, 18, 22)
}, tags)

- tags, sections =
self.m.RenderStringToHtml("[izu:cat:videos,photos]") #@UnusedVariable
+ tags, sections =
self.m.RenderStringToHtml("[izu:cat:videos,photos]", encoding=None)
#@UnusedVariable
self.assertDictEquals({ "cat": { "videos": True, "photos": True }
}, tags)

- tags, sections = self.m.RenderStringToHtml("[izu:title:some random
title with : colon]") #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[izu:title:some random
title with : colon]", encoding=None) #@UnusedVariable
self.assertDictEquals({ "title": "some random title with : colon"
}, tags)

- tags, sections = self.m.RenderStringToHtml("[izu:date:0000-00-00
00:00:00]") #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[izu:date:0000-00-00
00:00:00]", encoding=None) #@UnusedVariable
self.assertDictEquals({}, tags)

def testParseFirstLine(self):
@@ -568,19 +568,19 @@
glob={ "A01234*.jpg": "A01234 My Image.jpg"
},
rig_base=None,
img_gen_script=None)
- tags, sections = self.m.RenderStringToHtml("[s:images]")
#@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[s:images]",
encoding=None) #@UnusedVariable
self.assertEquals(None, sections.get("en", None))
self.assertEquals(None, sections.get("fr", None))
self.assertEquals([], sections.get("images", None))

# Ignore invalid tags
- tags, sections = self.m.RenderStringToHtml("[s:images]line 1\nline
2\n[not a rigimg tag]") #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[s:images]line 1\nline
2\n[not a rigimg tag]", encoding=None) #@UnusedVariable
self.assertEquals(None, sections.get("en", None))
self.assertEquals(None, sections.get("fr", None))
self.assertEquals([], sections.get("images", None))

# full tag with name, size and glob
- tags, sections = self.m.RenderStringToHtml("[s:images][This is &
comment|rigimg:256:A01234*.jpg] ignore the rest") #@UnusedVariable
+ tags, sections = self.m.RenderStringToHtml("[s:images][This is &
comment|rigimg:256:A01234*.jpg] ignore the rest", encoding=None)
#@UnusedVariable
self.assertListEquals(
[ '[[if rig_base]]<img title="This is &amp; comment" '
'src="[[raw rig_thumb_url % '
@@ -610,13 +610,17 @@

# error code is not 0, so nothing is done
m.SetPopenValues(42, "blah")
- self.assertEquals(None, m._ExternalGenRigUrl(
- rel_file=None, abs_dir=0, filename=1, title=2,
is_link=False, size=4, caption=5))
-
- # output is empty, so nothing is done
+ self.assertEquals(
+ None,
+ m._ExternalGenRigUrl(
+ rel_file=None, abs_dir="@test@", filename=1, title=2,
is_link=False, size=4, caption=5))
+
+ # output from script is empty so nothinf is done
m.SetPopenValues(0, "")
- self.assertEquals(None, m._ExternalGenRigUrl(
- rel_file=None, abs_dir=0, filename=1, title=2,
is_link=False, size=4, caption=5))
+ self.assertEquals(
+ None,
+ m._ExternalGenRigUrl(
+ rel_file=None, abs_dir="@test@", filename=1, title=2,
is_link=False, size=4, caption=5))

def testExternalGenRigUrl_url(self):
m = MockIzuParser(self.Log(),
=======================================
--- /trunk/rig3serv/src/tests/site/test_site_defaut.py Wed Feb 10 21:43:29
2010
+++ /trunk/rig3serv/src/tests/site/test_site_defaut.py Sun Aug 29 21:19:47
2010
@@ -138,7 +138,8 @@
dest_dir=self._tempdir,
cache_dir=self._cachedir,
theme=DEFAULT_THEME,
- base_url="http://www.example.com")
+ base_url="http://www.example.com",
+ encoding="iso-8859-1")
sos =
SourceSettings(rig_base="http://example.com/photos/index.php")
return sis, sos

=======================================
--- /trunk/rig3serv/src/tests/test_sites_settings.py Mon Oct 26 21:47:21
2009
+++ /trunk/rig3serv/src/tests/test_sites_settings.py Sun Aug 29 21:19:47
2010
@@ -252,13 +252,13 @@

sis = SiteSettings()
self.m._ProcessSources(sis,
- { "sources": "file:/my/path1,
rig_base:http://some/url" })
+ { "sources": "file:/my/path1,
rig_base:http://some/url, encoding=iso-8859-1" })
self.assertListEquals(
[ SourceFileReader(log, sis,
- SourceSettings(rig_base="http://some/url"),
+ SourceSettings(rig_base="http://some/url",
encoding="iso-8859-1"),
"/my/path1") ],
sis.source_list)
- self.assertDictEquals( { "rig_base": "http://some/url" },
+ self.assertDictEquals(
{ "rig_base": "http://some/url", "encoding": "iso-8859-1" },
sis.source_list[0]._source_settings.AsDict())

sis = SiteSettings()
@@ -270,11 +270,11 @@
SourceFileReader(log, sis, sos, "/my/path2"),
SourceFileReader(log, sis, sos, "/my/path3") ],
sis.source_list)
- self.assertDictEquals( { "rig_base": "http://some/url" },
+ self.assertDictEquals(
{ "rig_base": "http://some/url", "encoding": None },
sis.source_list[0]._source_settings.AsDict())
- self.assertDictEquals( { "rig_base": "http://some/url" },
+ self.assertDictEquals(
{ "rig_base": "http://some/url", "encoding": None },
sis.source_list[1]._source_settings.AsDict())
- self.assertDictEquals( { "rig_base": "http://some/url" },
+ self.assertDictEquals(
{ "rig_base": "http://some/url", "encoding": None },
sis.source_list[2]._source_settings.AsDict())

def testSiteSettingsTypes(self):
=======================================
--- /trunk/rig3serv/testdata/album/blog1/2007-10-07_Folder 1/index.izu Sun
Mar 22 22:15:48 2009
+++ /trunk/rig3serv/testdata/album/blog1/2007-10-07_Folder 1/index.izu Sun
Aug 29 21:19:47 2010
@@ -1,4 +1,4 @@
-[izu:cat:bar,foo,other,Foo FOO foo]
+[izu:cat:bar,foo,other,Foo FOO foo] [izu:encoding:iso-8859-1]
[s:en]
blog 1

=======================================
--- /trunk/rig3serv/testdata/album/blog1/file_items/2007-09-09 Izu File
Item.izu Fri Feb 12 09:06:49 2010
+++ /trunk/rig3serv/testdata/album/blog1/file_items/2007-09-09 Izu File
Item.izu Sun Aug 29 21:19:47 2010
@@ -12,5 +12,5 @@
Rig link: [This is a rig link|riglink:T12896*.jpg]

[s:fr]
-Un mot ou deux en francais, avec des accents en ISO 8859-1:
+Un mot ou deux en français, avec des accents en UTF-8:
ça, où est le pré près du prêt?
Reply all
Reply to author
Forward
0 new messages