UNPKG

tweet-to-html

Version:

Browser friendly package that converts twitter's API tweet objects text property to HTML. Takes care of all the entities and its links. Handles emoji's.

116 lines (93 loc) 3.69 kB
var twemoji = require('twemoji' ); module.exports.parse = parseTweets; var options = {}; function parseTweets(tweets, opts) { options = opts; return Array.isArray(tweets) ? tweets.map(parseTweet) : parseTweet(tweets); } function parseTweet(tweetObj) { var entityProcessors = { hashtags: processHashTags, symbols: processSymbols, user_mentions: processUserMentions, urls: processUrls, media: processMedia }; var entities = tweetObj.entities; var processorObj; //When extended_mode is enabled, the text property will be empty and the value of the html property will be set to the full_text value //Replace the text property because the property is used in other functions (i.e. processUrls) if (tweetObj.full_text) { tweetObj.text = tweetObj.full_text; } //Copying text value to a new property html. The final output will be set to this property tweetObj.html = tweetObj.text; //Process entities if(Object.getOwnPropertyNames(entities).length) { Object.keys(entities).forEach((entity) => { if(entities[entity].length) { processorObj = entities[entity]; //Need to check if entity is media. If so, extended_entities should be used processorObj = entity === 'media' ? tweetObj.extended_entities.media : processorObj; entityProcessors[entity](processorObj, tweetObj); } }); } //Process Emoji's processEmoji(tweetObj); return tweetObj; } function processHashTags(tags, tweetObj) { tags.forEach((tagObj) => { var anchor = ('#' + tagObj.text).link('http://twitter.com/hashtag/' + tagObj.text); tweetObj.html = tweetObj.html.replace('#' + tagObj.text, anchor); }); } function processSymbols(symbols, tweetObj) {} function processUserMentions(users, tweetObj) { users.forEach((userObj) => { var anchor = ('@' + userObj.screen_name).link('http://twitter.com/' + userObj.screen_name); var regex = new RegExp('@' + userObj.screen_name, 'gi' ); tweetObj.html = tweetObj.html.replace(regex, anchor); }); } function processUrls(urls, tweetObj) { urls.forEach((urlObj, index) => { var quotedTweetHtml = ''; var indices = urlObj.indices; var urlToReplace = tweetObj.text.substring(indices[0],indices[1]); if(index === urls.length-1 && tweetObj.quoted_status) { quotedTweetHtml = parseTweets(tweetObj.quoted_status).html; quotedTweetHtml = `<div class="quoted-tweet">${quotedTweetHtml}</div>` } var finalText = quotedTweetHtml || urlObj.display_url.link(urlObj.expanded_url); tweetObj.html = tweetObj.html.replace(urlToReplace, finalText); }); } function processMedia(media, tweetObj) { media.forEach((mediaObj) => { if(mediaObj.type === 'photo') { // Use HTTPS if available var src = mediaObj.media_url_https ? mediaObj.media_url_https : mediaObj.media_url; if(options && options.photoSize && mediaObj.sizes && mediaObj.sizes[options.photoSize]) { // If specified size is available, patch image src to use it src = src + ':' + options.photoSize; } var image = '<img src="' + src + '"/>'; tweetObj.html = tweetObj.html.replace(mediaObj.url, image); } else if(mediaObj.type === 'video') { var source = ''; mediaObj.video_info.variants.forEach((info) => { source += '<source src="'+ info.url +'" type="'+ info.content_type +'">'; }); var video = '<video controls poster="' + mediaObj.media_url +'">' + source + '</video>'; tweetObj.html = tweetObj.html.replace(mediaObj.url, video); } }); } function processEmoji(tweetObj) { tweetObj.html = twemoji.parse(tweetObj.html); }