@@ -388,6 +388,16 @@ private static ImmutableList<Token> joinAdjacentLiteralsAndAdjacentWhitespace(Li
388388 continue ;
389389 }
390390
391+ if (seenWhitespace .indexOf ("\n " ) >= 0
392+ && !hasMultipleNewlines (seenWhitespace .toString ())
393+ && isHyphenatedWordEnd (accumulated )
394+ && tokens .peek ().getType () == LITERAL
395+ && isWordStart (tokens .peek ().getValue ())
396+ && !isSuspendedHyphenConjunction (tokens .peek ().getValue ())) {
397+ accumulated .append (tokens .next ().getValue ());
398+ continue ;
399+ }
400+
391401 output .add (new Token (LITERAL , accumulated .toString ()));
392402 accumulated .setLength (0 );
393403
@@ -399,13 +409,26 @@ private static ImmutableList<Token> joinAdjacentLiteralsAndAdjacentWhitespace(Li
399409 // We have another token coming, possibly of type OTHER. Leave it for the next iteration.
400410 }
401411
402- /*
403- * TODO(cpovirk): Another case where we could try to join tokens is if a line ends with
404- * /[^ -]-/, as in "non-\nblocking."
405- */
406412 return output .build ();
407413 }
408414
415+ private static boolean isHyphenatedWordEnd (CharSequence cs ) {
416+ int length = cs .length ();
417+ return length >= 2 && cs .charAt (length - 1 ) == '-' && isWordChar (cs .charAt (length - 2 ));
418+ }
419+
420+ private static boolean isWordChar (char c ) {
421+ return Character .isLetterOrDigit (c ) || c == '_' ;
422+ }
423+
424+ private static boolean isWordStart (String s ) {
425+ return !s .isEmpty () && isWordChar (s .charAt (0 ));
426+ }
427+
428+ private static boolean isSuspendedHyphenConjunction (String s ) {
429+ return s .equals ("and" ) || s .equals ("or" );
430+ }
431+
409432 /**
410433 * Where the input has two consecutive line breaks between literals, insert a {@code <p>} tag between the literals.
411434 *
0 commit comments