Dartdoc snippet extension to inject full featured code snippets in to API docs. (#23281)

This creates a custom dartdoc tool that will generate snippet blocks in our API docs that allow the user to copy easily to the clipboard, and will also embed the snippet code into a template to show it in a larger context with an app.

This PR adds the snippet tool, a template, and a couple of HTML skeleton files, one for snippets that are designed to be in an application setting, and one where it simply puts a nice container around existing snippets, making them easier to copy to the clipboard.
diff --git a/dev/snippets/config/skeletons/application.html b/dev/snippets/config/skeletons/application.html
new file mode 100644
index 0000000..bbbed4f
--- /dev/null
+++ b/dev/snippets/config/skeletons/application.html
@@ -0,0 +1,34 @@
+{@inject-html}
+<div class="snippet-buttons">
+  <button id="shortSnippetButton" onclick="showSnippet(shortSnippet);" selected>Sample</button>
+  <button id="longSnippetButton" onclick="showSnippet(longSnippet);">Sample in an App</button>
+</div>
+<div class="snippet-container">
+  <div class="snippet" id="shortSnippet">
+    <div class="snippet-description">
+      {@end-inject-html}
+      {{description}}
+      {@inject-html}
+    </div>
+    <div class="copyable-container">
+      <button class="copy-button-overlay copy-button" title="Copy to clipboard"
+              onclick="copyTextToClipboard();">
+        <i class="material-icons copy-image">assignment</i>
+      </button>
+      <pre class="language-dart"><code class="language-dart">{{code}}</code></pre>
+    </div>
+  </div>
+  <div class="snippet" id="longSnippet" hidden>
+    <div class="snippet-description">To create a sample project with this code snippet, run:<br/>
+      <span class="snippet-create-command">flutter create --snippet={{id}} mysample</span>
+    </div>
+    <div class="copyable-container">
+      <button class="copy-button-overlay copy-button" title="Copy to clipboard"
+              onclick="copyTextToClipboard();">
+        <i class="material-icons copy-image">assignment</i>
+      </button>
+      <pre class="language-dart"><code class="language-dart">{{app}}</code></pre>
+    </div>
+  </div>
+</div>
+{@end-inject-html}
diff --git a/dev/snippets/config/skeletons/sample.html b/dev/snippets/config/skeletons/sample.html
new file mode 100644
index 0000000..9343a01
--- /dev/null
+++ b/dev/snippets/config/skeletons/sample.html
@@ -0,0 +1,20 @@
+{@inject-html}
+<div class="snippet-container">
+  <div class="snippet">
+    <div class="snippet-description">
+      {@end-inject-html}
+      {{description}}
+      {@inject-html}
+    </div>
+    <div class="copyable-container">
+      <button class="copy-button-overlay copy-button" title="Copy to clipboard"
+              onclick="copyTextToClipboard(findSiblingWithId(this, 'sample-code'));">
+        <i class="material-icons copy-image">assignment</i>
+      </button>
+      <pre class="language-dart" id="sample-code">
+        <code class="language-dart">{{code}}</code>
+      </pre>
+    </div>
+  </div>
+</div>
+{@end-inject-html}
diff --git a/dev/snippets/config/templates/README.md b/dev/snippets/config/templates/README.md
new file mode 100644
index 0000000..e5addd0
--- /dev/null
+++ b/dev/snippets/config/templates/README.md
@@ -0,0 +1,56 @@
+## Creating Code Snippets
+
+In general, creating application snippets can be accomplished with the following
+syntax inside of the dartdoc comment for a Flutter class/variable/enum/etc.:
+
+```dart
+/// {@tool snippet --template=stateful_widget}
+/// Any text outside of the code blocks will be accumulated and placed at the
+/// top of the snippet box as a description. Don't try and say "see the code
+/// above" or "see the code below", since the location of the description may
+/// change in the future. You can use dartdoc [Linking] in the description, and
+/// __Markdown__ too.
+/// ```dart preamble
+/// class Foo extends StatelessWidget {
+///   const Foo({this.value = ''});
+/// 
+///   String value; 
+/// 
+///   @override
+///   Widget build(BuildContext context) {
+///     return Text(value);
+///   }
+/// }
+/// ```
+/// This will get tacked on to the end of the description above, and shown above
+/// the snippet.  These two code blocks will be separated by `///...` in the
+/// short version of the snippet code sample.
+/// ```dart
+/// String myValue = 'Foo';
+/// 
+/// @override
+/// Widget build(BuildContext) {
+///   return const Foo(myValue);
+/// }
+/// ```
+/// {@end-tool}
+```
+
+This will result in the template having the section that's inside "```dart"
+interpolated into the template's stateful widget's state object body.
+
+All code within a code block in a snippet needs to be able to be run through
+dartfmt without errors, so it needs to be valid code (This shouldn't be an
+additional burden, since all code will also be compiled to be sure it compiles).
+
+## Available Templates
+
+The templates available for using as an argument to the snippets tool are as
+follows:
+
+- __`stateful_widget`__ : Takes a `preamble` in addition to the default code
+  block, which will be placed at the top level of the Dart file, so bare
+  function calls are not allowed in the preamble.  The default code block is
+  placed as the body of a stateful widget, so you will need to implement the
+  build() function, and any state variables.
+  
diff --git a/dev/snippets/config/templates/stateful_widget.tmpl b/dev/snippets/config/templates/stateful_widget.tmpl
new file mode 100644
index 0000000..aff8fbf
--- /dev/null
+++ b/dev/snippets/config/templates/stateful_widget.tmpl
@@ -0,0 +1,32 @@
+{{description}}
+
+import 'package:flutter/material.dart';
+
+void main() => runApp(new MyApp());
+
+class MyApp extends StatelessWidget {
+  // This widget is the root of your application.
+  @override
+  Widget build(BuildContext context) {
+    return new MaterialApp(
+      title: 'Flutter Code Sample for {{id}}',
+      theme: new ThemeData(
+        primarySwatch: Colors.blue,
+      ),
+      home: new MyHomePage(title: '{{id}} Sample'),
+    );
+  }
+}
+
+{{code-preamble}}
+
+class MyHomePage extends StatelessWidget {
+  MyHomePage({Key key}) : super(key: key);
+
+  @override
+  _MyHomePageState createState() => new _MyHomePageState();
+}
+
+class _MyHomePageState extends State<MyHomePage> {
+  {{code}}
+}