@@ -5,8 +5,8 @@ namespace Yarn.Compiler
55{
66 using System . Collections . Generic ;
77 using System . Linq ;
8- using System . Text . RegularExpressions ;
98 using Antlr4 . Runtime . Misc ;
9+ using Yarn . Markup ;
1010
1111 /// <summary>
1212 /// Extracts node metadata during compilation for language server features.
@@ -20,6 +20,7 @@ internal class NodeMetadataVisitor : YarnSpinnerParserBaseVisitor<object>
2020 private readonly List < NodeMetadata > nodes = new List < NodeMetadata > ( ) ;
2121 private NodeMetadata ? currentNode = null ;
2222 private readonly string fileUri ;
23+ private readonly LineParser lineParser ;
2324 private int previewLineCount = 0 ;
2425 private const int MaxPreviewLines = 3 ;
2526
@@ -31,18 +32,10 @@ internal class NodeMetadataVisitor : YarnSpinnerParserBaseVisitor<object>
3132 private int lastOptionIndent = - 1 ;
3233 private int lastLineNumber = - 1 ;
3334
34- /// <summary>
35- /// Regex for detecting implicit character names in dialogue lines.
36- /// </summary>
37- /// <remarks>
38- /// Matches the pattern "characterName: " at the start of a line.
39- /// This uses the same logic as LineParser for consistency.
40- /// </remarks>
41- private static readonly Regex implicitCharacterRegex = new Regex ( @"^((?:[^:\\]|\\.)*?(?<!\\)):\s*" ) ;
42-
4335 public NodeMetadataVisitor ( string fileUri )
4436 {
4537 this . fileUri = fileUri ;
38+ this . lineParser = new LineParser ( ) ;
4639 }
4740
4841 /// <summary>
@@ -280,18 +273,19 @@ public override object VisitLine_statement([NotNull] YarnSpinnerParser.Line_stat
280273 var lineText = context . line_formatted_text ( ) ? . GetText ( ) ;
281274 if ( ! string . IsNullOrWhiteSpace ( lineText ) )
282275 {
283- // Use the same regex logic as LineParser for consistency.
284- var match = implicitCharacterRegex . Match ( lineText ) ;
285- if ( match . Success )
276+ // TODO: receive locale code from invoker instead of hard-coding
277+ // "en" - it's not relevant to extracting characters but we
278+ // shouldn't be hard-coding locales. It _will_ impact the
279+ // diagnostics (which this current code doesn't use, but it
280+ // should.)
281+ var ( markup , diagnostics ) = lineParser . ParseStringWithDiagnostics ( lineText , "en" ) ;
282+ var charAttr = markup . Attributes . SingleOrDefault ( a => a . Name == "character" ) ;
283+
284+ if ( charAttr . Properties != null && charAttr . TryGetProperty ( "name" , out string ? characterName ) )
286285 {
287- // Extract character name from capture group, unescaping \: to :
288- var characterName = match . Groups [ 1 ] . Value . Trim ( ) . Replace ( "\\ :" , ":" ) ;
289- if ( ! string . IsNullOrWhiteSpace ( characterName ) )
286+ if ( ! currentNode . CharacterNames . Contains ( characterName ) )
290287 {
291- if ( ! currentNode . CharacterNames . Contains ( characterName ) )
292- {
293- currentNode . CharacterNames . Add ( characterName ) ;
294- }
288+ currentNode . CharacterNames . Add ( characterName ) ;
295289 }
296290 }
297291
0 commit comments