Skip to content

Commit b7b9f1c

Browse files
committed
GetExtendedTweetElements
1 parent 22657f3 commit b7b9f1c

File tree

11 files changed

+104
-36
lines changed

11 files changed

+104
-36
lines changed

CoreTweetSupplement.Pcl/CoreTweetSupplement.Pcl.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@
4646
</Compile>
4747
</ItemGroup>
4848
<ItemGroup>
49-
<Reference Include="CoreTweet, Version=0.6.1.267, Culture=neutral, processorArchitecture=MSIL">
50-
<HintPath>..\packages\CoreTweet.0.6.1.267\lib\portable-net45+dnxcore50+win8+wpa81+MonoAndroid+xamarinios+MonoTouch\CoreTweet.dll</HintPath>
49+
<Reference Include="CoreTweet, Version=0.6.3.296, Culture=neutral, processorArchitecture=MSIL">
50+
<HintPath>..\packages\CoreTweet.0.6.3.296\lib\portable-net45+dnxcore50+win8+wpa81+MonoAndroid+xamarinios+MonoTouch\CoreTweet.dll</HintPath>
5151
<Private>True</Private>
5252
</Reference>
5353
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
3-
<package id="CoreTweet" version="0.6.1.267" targetFramework="portable45-net45+win8+wpa81" />
3+
<package id="CoreTweet" version="0.6.3.296" targetFramework="portable45-net45+win8+wpa81" />
44
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="portable45-net45+win8+wpa81" />
55
</packages>

CoreTweetSupplement/CoreTweetSupplement.cs

Lines changed: 86 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public static Source ParseSource(this Status status)
103103
return ParseSource(status.Source);
104104
}
105105

106-
private static List<DoubleUtf16Char> EnumerateChars(string str)
106+
private static List<DoubleUtf16Char> GetCodePoints(string str)
107107
{
108108
var result = new List<DoubleUtf16Char>(str.Length);
109109
for (var i = 0; i < str.Length; i++)
@@ -116,21 +116,6 @@ private static List<DoubleUtf16Char> EnumerateChars(string str)
116116
return result;
117117
}
118118

119-
private static string ToString(IList<DoubleUtf16Char> source, int start)
120-
{
121-
var sourceLen = source.Count;
122-
var arr = new char[sourceLen * 2];
123-
var strLen = 0;
124-
for (var i = start; i < sourceLen; i++)
125-
{
126-
var x = source[i];
127-
arr[strLen++] = x.X;
128-
if (char.IsHighSurrogate(x.X))
129-
arr[strLen++] = x.Y;
130-
}
131-
return new string(arr, 0, strLen);
132-
}
133-
134119
private static string ToString(IList<DoubleUtf16Char> source, int start, int count)
135120
{
136121
var arr = new char[count * 2];
@@ -154,8 +139,34 @@ private static string ToString(IList<DoubleUtf16Char> source, int start, int cou
154139
/// <returns>An <see cref="IEnumerable{ITextPart}"/> whose elements are parts of <paramref name="text"/>.</returns>
155140
public static IEnumerable<TextPart> EnumerateTextParts(string text, Entities entities)
156141
{
142+
var chars = GetCodePoints(text);
143+
return EnumerateTextParts(chars, entities, 0, chars.Count);
144+
}
145+
146+
/// <summary>
147+
/// Enumerates parts split into Tweet Entities.
148+
/// </summary>
149+
/// <param name="text">The text such as <see cref="Status.Text"/>, <see cref="DirectMessage.Text"/> and <see cref="User.Description"/>.</param>
150+
/// <param name="entities">The <see cref="Entities"/> instance.</param>
151+
/// <param name="startIndex">The starting character position in code point.</param>
152+
/// <param name="endIndex">The ending character position in code point.</param>
153+
/// <returns>An <see cref="IEnumerable{ITextPart}"/> whose elements are parts of <paramref name="text"/>.</returns>
154+
public static IEnumerable<TextPart> EnumerateTextParts(string text, Entities entities, int startIndex, int endIndex)
155+
{
156+
return EnumerateTextParts(GetCodePoints(text), entities, startIndex, endIndex);
157+
}
158+
159+
private static IEnumerable<TextPart> EnumerateTextParts(IList<DoubleUtf16Char> chars, Entities entities, int startIndex, int endIndex)
160+
{
161+
if (startIndex < 0 || startIndex >= chars.Count)
162+
throw new ArgumentOutOfRangeException(nameof(startIndex));
163+
164+
if (endIndex < startIndex || endIndex > chars.Count)
165+
throw new ArgumentOutOfRangeException(nameof(endIndex));
166+
157167
if (entities == null)
158168
{
169+
var text = ToString(chars, startIndex, endIndex - startIndex);
159170
yield return new TextPart()
160171
{
161172
RawText = text,
@@ -202,7 +213,7 @@ public static IEnumerable<TextPart> EnumerateTextParts(string text, Entities ent
202213
Type = TextPartType.Url,
203214
Start = e.Indices[0],
204215
End = e.Indices[1],
205-
RawText = e.Url.ToString(),
216+
RawText = e.Url,
206217
Text = e.DisplayUrl,
207218
Entity = e
208219
})
@@ -219,11 +230,13 @@ public static IEnumerable<TextPart> EnumerateTextParts(string text, Entities ent
219230
Entity = e
220231
})
221232
)
233+
.Where(e => e.Start >= startIndex && e.Start < endIndex)
222234
.OrderBy(part => part.Start)
223235
);
224236

225237
if (list.Count == 0)
226238
{
239+
var text = ToString(chars, startIndex, endIndex - startIndex);
227240
yield return new TextPart()
228241
{
229242
RawText = text,
@@ -233,11 +246,10 @@ public static IEnumerable<TextPart> EnumerateTextParts(string text, Entities ent
233246
}
234247

235248
var current = list.First;
236-
var chars = EnumerateChars(text);
237249

238250
while (true)
239251
{
240-
var start = current.Previous?.Value.End ?? 0;
252+
var start = current.Previous?.Value.End ?? startIndex;
241253
var count = current.Value.Start - start;
242254
if (count > 0)
243255
{
@@ -256,9 +268,9 @@ public static IEnumerable<TextPart> EnumerateTextParts(string text, Entities ent
256268
}
257269

258270
var lastStart = current.Value.End;
259-
if (lastStart < chars.Count)
271+
if (lastStart < endIndex)
260272
{
261-
var lastOutput = ToString(chars, lastStart);
273+
var lastOutput = ToString(chars, lastStart, endIndex - lastStart);
262274
yield return new TextPart()
263275
{
264276
RawText = lastOutput,
@@ -287,6 +299,38 @@ public static IEnumerable<TextPart> EnumerateTextParts(this DirectMessage dm)
287299
return EnumerateTextParts(dm.Text, dm.Entities);
288300
}
289301

302+
/// <summary>
303+
/// Enumerates parts split into Tweet Entities.
304+
/// </summary>
305+
/// <param name="status">The <see cref="Status"/> instance.</param>
306+
/// <returns>An <see cref="ExtendedTweetInfo"/> instance.</returns>
307+
public static ExtendedTweetInfo GetExtendedTweetElements(this Status status)
308+
{
309+
var displayTextRange = status.DisplayTextRange ?? status.ExtendedTweet?.DisplayTextRange;
310+
if (displayTextRange == null)
311+
return new ExtendedTweetInfo
312+
{
313+
TweetText = status.EnumerateTextParts().ToArray(),
314+
HiddenPrefix = new UserMentionEntity[0],
315+
HiddenSuffix = new UrlEntity[0]
316+
};
317+
318+
var start = displayTextRange[0];
319+
var end = displayTextRange[1];
320+
return new ExtendedTweetInfo
321+
{
322+
TweetText = EnumerateTextParts(
323+
status.FullText ?? status.ExtendedTweet?.FullText ?? status.Text,
324+
status.Entities,
325+
start, end).ToArray(),
326+
HiddenPrefix = status.Entities?.UserMentions == null ? new UserMentionEntity[0]
327+
: status.Entities.UserMentions.Where(x => x.Indices[0] < start).ToArray(),
328+
HiddenSuffix = (status.Entities?.Urls ?? Enumerable.Empty<UrlEntity>())
329+
.Concat(status.Entities?.Media ?? Enumerable.Empty<UrlEntity>())
330+
.Where(x => x.Indices[0] >= end).ToArray()
331+
};
332+
}
333+
290334
/// <summary>
291335
/// Returns the URI suffix for given profile size image variant. See User Profile Images and Banners.
292336
/// </summary>
@@ -443,4 +487,25 @@ public DoubleUtf16Char(char x, char y)
443487
this.Y = y;
444488
}
445489
}
490+
491+
/// <summary>
492+
/// Represents a Tweet rendered in Extended mode.
493+
/// </summary>
494+
public class ExtendedTweetInfo
495+
{
496+
/// <summary>
497+
/// The elements of Tweet Text part.
498+
/// </summary>
499+
public TextPart[] TweetText { get; set; }
500+
501+
/// <summary>
502+
/// Replies.
503+
/// </summary>
504+
public UserMentionEntity[] HiddenPrefix { get; set; }
505+
506+
/// <summary>
507+
/// Attachment URLs.
508+
/// </summary>
509+
public UrlEntity[] HiddenSuffix { get; set; }
510+
}
446511
}

CoreTweetSupplement/CoreTweetSupplement.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141
<Compile Include="Properties\AssemblyInfo.cs" />
4242
</ItemGroup>
4343
<ItemGroup>
44-
<Reference Include="CoreTweet, Version=0.6.1.267, Culture=neutral, processorArchitecture=MSIL">
45-
<HintPath>..\packages\CoreTweet.0.6.1.267\lib\net40\CoreTweet.dll</HintPath>
44+
<Reference Include="CoreTweet, Version=0.6.3.296, Culture=neutral, processorArchitecture=MSIL">
45+
<HintPath>..\packages\CoreTweet.0.6.3.296\lib\net40\CoreTweet.dll</HintPath>
4646
<Private>True</Private>
4747
</Reference>
4848
<Reference Include="System" />

CoreTweetSupplement/CoreTweetSupplement.nuspec

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
<copyright>(c) 2014-2016 CoreTweet Development Team</copyright>
1414
<tags>Twitter</tags>
1515
<dependencies>
16-
<dependency id="CoreTweet" version="0.6.1.267" />
16+
<dependency id="CoreTweet" version="0.6.3.296" />
1717
</dependencies>
1818
</metadata>
1919
<files>
2020
<file src="bin\Release\CoreTweetSupplement.dll" target="lib\net40\CoreTweetSupplement.dll" />
2121
<file src="bin\Release\CoreTweetSupplement.xml" target="lib\net40\CoreTweetSupplement.xml" />
22-
<file src="..\CoreTweetSupplement.Pcl\bin\Release\CoreTweetSupplement.dll" target="lib\portable-net4+wp8+win81+wpa81+MonoAndroid+MonoTouch\CoreTweetSupplement.dll" />
23-
<file src="..\CoreTweetSupplement.Pcl\bin\Release\CoreTweetSupplement.xml" target="lib\portable-net4+wp8+win81+wpa81+MonoAndroid+MonoTouch\CoreTweetSupplement.xml" />
22+
<file src="..\CoreTweetSupplement.Pcl\bin\Release\CoreTweetSupplement.dll" target="lib\portable-net45+dnxcore50+win8+wpa81+MonoAndroid+xamarinios+MonoTouch\CoreTweetSupplement.dll" />
23+
<file src="..\CoreTweetSupplement.Pcl\bin\Release\CoreTweetSupplement.xml" target="lib\portable-net45+dnxcore50+win8+wpa81+MonoAndroid+xamarinios+MonoTouch\CoreTweetSupplement.xml" />
2424
</files>
2525
</package>

CoreTweetSupplement/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@
1111
[assembly: AssemblyCulture("")]
1212
[assembly: NeutralResourcesLanguage("en")]
1313

14-
[assembly: AssemblyVersion("1.5.0.0")]
15-
[assembly: AssemblyFileVersion("1.5.0.0")]
14+
[assembly: AssemblyVersion("1.6.0.0")]
15+
[assembly: AssemblyFileVersion("1.6.0.0")]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
3-
<package id="CoreTweet" version="0.6.1.267" targetFramework="net40" />
3+
<package id="CoreTweet" version="0.6.3.296" targetFramework="net40" />
44
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net4" />
55
</packages>

CoreTweetSupplementTest/CoreTweetSupplementTest.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141
</DocumentationFile>
4242
</PropertyGroup>
4343
<ItemGroup>
44-
<Reference Include="CoreTweet, Version=0.6.1.267, Culture=neutral, processorArchitecture=MSIL">
45-
<HintPath>..\packages\CoreTweet.0.6.1.267\lib\net45\CoreTweet.dll</HintPath>
44+
<Reference Include="CoreTweet, Version=0.6.3.296, Culture=neutral, processorArchitecture=MSIL">
45+
<HintPath>..\packages\CoreTweet.0.6.3.296\lib\net45\CoreTweet.dll</HintPath>
4646
<Private>True</Private>
4747
</Reference>
4848
<Reference Include="Microsoft.CSharp" />
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
33
<package id="ChainingAssertion" version="1.7.1.0" targetFramework="net45" />
4-
<package id="CoreTweet" version="0.6.1.267" targetFramework="net45" />
4+
<package id="CoreTweet" version="0.6.3.296" targetFramework="net45" />
55
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net45" />
66
</packages>

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ Enumerates order sorted and HTML-decoded parts of the text.
2727

2828
Example: [TestEnumerateTextParts](https://github.com/azyobuzin/CoreTweetSupplement/blob/f695b971fb2415180b7091bbc0b78280bda5e7ff/CoreTweetSupplementTest/CoreTweetSupplementTest.cs#L53-L332)
2929

30+
## GetExtendedTweetElements(this Status) ##
31+
A variation of EnumerateTextParts which supports the new structure of Tweets.
32+
3033
## GetProfileImageUrl / GetProfileImageUrlHttps(this User, string) ##
3134
This is a method to get a URL pointing to the user's avatar image with given size.
3235

0 commit comments

Comments
 (0)