[california] Linkify event description: Bug #726846
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [california] Linkify event description: Bug #726846
- Date: Wed, 18 Jun 2014 22:43:22 +0000 (UTC)
commit a63abf547c141fbe6f823fb91921d20140964aaf
Author: Jim Nelson <jim yorba org>
Date: Wed Jun 18 15:42:57 2014 -0700
Linkify event description: Bug #726846
src/Makefile.am | 2 +
src/application/california-application.vala | 2 +
src/host/host-show-event.vala | 21 ++++++-
src/util/util-markup.vala | 84 +++++++++++++++++++++++++++
src/util/util.vala | 26 ++++++++
5 files changed, 133 insertions(+), 2 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 2d87178..2b50cad 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -125,7 +125,9 @@ california_VALASOURCES = \
toolkit/toolkit-popup.vala \
toolkit/toolkit-stack-model.vala \
\
+ util/util.vala \
util/util-gfx.vala \
+ util/util-markup.vala \
util/util-memory.vala \
util/util-string.vala \
util/util-uri.vala \
diff --git a/src/application/california-application.vala b/src/application/california-application.vala
index bab1a70..6d2405f 100644
--- a/src/application/california-application.vala
+++ b/src/application/california-application.vala
@@ -167,6 +167,7 @@ public class Application : Gtk.Application {
// unit initialization
try {
+ Util.init();
Host.init();
Manager.init();
Activator.init();
@@ -188,6 +189,7 @@ public class Application : Gtk.Application {
Activator.terminate();
Manager.terminate();
Host.terminate();
+ Util.terminate();
base.shutdown();
}
diff --git a/src/host/host-show-event.vala b/src/host/host-show-event.vala
index 39acd37..18d5200 100644
--- a/src/host/host-show-event.vala
+++ b/src/host/host-show-event.vala
@@ -80,7 +80,7 @@ public class ShowEvent : Gtk.Grid, Toolkit.Card {
set_label(when_label, when_text, event.get_event_time_pretty_string(Calendar.Timezone.local));
// description
- set_label(null, description_text, escape(event.description));
+ set_label(null, description_text, Markup.linkify(escape(event.description), linkify_delegate));
// don't current support updating or removing recurring events properly; see
// https://bugzilla.gnome.org/show_bug.cgi?id=725786
@@ -94,7 +94,24 @@ public class ShowEvent : Gtk.Grid, Toolkit.Card {
}
private string? escape(string? plain) {
- return !String.is_empty(plain) ? Markup.escape_text(plain) : plain;
+ return !String.is_empty(plain) ? GLib.Markup.escape_text(plain) : plain;
+ }
+
+ private bool linkify_delegate(string uri, bool known_protocol, out string? pre_markup,
+ out string? post_markup) {
+ // preserve but don't linkify if unknown protocol
+ if (!known_protocol) {
+ pre_markup = null;
+ post_markup = null;
+
+ return true;
+ }
+
+ // anchor it
+ pre_markup = "<a href=\"%s\">".printf(uri);
+ post_markup = "</a>";
+
+ return true;
}
// Note that text is not escaped, up to caller to determine if necessary or not.
diff --git a/src/util/util-markup.vala b/src/util/util-markup.vala
new file mode 100644
index 0000000..e633cf1
--- /dev/null
+++ b/src/util/util-markup.vala
@@ -0,0 +1,84 @@
+/* Copyright 2014 Yorba Foundation
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+namespace California.Markup {
+
+/**
+ * Given a URI, return the prefix markup and the postfix markup as strings.
+ *
+ * known_protocol indicates the URI has a well-known protocol (i.e. http:// or ftp://, etc.)
+ *
+ * Returns false if the uri should not be included in the string returned by { link linkify}. To
+ * leave a URI bare, return null for both strings and return true.
+ */
+public delegate bool LinkifyDelegate(string uri, bool known_protocol, out string? pre_markup,
+ out string? post_markup);
+
+// Regex to detect URLs.
+// Originally from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
+private const string URL_REGEX =
"(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»“”‘’]))";
+
+// Regex to determine if a URL has a known protocol.
+private const string PROTOCOL_REGEX =
"^(aim|apt|bitcoin|cvs|ed2k|ftp|file|finger|git|gtalk|http|https|irc|ircs|irc6|lastfm|ldap|ldaps|magnet|news|nntp|rsync|sftp|skype|smb|sms|svn|telnet|tftp|ssh|webcal|xmpp):";
+
+private Regex url_regex;
+private Regex protocol_regex;
+
+/**
+ * Called by Util.init()
+ */
+internal void init() throws Error {
+ url_regex = new Regex(URL_REGEX, RegexCompileFlags.CASELESS | RegexCompileFlags.OPTIMIZE);
+ protocol_regex = new Regex(PROTOCOL_REGEX, RegexCompileFlags.CASELESS | RegexCompileFlags.OPTIMIZE);
+}
+
+/**
+ * Called by Util.terminate()
+ */
+internal void terminate() {
+ url_regex = null;
+ protocol_regex = null;
+}
+
+/**
+ * Replace all the URIs in a string with link markup provided by { link LinkifyDelegate}.
+ *
+ * NOTE: linkify() is not thread-safe.
+ */
+public string? linkify(string? unlinked, LinkifyDelegate linkify_cb) {
+ if (String.is_empty(unlinked))
+ return unlinked;
+
+ try {
+ return url_regex.replace_eval(unlinked, -1, 0, 0, (match_info, result) => {
+ // match zero is the only match we're interested in
+ string? url = match_info.fetch(0);
+ if (String.is_empty(url))
+ return false;
+
+ // have original caller provide markup (or drop the URL)
+ string? pre_markup, post_markup;
+ if (!linkify_cb(url, protocol_regex.match(url), out pre_markup, out post_markup))
+ return false;
+
+ // put it all together
+ result.append_printf("%s%s%s",
+ (pre_markup != null) ? pre_markup : "",
+ url,
+ (post_markup != null) ? post_markup : ""
+ );
+
+ return false;
+ });
+ } catch (RegexError rerr) {
+ debug("Unable to linkify string: %s", rerr.message);
+
+ return unlinked;
+ }
+}
+
+}
+
diff --git a/src/util/util.vala b/src/util/util.vala
new file mode 100644
index 0000000..8bc0b78
--- /dev/null
+++ b/src/util/util.vala
@@ -0,0 +1,26 @@
+/* Copyright 2014 Yorba Foundation
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+namespace California.Util {
+
+private int init_count = 0;
+
+public void init() throws Error {
+ if (!Unit.do_init(ref init_count))
+ return;
+
+ // internal init
+ Markup.init();
+}
+
+public void terminate() {
+ if (!Unit.do_terminate(ref init_count))
+ return;
+
+ Markup.terminate();
+}
+
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]