diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 06fc6e4..94de2dd 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -14,6 +14,10 @@ The format of this *Change Log* is inspired by `keeapachangelog.org`_.
 ---------------
 .. _X.Y.Z: https://github.com/apalala/tatsu/compare/v4.2.6...master
 
+*   `#66`_ Fix multiline (`(?x)`) patterns not properly supported in grammar  (`@pdw-mb`_)
+
+.. _#66: https://github.com/neogeny/TatSu/issues/56
+
 `4.2.6`_ @ 2018-0506
 ---------------------
 .. _4.2.6: https://github.com/apalala/tatsu/compare/v4.2.5...v4.2.6
@@ -298,5 +302,6 @@ Added
 .. _gkimbar: https://bitbucket.org/gkimbar
 .. _nehz: https://bitbucket.org/nehz
 .. _neumond: https://bitbucket.org/neumond
+.. _pdw-mb: https://bitbucket.org/pdw-mb
 .. _pgebhard: https://bitbucket.org/pgebhard
 .. _siemer: https://bitbucket.org/siemer
diff --git a/docs/contributors.rst b/docs/contributors.rst
index cafe69a..5e38e83 100644
--- a/docs/contributors.rst
+++ b/docs/contributors.rst
@@ -40,6 +40,7 @@ features, but reports, bug fixes, or suggestions:
     `gkimbar`_,
     `nehz`_ ,
     `neumond`_,
+    `pdw-mb`_,
     `pgebhard`_,
     `siemer`_
 
@@ -83,5 +84,6 @@ Most of the contributions are recorded as **Grako** commits_ or issues_.
 .. _gkimbar: https://bitbucket.org/gkimbar
 .. _nehz: https://bitbucket.org/nehz
 .. _neumond: https://bitbucket.org/neumond
+.. _pdw-mb: https://bitbucket.org/pdw-mb
 .. _pgebhard: https://bitbucket.org/pgebhard
 .. _siemer: https://bitbucket.org/siemer
diff --git a/tatsu/codegen/python.py b/tatsu/codegen/python.py
index 71d606a..2b06af3 100644
--- a/tatsu/codegen/python.py
+++ b/tatsu/codegen/python.py
@@ -98,7 +98,7 @@ class Constant(Base):
 
 class Pattern(Base):
     def render_fields(self, fields):
-        raw_repr = 'r' + urepr(self.node.pattern).replace("\\\\", '\\')
+        raw_repr = urepr(self.node.pattern)
         fields.update(pattern=raw_repr)
 
     template = 'self._pattern({pattern})'

Generated Python code doesn't cope with multi-line regexs
Consider:

```
myrule = /(?x) 
   foo
   bar
/ $ ;
```
This generates:

```
self._pattern(r'(?x) \n   foo\n   bar\n')
```
Which will look for literal newlines in the string, rather than being ignored.


diff --git a/test/grammar/pattern_test.py b/test/grammar/pattern_test.py
index c2a214a..6dd7c0d 100644
--- a/test/grammar/pattern_test.py
+++ b/test/grammar/pattern_test.py
@@ -3,9 +3,10 @@ from __future__ import absolute_import, division, print_function, unicode_litera
 
 import unittest
 
-from tatsu.util import trim
+from tatsu.util import trim, urepr
 from tatsu.tool import compile
 from tatsu.exceptions import FailedParse
+from tatsu.codegen import codegen
 
 
 class PatternTests(unittest.TestCase):
@@ -103,3 +104,30 @@ class PatternTests(unittest.TestCase):
         model = compile(grammar=grammar)
         ast = model.parse('ABcD xYZ')
         self.assertEqual(['ABcD', 'xYZ'], ast)
+
+    def test_multiline_pattern(self):
+        grammar = r'''
+            start =
+            /(?x)
+            foo
+            bar
+            / $ ;
+        '''
+        model = compile(grammar=trim(grammar))
+        print(codegen(model.rules[0].exp.sequence[0]))
+        self.assertEqual(
+            codegen(model.rules[0].exp.sequence[0]),
+            urepr("self._pattern('(?x)\nfoo\nbar\n')").strip('"\'')
+        )
+
+        grammar = r'''
+            start =
+            /(?x)foo\nbar
+            blort/ $ ;
+        '''
+        model = compile(grammar=trim(grammar))
+        print(codegen(model.rules[0].exp.sequence[0]))
+        self.assertEqual(
+            trim(codegen(model.rules[0].exp.sequence[0])),
+            urepr("self._pattern('(?x)foo\\nbar\nblort')").strip('"\.')
+        )

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-flake8 pytest-mypy pytest-pylint
3.9
requirements-dev.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
astroid==3.3.9
dill==0.3.9
exceptiongroup==1.2.2
filelock==3.18.0
flake8==7.2.0
iniconfig==2.1.0
isort==6.0.1
mccabe==0.7.0
mypy==1.15.0
mypy-extensions==1.0.0
packaging==24.2
platformdirs==4.3.7
pluggy==1.5.0
pycodestyle==2.13.0
pyflakes==3.3.1
pylint==3.3.6
pytest==8.3.5
pytest-flake8==1.3.0
pytest-mypy==1.0.0
pytest-pylint==0.21.0
-e git+https://github.com/neogeny/TatSu.git@677e51bed96fd15ce689b76e6f60f7251975eff2#egg=TatSu
tomli==2.2.1
tomlkit==0.13.2
typing_extensions==4.13.0

name: TatSu
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - astroid==3.3.9
      - dill==0.3.9
      - exceptiongroup==1.2.2
      - filelock==3.18.0
      - flake8==7.2.0
      - iniconfig==2.1.0
      - isort==6.0.1
      - mccabe==0.7.0
      - mypy==1.15.0
      - mypy-extensions==1.0.0
      - packaging==24.2
      - platformdirs==4.3.7
      - pluggy==1.5.0
      - pycodestyle==2.13.0
      - pyflakes==3.3.1
      - pylint==3.3.6
      - pytest==8.3.5
      - pytest-flake8==1.3.0
      - pytest-mypy==1.0.0
      - pytest-pylint==0.21.0
      - tomli==2.2.1
      - tomlkit==0.13.2
      - typing-extensions==4.13.0
prefix: /opt/conda/envs/TatSu

test/grammar/pattern_test.py::PatternTests::test_multiline_pattern
test/grammar/pattern_test.py::PatternTests::test_ignorecase_not_for_pattern test/grammar/pattern_test.py::PatternTests::test_ignorecase_pattern test/grammar/pattern_test.py::PatternTests::test_pattern_concatenation test/grammar/pattern_test.py::PatternTests::test_patterns_with_newlines
CHANGELOG.rst tatsu/codegen/python.py docs/contributors.rst
CHANGELOG.rst tatsu/codegen/python.py docs/contributors.rst