Convert existing '## Sample code' samples to '{@tool sample}...{@end-tool}' form. (#24077)

This converts existing ## Sample code samples to {@tool sample}...{@end-tool} form.

Also:
1. Fixed a minor bug in analyze-sample-code.dart
2. Made the snippet tool only insert descriptions if the description is non-empty.
3. Moved the Card diagram to before the code sample.
diff --git a/dev/snippets/config/skeletons/application.html b/dev/snippets/config/skeletons/application.html
index 347b6e1..afe9c4c 100644
--- a/dev/snippets/config/skeletons/application.html
+++ b/dev/snippets/config/skeletons/application.html
@@ -5,11 +5,7 @@
 </div>
 <div class="snippet-container">
   <div class="snippet" id="shortSnippet">
-    <div class="snippet-description">
-      {@end-inject-html}
-      {{description}}
-      {@inject-html}
-    </div>
+    {{description}}
     <div class="copyable-container">
       <button class="copy-button-overlay copy-button" title="Copy to clipboard"
               onclick="copyTextToClipboard();">
diff --git a/dev/snippets/config/skeletons/sample.html b/dev/snippets/config/skeletons/sample.html
index 15a98ea..fbdc5fe 100644
--- a/dev/snippets/config/skeletons/sample.html
+++ b/dev/snippets/config/skeletons/sample.html
@@ -3,10 +3,7 @@
   <button id="shortSnippetButton" selected>Sample</button>
 </div>
 <div class="snippet-container">
-  <div class="snippet">
-    <div class="snippet-description">{@end-inject-html}
-{{description}}{@inject-html}
-    </div>
+  <div class="snippet">{{description}}
     <div class="copyable-container">
       <button class="copy-button-overlay copy-button" title="Copy to clipboard"
               onclick="copyTextToClipboard(findSiblingWithId(this, 'sample-code'));">
diff --git a/dev/snippets/config/templates/stateless_widget.tmpl b/dev/snippets/config/templates/stateless_widget.tmpl
index 728eb51..93512bb 100644
--- a/dev/snippets/config/templates/stateless_widget.tmpl
+++ b/dev/snippets/config/templates/stateless_widget.tmpl
@@ -25,6 +25,6 @@
 
   @override
   Widget build(BuildContext context) {
-    return {{code}}
+    return {{code}};
   }
 }
diff --git a/dev/snippets/lib/snippets.dart b/dev/snippets/lib/snippets.dart
index 482b3b1..3155ec4 100644
--- a/dev/snippets/lib/snippets.dart
+++ b/dev/snippets/lib/snippets.dart
@@ -113,10 +113,15 @@
     if (result.length > 3) {
       result.removeRange(result.length - 3, result.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.
+    String description = injections.firstWhere((_ComponentTuple tuple) => tuple.name == 'description').mergedContent;
+    description = description.trim().isNotEmpty
+        ? '<div class="snippet-description">{@end-inject-html}$description{@inject-html}</div>'
+        : '';
     final Map<String, String> substitutions = <String, String>{
-      'description': injections
-          .firstWhere((_ComponentTuple tuple) => tuple.name == 'description')
-          .mergedContent,
+      'description': description,
       'code': htmlEscape.convert(result.join('\n')),
       'language': language ?? 'dart',
     }..addAll(type == SnippetType.application
diff --git a/dev/snippets/test/snippets_test.dart b/dev/snippets/test/snippets_test.dart
index f621d6d..c73e38d 100644
--- a/dev/snippets/test/snippets_test.dart
+++ b/dev/snippets/test/snippets_test.dart
@@ -106,7 +106,9 @@
       expect(html, contains('<div>HTML Bits</div>'));
       expect(html, contains('<div>More HTML Bits</div>'));
       expect(html, contains('  print(&#39;The actual \$name.&#39;);'));
-      expect(html, contains('A description of the snippet.\n\nOn several lines.\n'));
+      expect(html, contains('<div class="snippet-description">'
+          '{@end-inject-html}A description of the snippet.\n\n'
+          'On several lines.{@inject-html}</div>\n'));
       expect(html, contains('main() {'));
     });
   });