summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/format.cc
diff options
context:
space:
mode:
authorharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2008-10-13 11:16:17 +0000
committerharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2008-10-13 11:16:17 +0000
commit3800d44b7952e7ae1f05b711ad46268dde11821d (patch)
tree0f3726a7ecc2ce8690b55ea91ad9cf3ac1f99d65 /crawl-ref/source/format.cc
parentdc024449143f2b6d6599bc41dabfbb3109a76999 (diff)
downloadcrawl-ref-3800d44b7952e7ae1f05b711ad46268dde11821d.tar.gz
crawl-ref-3800d44b7952e7ae1f05b711ad46268dde11821d.zip
Fix 2162827: tag length calculation was incorrect.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7230 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/format.cc')
-rw-r--r--crawl-ref/source/format.cc93
1 files changed, 93 insertions, 0 deletions
diff --git a/crawl-ref/source/format.cc b/crawl-ref/source/format.cc
index e4280e5038..9cd282e058 100644
--- a/crawl-ref/source/format.cc
+++ b/crawl-ref/source/format.cc
@@ -577,3 +577,96 @@ int count_linebreaks(const formatted_string& fs)
}
return count;
}
+
+// Return the actual (string) offset of character #loc to be printed,
+// i.e. ignoring tags. So for instance, if s == "<tag>ab</tag>", then
+// _find_string_location(s, 2) == 6.
+int _find_string_location(const std::string& s, int loc)
+{
+ int real_offset = 0;
+ bool in_tag = false;
+ int last_taglen = 0;
+ int offset = 0;
+ for (std::string::const_iterator ci = s.begin();
+ ci != s.end() && real_offset < loc;
+ ++ci, ++offset)
+ {
+ if (in_tag)
+ {
+ if (*ci == '<' && last_taglen == 1)
+ {
+ ++real_offset;
+ in_tag = false;
+ }
+ else if (*ci == '>')
+ {
+ in_tag = false;
+ }
+ else
+ {
+ ++last_taglen;
+ }
+ }
+ else if (*ci == '<')
+ {
+ in_tag = true;
+ last_taglen = 1;
+ }
+ else
+ {
+ ++real_offset;
+ }
+ }
+ return (offset);
+}
+
+// Return the substring of s from character start to character end,
+// where tags count as length 0.
+std::string tagged_string_substr(const std::string& s, int start, int end)
+{
+ return (s.substr(_find_string_location(s, start),
+ _find_string_location(s, end)));
+}
+
+int tagged_string_printable_length(const std::string& s)
+{
+ int len = 0;
+ bool in_tag = false;
+ int last_taglen = 0;
+ for (std::string::const_iterator ci = s.begin(); ci != s.end(); ++ci)
+ {
+ if (in_tag)
+ {
+ if (*ci == '<' && last_taglen == 1) // "<<" sequence
+ {
+ in_tag = false; // this is an escape for '<'
+ ++len; // len wasn't incremented before
+ }
+ else if (*ci == '>') // tag close, still nothing printed
+ {
+ in_tag = false;
+ }
+ else // tag continues
+ {
+ ++last_taglen;
+ }
+ }
+ else if (*ci == '<') // tag starts
+ {
+ in_tag = true;
+ last_taglen = 1;
+ }
+ else // normal, printable character
+ {
+ ++len;
+ }
+ }
+ return (len);
+}
+
+
+// Count the length of the tags in the string.
+int tagged_string_tag_length(const std::string& s)
+{
+ return s.size() - tagged_string_printable_length(s);
+}