You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
2.5 KiB
C

#include "model/status.h"
// Submodules
#include "collections/array.h"
#include "util/format.h"
// Model
#include "model/account.h"
#include "model/emoji.h"
// Standard Library
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <ctype.h>
char* status_render_source( struct status* s )
{
if( s->content ) {
goto done;
}
if( !s->source ) {
s->content = strdup("");
goto done;
}
char account_server[50]; {
struct account* status_account = account_from_id(s->account_id);
strncpy( account_server, status_account->server, 50 );
account_free(status_account);
}
char* result = NULL;
size_t size = 0;
FILE* f = open_memstream(&result,&size);
for( char* i = s->source; *i; ++i ) {
// Handle URLs
if( 0 == strncmp( i, "https://", 8 ) ) {
char* start = i;
while( *i && !index(" ,\r\n\t",*i) ) ++i;
char* url = strndup( start, i - start );
fprintf( f, "<a href='%s' rel='ugc'>%s</a>", url, url );
free(url);
} else if( isalpha(i[1]) && *i == '@' ) {
char* start = i;
while( *i && !index(" ,\r\n",*i) ) ++i;
char* handle = strndup( start, i - start );
struct account* user = account_from_webfinger( &handle[1] );
if( !user ) {
char buffer[512];
format( buffer, 512, "%s@%s", handle, account_server );
user = account_from_webfinger( &handle[1] );
}
if( user ) {
status_add_mention( s, user->id );
fprintf( f,
"<span class='h-card'>"
"<a class='u-url mention' href='%s' rel='ugc'>"
"@<span>%s</span>"
"</a>"
"</span>",
user->account_url, user->handle
);
account_free(user);
} else {
fprintf( f, "%s", handle );
}
free(handle);
} else if( *i == ':' ) {
// Emoji
++i;
char* start = i;
while( *i && !index(" ,:",*i) ) ++i;
char* shortcode = strndup( start, i - start );
// Check if shortcode is already present in status
for( int i = 0; i < s->emoji.count; ++i ) {
struct emoji* e = s->emoji.items[i];
if( 0 == strcmp( e->shortcode, shortcode ) ) { goto already_has_emoji; }
}
struct emoji* e = emoji_from_shortcode( shortcode );
if( e ) {
array_append( &s->emoji, sizeof(e), &e );
}
already_has_emoji:
fprintf( f, ":%s", shortcode );
free(shortcode);
} else if( *i == '\n' ) {
fprintf( f, "<br/>" );
continue;
} else if( *i == '\r' ) {
// Ignore
}
if( !*i ) { break; }
fputc( *i, f );
}
fputc( '\0', f );
fclose(f);
s->content = result;
done:
status_save(s);
return s->content;
}