1313using Markdig ;
1414using Markdig . Extensions . Yaml ;
1515using Markdig . Syntax ;
16+ using YamlDotNet . Serialization ;
1617
1718namespace Elastic . Markdown . IO ;
1819
@@ -106,55 +107,35 @@ public async Task<MarkdownDocument> ParseFullAsync(Cancel ctx)
106107 return document ;
107108 }
108109
109- private void ReadDocumentInstructions ( MarkdownDocument document )
110+ private IReadOnlyDictionary < string , string > GetSubstitutions ( )
110111 {
112+ var globalSubstitutions = MarkdownParser . Configuration . Substitutions ;
113+ var fileSubstitutions = YamlFrontMatter ? . Properties ;
114+ if ( fileSubstitutions is not { Count : >= 0 } )
115+ return globalSubstitutions ;
116+
117+ var allProperties = new Dictionary < string , string > ( fileSubstitutions ) ;
118+ foreach ( var ( key , value ) in globalSubstitutions )
119+ allProperties [ key ] = value ;
120+ return allProperties ;
121+ }
111122
123+ private void ReadDocumentInstructions ( MarkdownDocument document )
124+ {
112125 Title = document
113126 . FirstOrDefault ( block => block is HeadingBlock { Level : 1 } ) ?
114127 . GetData ( "header" ) as string ;
115128
116- if ( document . FirstOrDefault ( ) is YamlFrontMatterBlock yaml )
117- {
118- var raw = string . Join ( Environment . NewLine , yaml . Lines . Lines ) ;
119- YamlFrontMatter = ReadYamlFrontMatter ( raw ) ;
120-
121- // TODO remove when migration tool and our demo content sets are updated
122- var deprecatedTitle = YamlFrontMatter . Title ;
123- if ( ! string . IsNullOrEmpty ( deprecatedTitle ) )
124- {
125- Collector . EmitWarning ( FilePath , "'title' is no longer supported in yaml frontmatter please use a level 1 header instead." ) ;
126- // TODO remove fallback once migration is over and we fully deprecate front matter titles
127- if ( string . IsNullOrEmpty ( Title ) )
128- Title = deprecatedTitle ;
129- }
129+ YamlFrontMatter = ProcessYamlFrontMatter ( document ) ;
130+ NavigationTitle = YamlFrontMatter . NavigationTitle ;
130131
132+ var subs = GetSubstitutions ( ) ;
131133
132- // set title on yaml front matter manually.
133- // frontmatter gets passed around as page information throughout
134- YamlFrontMatter . Title = Title ;
135-
136- NavigationTitle = YamlFrontMatter . NavigationTitle ;
137- if ( ! string . IsNullOrEmpty ( NavigationTitle ) )
138- {
139- var props = MarkdownParser . Configuration . Substitutions ;
140- var properties = YamlFrontMatter . Properties ;
141- if ( properties is { Count : >= 0 } local )
142- {
143- var allProperties = new Dictionary < string , string > ( local ) ;
144- foreach ( var ( key , value ) in props )
145- allProperties [ key ] = value ;
146- if ( NavigationTitle . AsSpan ( ) . ReplaceSubstitutions ( allProperties , out var replacement ) )
147- NavigationTitle = replacement ;
148- }
149- else
150- {
151- if ( NavigationTitle . AsSpan ( ) . ReplaceSubstitutions ( properties , out var replacement ) )
152- NavigationTitle = replacement ;
153- }
154- }
134+ if ( ! string . IsNullOrEmpty ( NavigationTitle ) )
135+ {
136+ if ( NavigationTitle . AsSpan ( ) . ReplaceSubstitutions ( subs , out var replacement ) )
137+ NavigationTitle = replacement ;
155138 }
156- else
157- YamlFrontMatter = new YamlFrontMatter { Title = Title } ;
158139
159140 if ( string . IsNullOrEmpty ( Title ) )
160141 {
@@ -166,10 +147,12 @@ private void ReadDocumentInstructions(MarkdownDocument document)
166147 . Descendants < HeadingBlock > ( )
167148 . Where ( block => block is { Level : >= 2 } )
168149 . Select ( h => ( h . GetData ( "header" ) as string , h . GetData ( "anchor" ) as string ) )
169- . Select ( h => new PageTocItem
150+ . Select ( h =>
170151 {
171- Heading = h . Item1 ! . StripMarkdown ( ) ,
172- Slug = ( h . Item2 ?? h . Item1 ) . Slugify ( )
152+ var header = h . Item1 ! . StripMarkdown ( ) ;
153+ if ( header . AsSpan ( ) . ReplaceSubstitutions ( subs , out var replacement ) )
154+ header = replacement ;
155+ return new PageTocItem { Heading = header ! , Slug = ( h . Item2 ?? header ) . Slugify ( ) } ;
173156 } )
174157 . ToList ( ) ;
175158
@@ -192,6 +175,29 @@ private void ReadDocumentInstructions(MarkdownDocument document)
192175 _instructionsParsed = true ;
193176 }
194177
178+ private YamlFrontMatter ProcessYamlFrontMatter ( MarkdownDocument document )
179+ {
180+ if ( document . FirstOrDefault ( ) is not YamlFrontMatterBlock yaml )
181+ return new YamlFrontMatter { Title = Title } ;
182+
183+ var raw = string . Join ( Environment . NewLine , yaml . Lines . Lines ) ;
184+ var fm = ReadYamlFrontMatter ( raw ) ;
185+
186+ // TODO remove when migration tool and our demo content sets are updated
187+ var deprecatedTitle = fm . Title ;
188+ if ( ! string . IsNullOrEmpty ( deprecatedTitle ) )
189+ {
190+ Collector . EmitWarning ( FilePath , "'title' is no longer supported in yaml frontmatter please use a level 1 header instead." ) ;
191+ // TODO remove fallback once migration is over and we fully deprecate front matter titles
192+ if ( string . IsNullOrEmpty ( Title ) )
193+ Title = deprecatedTitle ;
194+ }
195+ // set title on yaml front matter manually.
196+ // frontmatter gets passed around as page information throughout
197+ fm . Title = Title ;
198+ return fm ;
199+ }
200+
195201 private YamlFrontMatter ReadYamlFrontMatter ( string raw )
196202 {
197203 try
0 commit comments