Index: code/mission/missionbriefcommon.cpp
===================================================================
--- code/mission/missionbriefcommon.cpp	(revision 5643)
+++ code/mission/missionbriefcommon.cpp	(working copy)
@@ -1253,26 +1253,34 @@
 // Render a line of text for the briefings.  Lines are drawn in as a wipe, with leading bright
 // white characters.  Have to jump through some hoops since we support colored words.  This means
 // that we need to process the line one character at a time.
+//
+// @param line_num number of the line of the briefing page to be drawn
+// @x     horizontal position where the text is drawn
+// @y     vertical position where the text is drawn
+// @instance index of Colored_stream of the text page to display
 void brief_render_line(int line_num, int x, int y, int instance)
 {
-	int len, count, next, truncate_len, last_color, offset, w, h, bright_len, i;
-	char line[MAX_BRIEF_LINE_LEN];
-	SCP_vector<colored_char> *src; 
-
-	src = &Colored_stream[instance].at(line_num);
-	len = src->size();
-
-	if (len == 0){
+    Assert( 0<=instance && instance < (sizeof(Colored_stream)/sizeof(*Colored_stream)) );
+    
+    SCP_vector<colored_char> *src = &Colored_stream[instance].at(line_num);
+	
+	// empty strings have not to be drawn
+    int src_len = src->size();
+    if (src_len == 0){
 		return;
 	}
 
-	truncate_len = fl2i(Brief_text_wipe_time_elapsed / BRIEF_TEXT_WIPE_TIME * Max_briefing_line_len);
-	if (truncate_len > len){
-		truncate_len = len;
+    // truncate_len is the number of character currently displayed including the bright white characters
+	int truncate_len = fl2i(Brief_text_wipe_time_elapsed / BRIEF_TEXT_WIPE_TIME * Max_briefing_line_len);
+	if (truncate_len > src_len){
+		truncate_len = src_len;
 	}
 
-	bright_len = 0;
-	if (truncate_len < len) {
+    // truncate_len is going to be the number of character displayed with normal intensity
+    // bright_len is the additional characters displayed with high intensity
+    // bright_len+truncate_len<len chars are displayed
+	int bright_len = 0;
+	if (truncate_len < src_len) {
 		if (truncate_len <= BRIGHTEN_LEAD) {
 			bright_len = truncate_len;
 			truncate_len = 0;
@@ -1283,69 +1291,67 @@
 		}
 	}
 
-	offset = 0;
-	count  = 0;
-	next	 = 0;
-
+    int char_seq_pos=0; //Cursor position into the following character sequence
+	char char_seq[MAX_BRIEF_LINE_LEN];	
+	int offset = 0; //offset is the horizontal position of the screen where strings are drawn
 	gr_set_color_fast(&Color_white);
-	last_color = BRIEF_TEXT_WHITE;
-	for (i=0; i<truncate_len; i++) {
-		if (count >= truncate_len){
-			break;
-		}
 
-		line[next] = src->at(count).letter;
+    // PART1: Draw the the briefing line part with normal intensity and words colours.
+    // The following algorythm builds a character sequence of color 'last_color' into 'line' buffer.
+    // When the colour changes, the buffer drawn and reset.
+    {
+        int last_color = src->at(0).color;    
+        for (int current_pos=0; current_pos<truncate_len; current_pos++) {
+            colored_char &current_char=src->at(current_pos);		
+            //when the current color changes, the accumulated character sequence is drawn.
+            if (current_char.color != last_color){
+                //add a 0 terminal character to make line a valid C string
+                Assert(char_seq_pos<sizeof(char_seq));
+                char_seq[char_seq_pos] = 0;         
+                
+                // Draw coloured text, and increment cariage position
+                {
+                    int w=0,h=0;
+                    brief_set_text_color(last_color);        
+                    gr_string(x + offset, y, char_seq);
+                    gr_get_string_size(&w, &h, char_seq);
+                    offset += w;
+                }
+                //clear char buffer
+                char_seq_pos = 0;
+                last_color = current_char.color;
+            }
 
-		if (is_white_space(line[next])) {
-			// end of word reached, blit it
-			line[next + 1] = 0;
-			gr_string(x + offset, y, line);
-			gr_get_string_size(&w, &h, line);
-			offset += w;
-			next = 0;
+            Assert(char_seq_pos<sizeof(char_seq));
+            char_seq[char_seq_pos++] = current_char.letter;		
+        }	
 
-			// reset color
-			if (last_color != BRIEF_TEXT_WHITE) {
-				brief_set_text_color(BRIEF_TEXT_WHITE);
-				last_color = BRIEF_TEXT_WHITE;
-			}
+        // Draw the final chunk of acumulated characters
+        // Add a 0 terminal character to make line a valid C string
+        Assert(char_seq_pos<sizeof(char_seq));
+        char_seq[char_seq_pos] = 0;
+        // Draw coloured text, and increment cariage position
+        {
+            int w=0,h=0;
+            brief_set_text_color(last_color);        
+            gr_string(x + offset, y, char_seq);
+            gr_get_string_size(&w, &h, char_seq);
+            offset += w;
+        }
+    }
 
-			count++;
-			continue;
-		}
-
-		if (src->at(count).color != last_color) {
-			brief_set_text_color(src->at(count).color);
-			last_color = src->at(count).color;
-		}
-
-		count++;
-		next++;
-	}	// end for
-
-	line[next] = 0;
-	gr_string(x + offset, y, line);
-
-
-	// draw leading portion of the line bright white
-	if (bright_len) {
-
-		gr_set_color_fast(&Color_bright_white);
-		for (i=0; i<truncate_len+bright_len; i++) {
-			line[i] = src->at(i).letter;
-		}
-
-		line[i] = 0;
-
-
-		if ( truncate_len > 0 )	{
-			int width_dim, height_dim;
-			gr_get_string_size(&width_dim, &height_dim, line, truncate_len );
-			gr_string(x+width_dim, y, &line[truncate_len]);
-		} else {
-			gr_string(x, y, line);
-		}
-	}
+    // PART2: Draw leading bright white characters
+    {
+        char_seq_pos = 0;
+        for( int current_pos = truncate_len; current_pos<truncate_len + bright_len; current_pos++){		
+            Assert(char_seq_pos<sizeof(char_seq));
+            char_seq[char_seq_pos++] = src->at(current_pos).letter;
+        }
+        Assert(char_seq_pos<sizeof(char_seq));
+        char_seq[char_seq_pos] = 0;
+        gr_set_color_fast(&Color_bright_white);
+        gr_string(x + offset, y, char_seq);    
+    }
 }
 
 int brief_text_wipe_finished()
@@ -1574,51 +1580,78 @@
 	gr_set_color_fast(Brief_text_colors[color_index]);
 }
 
-// Set up the Colored_text array.
-// input:		index		=>		Index into Brief_text[] for source text.
-//					instance	=>		Which instance of Colored_text[] to use.  
-//										Value is 0 unless multiple text streams are required.
+
+// Returns true when a character is a word separator. The most usual separators are space
+// characters and punctuation. The following characters are separators 
+// [33;47] u [58;64] U [91;94] U {96} U [123;127]
+// @param character is the character to be analysed
+// @return true when the given character is a word separator, and false when the caracter is part of a word.
+bool is_a_word_separator(char character){
+    return character<=47                    // 48 characters including !"#$%&'()*+,-./
+        || (58<=character && character<=64) //  7 characters :;<=>?@
+        || (91<=character && character<=94) //  4 characters [\]^
+        || (character == 96 )               //  1 character  `
+        || (123<=character&&character<=127);//  5 characters including {|}~
+}
+
+// Builds a vector of colored character vrom a string containing color markups and store it to 
+// Colored_stream table.
+// a color markup is made of a minimum of three characters: 
+//   '$' + a char standing for a color + contigous multiple spaces (chars \t \n and ' ')
+// The markup is completely removed from the resulting character sequence.
+// @param src a not null pointer to a C string terminated by a /0 char.
+// @param instance index into Colored_stream where the result should be placed.
+//	  			   Value is 0 unless multiple text streams are required.
+// @return number of character of the resulting sequence.
+//
+// Here are a few examples of the expected behavior:
+//  "$g Alpha_one, and $g     Delta." gives "[color=green]Alpha_one[/color], and [color=green]Delta[/color].".
+//  "Something $g" gives "Something" whereas it gave "Something $g".
+//  "Something $" gives "Something $".
+
 int brief_text_colorize(char *src, int instance)
 {
-	int len, i, skip_to_next_word = 0;
-	colored_char dest; 
-	briefing_line dest_line; 
+    Assert(src);
+    Assert( 0<=instance && instance < (sizeof(Colored_stream)/sizeof(*Colored_stream)) );
 
-	ubyte active_color_index = BRIEF_TEXT_WHITE;
+    briefing_line dest_line; //the resulting vector of colored character
+	ubyte active_color_index = BRIEF_TEXT_WHITE; //the current drawing color
 
-	len = strlen(src);
-	for (i=0; i<len; i++) {
-		if (skip_to_next_word) {
-			if (is_white_space(src[i])) {
-				skip_to_next_word = 0;
-			}
+	int src_len = strlen(src);
+	for (int i=0; i<src_len; i++) {
 
-			continue;
+        // Is the character a color markup ?
+        // color markup is made of three character: 
+        // '$' + a char standing for a color + a white space
+		if ( src[i] == BRIEF_META_CHAR  // a $ is encountred
+            && i + 1 < src_len          // $ there is at least one character after the markup in this string
+            && ( i + 2 >= src_len  || is_white_space(src[i + 2])) //The following character is white if any
+            ) {
+            i ++;   //Consume the $ character
+			active_color_index = brief_return_color_index(src[i]);
+            i ++; // Consume the color identifier and focus on the white character (if any)
+            
+            // Skip every whitespace until the next word is reached
+            while( i+1 < src_len && is_white_space(src[i+1]) )
+                i++;
+            //The next character is not a whitespace, let's process it as usual
+            continue;
 		}
 
-		if ( src[i] == BRIEF_META_CHAR && is_white_space(src[i + 2]) ) {
-			active_color_index = brief_return_color_index(src[i + 1]);
-			skip_to_next_word = 1;
-			continue;
-		}
-
-		if (is_white_space(src[i])) {
+        // When the word is terminated reset color to white
+        if (is_a_word_separator(src[i])) {
 			active_color_index = BRIEF_TEXT_WHITE;
 		}
 
-		dest.letter = src[i];
+        // Append the character to the result structure
+        colored_char dest;
+        dest.letter = src[i];
 		dest.color = active_color_index;
-
 		dest_line.push_back(dest); 
-	} // end for
+	} 
 
-	// null terminate the line
-	dest.letter = 0;
-	dest.color = BRIEF_TEXT_WHITE; 
-	dest_line.push_back(dest);
-	Colored_stream[instance].push_back(dest_line); 
-	Colored_stream[instance].size();
-	return len;
+	Colored_stream[instance].push_back(dest_line); 	
+    return dest_line.size();
 }
 
 // ------------------------------------------------------------------------------------
