# -*- coding: utf-8 -*- # # GHC User's Guide documentation build configuration file # # This file is execfile()d with the current directory set to its # containing dir. # import sys import os # Support for :base-ref:, etc. sys.path.insert(0, os.path.abspath('.')) from ghc_config import extlinks, version import ghc_config extensions = ['sphinx.ext.extlinks', 'sphinx.ext.mathjax', # GHC-specific extensions 'flags', 'ghc_packages'] templates_path = ['.templates'] source_suffix = '.rst' source_encoding = 'utf-8-sig' master_doc = 'index' nitpick_ignore = [ ("envvar", "EDITOR"), ("envvar", "HOME"), ("envvar", "LD_LIBRARY_PATH"), ("envvar", "LIBRARY_PATH"), ("envvar", "PATH"), ("envvar", "RPATH"), ("envvar", "RUNPATH"), ("envvar", "TMPDIR"), ("c:type", "bool"), ("extension", "DoAndIfThenElse"), ("extension", "RelaxedPolyRec"), ] rst_prolog = """ .. |llvm-version-min| replace:: {llvm_version_min} .. |llvm-version-max| replace:: {llvm_version_max} """.format(llvm_version_min=ghc_config.llvm_version_min, llvm_version_max=ghc_config.llvm_version_max) # General information about the project. project = u'Glasgow Haskell Compiler' copyright = u'2023, GHC Team' # N.B. version comes from ghc_config release = version # The full version, including alpha/beta/rc tags. # Syntax highlighting highlight_language = 'haskell' pygments_style = 'tango' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['.build'] # -- Options for HTML output --------------------------------------------- # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". html_title = "Glasgow Haskell Compiler %s User's Guide" % release html_short_title = "GHC %s User's Guide" % release html_theme_path = ['.'] html_theme = 'rtd-theme' html_logo = None html_static_path = ['images'] # Convert quotes and dashes to typographically correct entities html_use_smartypants = True html_use_opensearch = 'https://downloads.haskell.org/~ghc/master/users-guide' html_show_copyright = True # See GHC #15006, #19423 mathjax_path = 'https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js?config=TeX-AMS-MML_HTMLorMML ' # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'GHCUsersGuide' # -- Options for LaTeX output --------------------------------------------- latex_elements = { 'inputenc': '', 'utf8extra': '', 'preamble': r''' \usepackage{fontspec} \usepackage{makeidx} \setsansfont{DejaVu Sans} \setromanfont{DejaVu Serif} \setmonofont{DejaVu Sans Mono} \setlength{\tymin}{45pt} % Dynamic section number spacing. Fixes #18554 \renewcommand{\numberline}[1]{#1~} % Avoid a torrent of over-full \hbox warnings \usepackage{microtype} \hbadness=99999 ''', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', 'users_guide.tex', u'GHC User\'s Guide Documentation', u'GHC Team', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. latex_logo = 'images/logo.pdf' # If true, show page references after internal links. latex_show_pagerefs = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('ghc', 'ghc', 'the Glasgow Haskell Compiler', 'The GHC Team', 1) ] # If true, show URL addresses after external links. man_show_urls = True # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'GHCUsersGuide', u'GHC User\'s Guide', u'GHC Team', 'GHCUsersGuide', 'The Glasgow Haskell Compiler.', 'Compilers'), ] from sphinx import addnodes from docutils import nodes # The following functions parse flag declarations, and then have two jobs. First # they modify the docutils node `signode` for the proper display of the # declaration. Second, they return the name used to reference the flag. # (i.e. return "name" implies you reference the flag with :flag:`name`) def parse_ghci_cmd(env, sig, signode): parts = sig.split(';') name = parts[0] args = '' if len(parts) > 1: args = parts[1] # Bold name signode += addnodes.desc_name(name, name) # Smaller args signode += addnodes.desc_addname(args, args) # Reference name return name def parse_pragma(env, sig, signode): # Collect a prefix of alphabetical tokens to use as the pragma name parts = sig.split(' ') idx_parts = [] for part in parts: if all(c.isalpha() or c == "_" for c in part): idx_parts.append(part) else: break idx = '-'.join(idx_parts) name = '{-# ' + sig + ' #-}' signode += addnodes.desc_name(name, name) return idx def parse_flag(env, sig, signode): # Break flag into name and args import re parts = re.split('( |=|\\[)', sig, 1) flag = parts[0] args = '' if len(parts) > 1: args = ''.join(parts[1:]) # Bold printed name signode += addnodes.desc_name(flag, flag) # Smaller arguments signode += addnodes.desc_addname(args, args) # Reference name left unchanged return sig def haddock_role(lib): """ For instance, * reference to module: :base-ref:`Control.Applicative.` * reference to identifier: :base-ref:`Control.Applicative.pure` * reference to type: :base-ref:`Control.Applicative.Applicative` """ def get_relative_uri(topdir, current_doc, module, anchor): lib_version = ghc_config.lib_versions[lib] libs_base_uri = ghc_config.libs_base_uri # We want to find the relative uri to the Haddocks for relative links # from users guide to haddocks. The inputs are: # # - The users guide lives under 'topdir': //docs/users_guide # - The current doc file is 'current_doc': //docs/users_guide/exts/template_haskell.rst # (The html output will be //docs/users_guide/exts/template_haskell.html) # - The haddocks live under 'libs_base_uri' (relative to 'topdir'): ../libraries # for the template_haskell.rst example this will be '..' current_doc_to_topdir = os.path.relpath(topdir, os.path.dirname(current_doc)) relative_path = '%s/%s/%s-%s' % (current_doc_to_topdir, libs_base_uri, lib, lib_version) uri = '%s/%s.html%s' % (relative_path, module, anchor) return uri def role(name, rawtext, text, lineno, inliner, options={}, content=[]): try: parts = text.split('.') module_parts = parts[:-1] thing = parts[-1] if thing != '': # reference to type or identifier tag = 't' if thing[0].isupper() else 'v' anchor = '#%s:%s' % (tag, thing) link_text = text else: # reference to module anchor = '' link_text = '.'.join(module_parts) uri = get_relative_uri( inliner.document.settings.env.srcdir, inliner.document.current_source, '-'.join(module_parts), anchor) node = nodes.reference(link_text, link_text, refuri=uri) return [node], [] except ValueError: msg = inliner.reporter.error('') return role def setup(app): from sphinx.util.docfields import Field, TypedField increase_python_stack() # the :ghci-cmd: directive used in ghci.rst app.add_object_type('ghci-cmd', 'ghci-cmd', parse_node=parse_ghci_cmd, objname='GHCi command', indextemplate='pair: %s; GHCi command') # Haddock references app.add_role('th-ref', haddock_role('template-haskell')) app.add_role('base-ref', haddock_role('base')) app.add_role('cabal-ref', haddock_role('Cabal')) app.add_role('ghc-compact-ref', haddock_role('ghc-compact')) app.add_role('ghc-prim-ref', haddock_role('ghc-prim')) app.add_role('parallel-ref', haddock_role('parallel')) app.add_role('array-ref', haddock_role('array')) app.add_object_type('rts-flag', 'rts-flag', objname='runtime system command-line option', parse_node=parse_flag, indextemplate='pair: %s; RTS option', doc_field_types=[ Field('since', label='Introduced in GHC version', names=['since']) ]) app.add_object_type('event-type', 'event-type', objname='event log event type', indextemplate='pair: %s; eventlog event type', doc_field_types=[ Field('since', label='Introduced in GHC version', names=['since']), Field('tag', label='Event type ID', names=['tag']), Field('length', label='Record length', names=['length']), TypedField('fields', label='Fields', names='field', typenames=('fieldtype', 'type')) ]) app.add_object_type('pragma', 'pragma', objname='Haskell pragma', parse_node=parse_pragma, indextemplate='pair: %s; pragma', doc_field_types=[ Field('since', label='Introduced in GHC version', names=['since']), Field('where', label='Allowed contexts', names=['where']) ]) def increase_python_stack(): # Workaround sphinx-build recursion limit overflow: # pickle.dump(doctree, f, pickle.HIGHEST_PROTOCOL) # RuntimeError: maximum recursion depth exceeded while pickling an object # # Default python allows recursion depth of 1000 calls. sys.setrecursionlimit(10000)