Repository: prettier/plugin-xml (js)

Issue:
The plugin fails to parse XML with doctype
The XML I have (from the jhipster project defaults)
```
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
        "https://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">

    <!-- Configure checker to use UTF-8 encoding -->
    <property name="charset" value="UTF-8"/>
    <!-- Configure checker to run on files with these extensions -->
    <property name="fileExtensions" value=""/>
    <!-- For detailed checkstyle configuration, see https://github.com/spring-io/nohttp/tree/master/nohttp-checkstyle -->
    <module name="io.spring.nohttp.checkstyle.check.NoHttpCheck">
        <property name="whitelist" value="http://maven.apache.org/POM/4.0.0&#10;
            http://www.w3.org/2001/XMLSchema-instance&#10;http://maven.apache.org/maven-v4_0_0.xsd"/>
    </module>
    <!-- Allow suppression with comments
       // CHECKSTYLE:OFF
       ... ignored content ...
       // CHECKSTYLE:ON
    -->
    <module name="SuppressWithPlainTextCommentFilter"/>
</module>
```

The error I get
```
[error] checkstyle.xml: Error: Error parsing XML
[error]     at Object.parse (/home/user/node_modules/@prettier/plugin-xml/src/parse.js:7:11)
[error]     at Object.parse (/home/user/node_modules/prettier/bin-prettier.js:9743:19)
[error]     at coreFormat (/home/user/node_modules/prettier/bin-prettier.js:13258:23)
[error]     at format (/home/user/node_modules/prettier/bin-prettier.js:13516:73)
[error]     at formatWithCursor (/home/user/node_modules/prettier/bin-prettier.js:13532:12)
[error]     at Object.formatWithCursor (/home/user/node_modules/prettier/bin-prettier.js:44213:15)
[error]     at format$1 (/home/user/node_modules/prettier/bin-prettier.js:45598:19)
[error]     at /home/user/node_modules/prettier/bin-prettier.js:45792:16
[error]     at /home/user/node_modules/prettier/bin-prettier.js:45731:14
[error]     at Array.forEach (<anonymous>)
```


NPM modules I have
```
"prettier": "1.19.1",
"@prettier/plugin-xml": "^0.4.0",
```

If I remove the doctype then it works correctly. Not sure if it is related to https://github.com/prettier/plugin-xml/issues/5

Pull request description:
Support DOCTYPE nodes
Fixes #42 

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0b040b9..5123247 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
 
 ## [Unreleased]
 
+### Added
+
+- Support for DOCTYPE nodes.
+
 ## [0.4.0] - 2020-01-19
 
 ### Added
diff --git a/src/print.js b/src/print.js
index 5134933..34f62ab 100644
--- a/src/print.js
+++ b/src/print.js
@@ -80,10 +80,27 @@ const nodes = {
 
     return group(concat(parts));
   },
+  docTypeDecl: (path, opts, print) => {
+    const { DocType, Name, externalID, CLOSE } = path.getValue().children;
+    const parts = [DocType[0].image, " ", Name[0].image];
+
+    if (externalID) {
+      parts.push(" ", path.call(print, "children", "externalID", 0));
+    }
+
+    return group(concat(parts.concat(CLOSE[0].image)));
+  },
   document: (path, opts, print) => {
-    const { element, misc, prolog } = path.getValue().children;
+    const { docTypeDecl, element, misc, prolog } = path.getValue().children;
     let parts = [];
 
+    if (docTypeDecl) {
+      parts.push({
+        offset: docTypeDecl[0].location.startOffset,
+        printed: path.call(print, "children", "docTypeDecl", 0)
+      });
+    }
+
     if (prolog) {
       parts.push({
         offset: prolog[0].location.startOffset,
@@ -98,9 +115,7 @@ const nodes = {
             offset: node.location.startOffset,
             printed: node.children.PROCESSING_INSTRUCTION[0].image
           });
-        }
-
-        if (node.children.Comment) {
+        } else if (node.children.Comment) {
           parts.push({
             offset: node.location.startOffset,
             printed: node.children.Comment[0].image
@@ -162,6 +177,35 @@ const nodes = {
       ])
     );
   },
+  externalID: (path, _opts, _print) => {
+    const {
+      Public,
+      PubIDLiteral,
+      System,
+      SystemLiteral
+    } = path.getValue().children;
+
+    if (System) {
+      return group(
+        concat([
+          System[0].image,
+          indent(concat([line, SystemLiteral[0].image]))
+        ])
+      );
+    }
+
+    return group(
+      concat([
+        group(
+          concat([
+            Public[0].image,
+            indent(concat([line, PubIDLiteral[0].image]))
+          ])
+        ),
+        indent(concat([line, SystemLiteral[0].image]))
+      ])
+    );
+  },
   prolog: (path, opts, print) => {
     const { XMLDeclOpen, attribute, SPECIAL_CLOSE } = path.getValue().children;
     const parts = [XMLDeclOpen[0].image];


Test patch:
diff --git a/test/__snapshots__/format.test.js.snap b/test/__snapshots__/format.test.js.snap
index 19b2c4e..f564f01 100644
--- a/test/__snapshots__/format.test.js.snap
+++ b/test/__snapshots__/format.test.js.snap
@@ -2,6 +2,8 @@
 
 exports[`fixture 1`] = `
 "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\" ?>
+<!DOCTYPE module PUBLIC \\"-//Puppy Crawl//DTD Check Configuration 1.3//EN\\"
+  \\"https://www.puppycrawl.com/dtds/configuration_1_3.dtd\\">
 <?xml-model href=\\"project.rnc\\" type=\\"application/relax-ng-compact-syntax\\"?>
 <!-- foo -->
 <svg
diff --git a/test/fixture.xml b/test/fixture.xml
index 3b18323..69dba7f 100644
--- a/test/fixture.xml
+++ b/test/fixture.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
+        "https://www.puppycrawl.com/dtds/configuration_1_3.dtd">
 <?xml-model href="project.rnc" type="application/relax-ng-compact-syntax"?>
 <!-- foo -->
 <svg