Repository: getnikola/nikola

Issue:
Headings are not rendered correctly from rst
### Environment:
**Python Version:** 3.6.6
**Nikola Version:** 8.0.0b2
**Operating System:** Arch Linux

### Description:
When I start a post with a heading (after all the meta tags), then this heading is ignored.
If I add some text before the heading - one non-whitespace character is enough - the heading is rendered in the output as it should be.




Discussion:
In reSt a single unique heading at the beginning of a document is special and becomes the document title.

If you want to do it anyway, maybe it works if you add  a comment before it.
We ignore that document title in Nikola, unless you explicitly enable that (`USE_REST_DOCINFO_METADATA`).
I can think of a better way to handle this.

Resolving patch:
diff --git a/nikola/plugins/compile/rest/__init__.py b/nikola/plugins/compile/rest/__init__.py
--- a/nikola/plugins/compile/rest/__init__.py
+++ b/nikola/plugins/compile/rest/__init__.py
@@ -75,7 +75,7 @@ def read_metadata(self, post, lang=None):
         null_logger.handlers = [logbook.NullHandler()]
         with io.open(source_path, 'r', encoding='utf-8') as inf:
             data = inf.read()
-            _, _, _, document = rst2html(data, logger=null_logger, source_path=source_path, transforms=self.site.rst_transforms, no_title_transform=False)
+            _, _, _, document = rst2html(data, logger=null_logger, source_path=source_path, transforms=self.site.rst_transforms)
         meta = {}
         if 'title' in document:
             meta['title'] = document['title']
@@ -124,7 +124,8 @@ def compile_string(self, data, source_path=None, is_two_file=True, post=None, la
             # warnings about it from reST.
             'math_output': 'mathjax /assets/js/mathjax.js',
             'template': default_template_path,
-            'language_code': LEGAL_VALUES['DOCUTILS_LOCALES'].get(LocaleBorg().current_lang, 'en')
+            'language_code': LEGAL_VALUES['DOCUTILS_LOCALES'].get(LocaleBorg().current_lang, 'en'),
+            'doctitle_xform': not self.site.config.get('USE_REST_DOCINFO_METADATA'),
         }
 
         from nikola import shortcodes as sc
@@ -132,8 +133,7 @@ def compile_string(self, data, source_path=None, is_two_file=True, post=None, la
         if self.site.config.get('HIDE_REST_DOCINFO', False):
             self.site.rst_transforms.append(RemoveDocinfo)
         output, error_level, deps, _ = rst2html(
-            new_data, settings_overrides=settings_overrides, logger=self.logger, source_path=source_path, l_add_ln=add_ln, transforms=self.site.rst_transforms,
-            no_title_transform=self.site.config.get('NO_DOCUTILS_TITLE_TRANSFORM', False))
+            new_data, settings_overrides=settings_overrides, logger=self.logger, source_path=source_path, l_add_ln=add_ln, transforms=self.site.rst_transforms)
         if not isinstance(output, unicode_str):
             # To prevent some weird bugs here or there.
             # Original issue: empty files.  `output` became a bytestring.
@@ -230,21 +230,18 @@ class NikolaReader(docutils.readers.standalone.Reader):
     def __init__(self, *args, **kwargs):
         """Initialize the reader."""
         self.transforms = kwargs.pop('transforms', [])
-        self.no_title_transform = kwargs.pop('no_title_transform', False)
+        self.logging_settings = kwargs.pop('nikola_logging_settings', {})
         docutils.readers.standalone.Reader.__init__(self, *args, **kwargs)
 
     def get_transforms(self):
         """Get docutils transforms."""
-        transforms = docutils.readers.standalone.Reader(self).get_transforms() + self.transforms
-        if self.no_title_transform:
-            transforms = [t for t in transforms if str(t) != "<class 'docutils.transforms.frontmatter.DocTitle'>"]
-        return transforms
+        return docutils.readers.standalone.Reader(self).get_transforms() + self.transforms
 
     def new_document(self):
         """Create and return a new empty document tree (root node)."""
         document = docutils.utils.new_document(self.source.source_path, self.settings)
         document.reporter.stream = False
-        document.reporter.attach_observer(get_observer(self.l_settings))
+        document.reporter.attach_observer(get_observer(self.logging_settings))
         return document
 
 
@@ -304,8 +301,7 @@ def rst2html(source, source_path=None, source_class=docutils.io.StringInput,
              parser=None, parser_name='restructuredtext', writer=None,
              writer_name='html', settings=None, settings_spec=None,
              settings_overrides=None, config_section=None,
-             enable_exit_status=None, logger=None, l_add_ln=0, transforms=None,
-             no_title_transform=False):
+             enable_exit_status=None, logger=None, l_add_ln=0, transforms=None):
     """Set up & run a ``Publisher``, and return a dictionary of document parts.
 
     Dictionary keys are the names of parts, and values are Unicode strings;
@@ -323,14 +319,16 @@ def rst2html(source, source_path=None, source_class=docutils.io.StringInput,
              reStructuredText syntax errors.
     """
     if reader is None:
-        reader = NikolaReader(transforms=transforms, no_title_transform=no_title_transform)
         # For our custom logging, we have special needs and special settings we
         # specify here.
         # logger    a logger from Nikola
         # source   source filename (docutils gets a string)
         # add_ln   amount of metadata lines (see comment in CompileRest.compile above)
-        reader.l_settings = {'logger': logger, 'source': source_path,
-                             'add_ln': l_add_ln}
+        reader = NikolaReader(transforms=transforms,
+                              nikola_logging_settings={
+                                  'logger': logger, 'source': source_path,
+                                  'add_ln': l_add_ln
+                              })
 
     pub = docutils.core.Publisher(reader, parser, writer, settings=settings,
                                   source_class=source_class,


Test patch: