interpolateSkeleton method
Interpolates the injections
into an HTML skeleton file.
Similar to interpolateTemplate, but we are only looking for code-
components, and we care about the order of the injections.
Takes into account the type
and doesn't substitute in the id and the app
if not a SnippetType.sample
snippet.
Implementation
String interpolateSkeleton(
CodeSample sample,
String skeleton,
) {
final List<String> codeParts = <String>[];
const HtmlEscape htmlEscape = HtmlEscape();
String? language;
for (final TemplateInjection injection in sample.parts) {
if (!injection.name.startsWith('code')) {
continue;
}
codeParts.addAll(injection.stringContents);
if (injection.language.isNotEmpty) {
language = injection.language;
}
codeParts.addAll(<String>['', '// ...', '']);
}
if (codeParts.length > 3) {
codeParts.removeRange(codeParts.length - 3, codeParts.length);
}
// Only insert a div for the description if there actually is some text there.
// This means that the {{description}} marker in the skeleton needs to
// be inside of an {@inject-html} block.
final String description = sample.description.trim().isNotEmpty
? '<div class="snippet-description">{@end-inject-html}${sample.description.trim()}{@inject-html}</div>'
: '';
// DartPad only supports stable or main as valid channels. Use main
// if not on stable so that local runs will work (although they will
// still take their sample code from the master docs server).
final String channel =
sample.metadata['channel'] == 'stable' ? 'stable' : 'main';
final Map<String, String> substitutions = <String, String>{
'description': description,
'code': htmlEscape.convert(codeParts.join('\n')),
'language': language ?? 'dart',
'serial': '',
'id': sample.metadata['id']! as String,
'channel': channel,
'element': sample.metadata['element'] as String? ?? sample.element,
'app': '',
};
if (sample is ApplicationSample) {
substitutions
..['serial'] = sample.metadata['serial']?.toString() ?? '0'
..['app'] = htmlEscape.convert(sample.output);
}
return skeleton.replaceAllMapped(
RegExp('{{(${substitutions.keys.join('|')})}}'), (Match match) {
return substitutions[match[1]]!;
});
}