Repository: beeware/briefcase

Issue:
Creating a new project using quoted inputs results in an invalid pyproject.toml
### Describe the bug

Several of the user inputs for the `briefcase new` command are inserted verbatim in to the `pyproject.toml`. This TOML document uses double quotes to enclose these strings; therefore, if the user inputs contain double quotes, the TOML will be invalid.

While entering text with double quotes in to the prompts wouldn't normally be expected, at least for some of the fields, such as name (perhaps for a quoted nickname) or the description, this character should be supported.

### Steps to reproduce

1. Run `briefcase new`
2. For the author, enter `Harald "Bluetooth" Gormsson`
3. Run `briefcase dev` in the project

### Expected behavior

`pyproject.toml` is valid.

A similar tactic to https://github.com/beeware/briefcase-template/pull/66 seems reasonable.

### Screenshots

_No response_

### Environment

- Operating System: pop os 22.04
- Python version: 3.10.14
- Software versions:
  - Briefcase: `0.3.18.dev206+g38fbb22b.d20240422`


### Logs

```console
❯ briefcase dev

Briefcase configuration error: Invalid pyproject.toml: Expected newline or end of document after a statement (at line 8, column 19)
```

### Additional context

_No response_

Discussion:

Patch:
diff --git a/changes/1746.bugfix.rst b/changes/1746.bugfix.rst
new file mode 100644
index 00000000..0c9d3a96
--- /dev/null
+++ b/changes/1746.bugfix.rst
@@ -0,0 +1,1 @@
+Escaping of quotation marks in TOML templates was corrected.
diff --git a/changes/1786.doc.rst b/changes/1786.doc.rst
deleted file mode 100644
index dcb6efe9..00000000
--- a/changes/1786.doc.rst
+++ /dev/null
@@ -1,1 +0,0 @@
-Specific examples added for requires under configuration.
diff --git a/docs/reference/configuration.rst b/docs/reference/configuration.rst
index 9cf896f4..f038f238 100644
--- a/docs/reference/configuration.rst
+++ b/docs/reference/configuration.rst
@@ -313,9 +313,6 @@ A hexadecimal RGB color value (e.g., ``#008577``) used alongside the primary
 color. This setting is only used if the platform allows color modification,
 otherwise it is ignored.
 
-
-.. _configuration-requires-key:
-
 ``requires``
 ~~~~~~~~~~~~
 
@@ -327,35 +324,6 @@ application level, *and* platform level, the final set of requirements will be
 the *concatenation* of requirements from all levels, starting from least to
 most specific.
 
-Any PEP 508 version specifier is legal. For example:
-
-* Bare package name::
-
-    requires = ["pillow"]
-
-* Package name with version specifier::
-
-    requires = ["pillow==9.1.0"]
-
-* Install from source using the ``--no-binary`` entry::
-
-    requires = [
-        "pillow==9.1.0",
-        "--no-binary", "pillow",
-    ]
-
-* Git repository::
-
-    requires=["git+https://github.com/beeware/briefcase.git"]
-
-* Local directory::
-
-    requires=["mysrc/myapp"]
-
-* Local wheel file::
-
-    requires=["fullpath/wheelfile.whl"]
-
 ``revision``
 ~~~~~~~~~~~~
 
@@ -434,8 +402,6 @@ level, application level, *and* platform level, the final set of requirements
 will be the *concatenation* of requirements from all levels, starting from least
 to most specific.
 
-See :ref:`requires <configuration-requires-key>` for examples.
-
 ``test_sources``
 ~~~~~~~~~~~~~~~~
 
diff --git a/src/briefcase/integrations/cookiecutter.py b/src/briefcase/integrations/cookiecutter.py
index 25c0e586..3c66ffd0 100644
--- a/src/briefcase/integrations/cookiecutter.py
+++ b/src/briefcase/integrations/cookiecutter.py
@@ -62,7 +62,7 @@ class TOMLEscape(Extension):
 
         def escape_toml(obj):
             """Escapes double quotes and backslashes."""
-            return obj.replace('"', '"').replace("\\", "\\\\")
+            return obj.replace("\\", "\\\\").replace('"', '\\"')
 
         def escape_non_ascii(obj):
             """Quotes obj if non ascii characters are present."""


Test patch:
diff --git a/tests/integrations/cookiecutter/test_TOMLEscape.py b/tests/integrations/cookiecutter/test_TOMLEscape.py
index e80adc33..a3e6d05f 100644
--- a/tests/integrations/cookiecutter/test_TOMLEscape.py
+++ b/tests/integrations/cookiecutter/test_TOMLEscape.py
@@ -10,7 +10,7 @@ from briefcase.integrations.cookiecutter import TOMLEscape
     [
         # Single digit minor
         ("Hello World", "Hello World"),
-        ('Hello " World', 'Hello " World'),
+        ('Hello " World', 'Hello \\" World'),
         ("Hello \\ World", "Hello \\\\ World"),
     ],
 )