13
13
using Markdig ;
14
14
using Markdig . Extensions . Yaml ;
15
15
using Markdig . Syntax ;
16
+ using YamlDotNet . Serialization ;
16
17
17
18
namespace Elastic . Markdown . IO ;
18
19
@@ -106,70 +107,54 @@ public async Task<MarkdownDocument> ParseFullAsync(Cancel ctx)
106
107
return document ;
107
108
}
108
109
109
- private void ReadDocumentInstructions ( MarkdownDocument document )
110
+ private IReadOnlyDictionary < string , string > GetSubstitutions ( )
110
111
{
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
+ }
111
122
123
+ private void ReadDocumentInstructions ( MarkdownDocument document )
124
+ {
112
125
Title = document
113
126
. FirstOrDefault ( block => block is HeadingBlock { Level : 1 } ) ?
114
127
. GetData ( "header" ) as string ;
115
128
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 ;
130
131
132
+ var subs = GetSubstitutions ( ) ;
131
133
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 ;
155
138
}
156
- else
157
- YamlFrontMatter = new YamlFrontMatter { Title = Title } ;
158
139
159
140
if ( string . IsNullOrEmpty ( Title ) )
160
141
{
161
142
Title = RelativePath ;
162
143
Collector . EmitWarning ( FilePath , "Document has no title, using file name as title." ) ;
163
144
}
145
+ else if ( Title . AsSpan ( ) . ReplaceSubstitutions ( subs , out var replacement ) )
146
+ Title = replacement ;
164
147
165
148
var contents = document
166
149
. Descendants < HeadingBlock > ( )
167
150
. Where ( block => block is { Level : >= 2 } )
168
151
. Select ( h => ( h . GetData ( "header" ) as string , h . GetData ( "anchor" ) as string ) )
169
- . Select ( h => new PageTocItem
152
+ . Select ( h =>
170
153
{
171
- Heading = h . Item1 ! . StripMarkdown ( ) ,
172
- Slug = ( h . Item2 ?? h . Item1 ) . Slugify ( )
154
+ var header = h . Item1 ! . StripMarkdown ( ) ;
155
+ if ( header . AsSpan ( ) . ReplaceSubstitutions ( subs , out var replacement ) )
156
+ header = replacement ;
157
+ return new PageTocItem { Heading = header ! , Slug = ( h . Item2 ?? header ) . Slugify ( ) } ;
173
158
} )
174
159
. ToList ( ) ;
175
160
@@ -192,6 +177,29 @@ private void ReadDocumentInstructions(MarkdownDocument document)
192
177
_instructionsParsed = true ;
193
178
}
194
179
180
+ private YamlFrontMatter ProcessYamlFrontMatter ( MarkdownDocument document )
181
+ {
182
+ if ( document . FirstOrDefault ( ) is not YamlFrontMatterBlock yaml )
183
+ return new YamlFrontMatter { Title = Title } ;
184
+
185
+ var raw = string . Join ( Environment . NewLine , yaml . Lines . Lines ) ;
186
+ var fm = ReadYamlFrontMatter ( raw ) ;
187
+
188
+ // TODO remove when migration tool and our demo content sets are updated
189
+ var deprecatedTitle = fm . Title ;
190
+ if ( ! string . IsNullOrEmpty ( deprecatedTitle ) )
191
+ {
192
+ Collector . EmitWarning ( FilePath , "'title' is no longer supported in yaml frontmatter please use a level 1 header instead." ) ;
193
+ // TODO remove fallback once migration is over and we fully deprecate front matter titles
194
+ if ( string . IsNullOrEmpty ( Title ) )
195
+ Title = deprecatedTitle ;
196
+ }
197
+ // set title on yaml front matter manually.
198
+ // frontmatter gets passed around as page information throughout
199
+ fm . Title = Title ;
200
+ return fm ;
201
+ }
202
+
195
203
private YamlFrontMatter ReadYamlFrontMatter ( string raw )
196
204
{
197
205
try
0 commit comments