public string CreateHtmlAnchor(ref string text, List<string> replyToIds, Entities entities, Dictionary<string, string> media) { string ret = text; if (entities != null) { var entityInfos = new SortedList<int, EntityInfo>(); // URL if (entities.Urls != null) { foreach (var ent in entities.Urls) { if (string.IsNullOrEmpty(ent.DisplayUrl)) { var tmpEntity = new EntityInfo { StartIndex = ent.Indices[0], EndIndex = ent.Indices[1], Text = ent.Url, Html = string.Format("<a href=\"{0}\">{0}</a>", ent.Url) }; entityInfos.Add(ent.Indices[0], tmpEntity); } else { string expanded = ShortUrl.ResolveMedia(ent.ExpandedUrl, false); var tmp = new EntityInfo { StartIndex = ent.Indices[0], EndIndex = ent.Indices[1], Text = ent.Url, Html = string.Format("<a href=\"{0}\" title=\"{1}\">{2}</a>", ent.Url, expanded, ent.DisplayUrl), Display = ent.DisplayUrl }; entityInfos.Add(ent.Indices[0], tmp); if (media != null && !media.ContainsKey(ent.Url)) { media.Add(ent.Url, expanded); } } } } if (entities.Hashtags != null) { foreach (var ent in entities.Hashtags) { string hash = text.Substring(ent.Indices[0], ent.Indices[1] - ent.Indices[0]); var tmp = new EntityInfo { StartIndex = ent.Indices[0], EndIndex = ent.Indices[1], Text = hash, Html = string.Format("<a href=\"{0}twitter.com/search?q=%23{1}\">{2}</a>", Protocol, ent.Text, hash) }; entityInfos.Add(ent.Indices[0], tmp); lock (_lockObj) { _hashList.Add("#" + ent.Text); } } } if (entities.UserMentions != null) { foreach (var ent in entities.UserMentions) { string screenName = text.Substring(ent.Indices[0] + 1, ent.Indices[1] - ent.Indices[0] - 1); var tmp = new EntityInfo { StartIndex = ent.Indices[0] + 1, EndIndex = ent.Indices[1], Text = ent.ScreenName, Html = string.Format("<a href=\"/{0}\">{1}</a>", ent.ScreenName, screenName) }; entityInfos.Add(ent.Indices[0] + 1, tmp); if (!replyToIds.Contains(ent.ScreenName.ToLower())) { replyToIds.Add(ent.ScreenName.ToLower()); } } } if (entities.Media != null) { foreach (var ent in entities.Media) { if (ent.Type == "photo") { var tmp = new EntityInfo { StartIndex = ent.Indices[0], EndIndex = ent.Indices[1], Text = ent.Url, Html = string.Format("<a href=\"{0}\" title=\"{1}\">{2}</a>", ent.Url, ent.ExpandedUrl, ent.DisplayUrl), Display = ent.DisplayUrl }; entityInfos.Add(ent.Indices[0], tmp); if (media != null && !media.ContainsKey(ent.Url)) { media.Add(ent.Url, ent.MediaUrl); } } } } if (entityInfos.Count > 0) { try { int idx = 0; ret = string.Empty; foreach (var et in entityInfos) { ret += text.Substring(idx, et.Key - idx) + et.Value.Html; idx = et.Value.EndIndex; } ret += text.Substring(idx); } catch (ArgumentOutOfRangeException) { // Twitterのバグで不正なエンティティ(Index指定範囲が重なっている)が返ってくる場合の対応 ret = text; if (media != null) { media.Clear(); } } } } ret = Regex.Replace(ret, "(^|[^a-zA-Z0-9_/&##@@>=.~])(sm|nm)([0-9]{1,10})", "$1<a href=\"http://www.nicovideo.jp/watch/$2$3\">$2$3</a>"); ret = AdjustHtml(ShortUrl.Resolve(PreProcessUrl(ret), false)); // IDN置換、短縮Uri解決、@リンクを相対→絶対にしてtarget属性付与 return ret; }
private string ReplaceTextFromApi(string text, Entities entities) { if (entities != null) { if (entities.Urls != null) { foreach (var m in entities.Urls) { if (!string.IsNullOrEmpty(m.DisplayUrl)) { text = text.Replace(m.Url, m.DisplayUrl); } } } if (entities.Media != null) { foreach (var m in entities.Media) { if (!string.IsNullOrEmpty(m.DisplayUrl)) { text = text.Replace(m.Url, m.DisplayUrl); } } } } return text; }