'Parse a file and add/update inventory entries for the doctree.'

def read_doc(self, docname, app=None):

    self.temp_data['docname'] = docname
    self.temp_data['default_domain'] = self.domains.get(self.config.primary_domain)
    self.settings['input_encoding'] = self.config.source_encoding
    self.settings['trim_footnote_reference_space'] = self.config.trim_footnote_reference_space
    self.settings['gettext_compact'] = self.config.gettext_compact
    language = (self.config.language or 'en')
    self.settings['language_code'] = language
    self.settings['smart_quotes'] = True
    for tag in normalize_language_tag(language):
        if (tag in smartchars.quotes):
            break
    else:
        self.settings['smart_quotes'] = False
    docutilsconf = path.join(self.srcdir, 'docutils.conf')
    OptionParser.standard_config_files[1] = docutilsconf
    if path.isfile(docutilsconf):
        self.note_dependency(docutilsconf)
    with sphinx_domains(self):
        if self.config.default_role:
            (role_fn, messages) = roles.role(self.config.default_role, english, 0, dummy_reporter)
            if role_fn:
                roles._roles[''] = role_fn
            else:
                logger.warning('default    role    %s    not    found', self.config.default_role, location=docname)
        codecs.register_error('sphinx', self.warn_and_replace)
        reader = SphinxStandaloneReader(self.app, parsers=self.app.registry.get_source_parsers())
        pub = Publisher(reader=reader, writer=SphinxDummyWriter(), destination_class=NullOutput)
        pub.set_components(None, 'restructuredtext', None)
        pub.process_programmatic_settings(None, self.settings, None)
        src_path = self.doc2path(docname)
        source = SphinxFileInput(app, self, source=None, source_path=src_path, encoding=self.config.source_encoding)
        pub.source = source
        pub.settings._source = src_path
        pub.set_destination(None, None)
        pub.publish()
        doctree = pub.document
    for domain in itervalues(self.domains):
        domain.process_doc(self, docname, doctree)
    if app:
        app.emit('doctree-read', doctree)
    self.all_docs[docname] = max(time.time(), path.getmtime(self.doc2path(docname)))
    if self.versioning_condition:
        old_doctree = None
        if self.versioning_compare:
            try:
                with open(self.doc2path(docname, self.doctreedir, '.doctree'), 'rb') as f:
                    old_doctree = pickle.load(f)
            except EnvironmentError:
                pass
        if ((not self.versioning_compare) or (old_doctree is None)):
            list(add_uids(doctree, self.versioning_condition))
        else:
            list(merge_doctrees(old_doctree, doctree, self.versioning_condition))
    doctree.reporter = None
    doctree.transformer = None
    doctree.settings.warning_stream = None
    doctree.settings.env = None
    doctree.settings.record_dependencies = None
    self.temp_data.clear()
    self.ref_context.clear()
    roles._roles.pop('', None)
    doctree_filename = self.doc2path(docname, self.doctreedir, '.doctree')
    ensuredir(path.dirname(doctree_filename))
    with open(doctree_filename, 'wb') as f:
        pickle.dump(doctree, f, pickle.HIGHEST_PROTOCOL)
