Commit 68162633 authored by Leonid Onokhov's avatar Leonid Onokhov
Browse files

docs: pkg-section is now an object description

Is now rendered as object description, and can have attached meta.

[ci skip]
parent 34e33f20
......@@ -21,20 +21,20 @@ Most directives have at least following optional arguments
Added directives
.. rst:directive:: .. cabal::pkg-section
.. rst:directive:: .. cabal::cfg-section
Marks a package.cabal section, such as library or exectuble.
Describes a package.cabal section, such as library or exectuble.
Needed to disambiguate fields with duplicate names, you can reset
the section to empty with `.. pkg-section:: None`.
All following `pkg-field` directives will add section name
to their fields name for disambiguating duplicates.
TODO: make this an ObjectDescription actually
You can reset the section disambguation with with `.. pkg-section:: None`.
.. rst::role:: pkg-section
References section added by `.. pkg-section`
.. rst:directive:: .. cabal::pkg-fields
.. rst:directive:: .. cabal::pkg-field
Describes a package.cabal field.
......@@ -44,9 +44,15 @@ Added directives
.. rst::role:: pkg-field
References field added by `.. pkg-field`, fields can be disambiguated
with section `:pkg-field:`section:field`.
with section name `:pkg-field:`section:field`.
.. rst:directive:: .. cabal::cfg-field
.. rst:directive:: .. cabal:cfg-section::
Same as `.. cabal::pkg-section` but does not produce any visible output
currently unused.
.. rst:directive:: .. cabal:cfg-field::
Describes a project.cabal field.
......@@ -264,16 +270,7 @@ class CabalSection(Directive):
return [inode, node]
class CabalPackageSection(CabalSection):
"""
Marks section in package.cabal file
"""
indextemplate = '%s; package.cabal section'
section_key = 'cabal:pkg-section'
target_prefix = 'pkg-section-'
class CabalField(ObjectDescription):
class CabalObject(ObjectDescription):
option_spec = {
'noindex' : directives.flag,
'deprecated': parse_deprecated,
......@@ -281,15 +278,11 @@ class CabalField(ObjectDescription):
'synopsis' : lambda x:x
}
doc_field_types = [
Field('default', label='Default value', names=['default'], has_arg=False)
]
# node attribute marking which section field belongs to
section_key = 'cabal:pkg-section'
section_key = ''
# template for index, it is passed a field name as argument
# used by default deg_index_entry method
indextemplate = '%s; package.cabal section'
indextemplate = ''
def get_meta(self, env):
'''
......@@ -338,6 +331,37 @@ class CabalField(ObjectDescription):
return indexentry, targetname
def add_target_and_index(self, name, sig, signode):
'''
As in sphinx.directive.ObjectDescription
By default adds 'pair' index as returned by get_index_entry and
stores object data into domain data store as returned by get_env_data
'''
env = self.state.document.settings.env
indexentry, targetname = self.get_index_entry(self, name)
signode['ids'].append(targetname)
self.state.document.note_explicit_target(signode)
inode = addnodes.index(
entries=[('pair', indexentry, targetname, '', None)])
signode.insert(0, inode)
meta = self.get_meta(env)
#for ref finding
key, store = self.get_env_key(env, name)
env.domaindata['cabal'][store][key] = env.docname, targetname, meta
class CabalPackageSection(CabalObject):
"""
Cabal section in package.cabal file
"""
section_key = 'cabal:pkg-section'
indextemplate = '%s; package.cabal section'
def handle_signature(self, sig, signode):
'''
As in sphinx.directives.ObjectDescription
......@@ -348,13 +372,13 @@ class CabalField(ObjectDescription):
env = self.state.document.settings.env
sig = sig.strip()
parts = sig.split(':',1)
parts = sig.split(' ',1)
name = parts[0]
signode += addnodes.desc_name(name, name)
signode += addnodes.desc_name(': ', ': ')
if len(parts) > 1:
rest = parts[1].strip()
signode += addnodes.desc_name(' ', ' ')
signode += addnodes.desc_addname(rest, rest)
meta = self.get_meta(env)
......@@ -366,29 +390,62 @@ class CabalField(ObjectDescription):
return name
def add_target_and_index(self, name, sig, signode):
def get_env_key(self, env, name):
store = CabalDomain.types[self.objtype]
return name, store
def run(self):
env = self.state.document.settings.env
section = self.arguments[0].strip().split(' ',1)[0]
if section == 'None':
env.ref_context.pop('cabal:pkg-section', None)
return []
env.ref_context['cabal:pkg-section'] = section
return super(CabalPackageSection, self).run()
class CabalField(CabalObject):
'''
Base for fields in *.cabal files
'''
option_spec = {
'noindex' : directives.flag,
'deprecated': parse_deprecated,
'since' : StrictVersion,
'synopsis' : lambda x:x
}
doc_field_types = [
Field('default', label='Default value', names=['default'], has_arg=False)
]
def handle_signature(self, sig, signode):
'''
As in sphinx.directive.ObjectDescription
As in sphinx.directives.ObjectDescription
By default adds 'pair' index as returned by get_index_entry and
stores object data into domain data store as returned by get_env_data
By default make an object description from name and adding
either deprecated or since as annotation.
'''
env = self.state.document.settings.env
indexentry, targetname = self.get_index_entry(self, name)
signode['ids'].append(targetname)
self.state.document.note_explicit_target(signode)
sig = sig.strip()
parts = sig.split(':',1)
name = parts[0]
signode += addnodes.desc_name(name, name)
signode += addnodes.desc_name(': ', ': ')
inode = addnodes.index(
entries=[('pair', indexentry, targetname, '', None)])
signode.insert(0, inode)
if len(parts) > 1:
rest = parts[1].strip()
signode += addnodes.desc_addname(rest, rest)
meta = self.get_meta(env)
#for ref finding
key, store = self.get_env_key(env, name)
env.domaindata['cabal'][store][key] = env.docname, targetname, meta
rendered = render_meta_title(meta)
if rendered != '':
signode += addnodes.desc_addname(' ', ' ')
signode += addnodes.desc_annotation(rendered, rendered)
return name
class CabalPackageField(CabalField):
'''
......@@ -418,6 +475,10 @@ class CabalFieldXRef(XRefRole):
return title, target
#
# Directives for config files.
#
class CabalPackageFieldXRef(CabalFieldXRef):
'''
Role referencing project.cabal section
......@@ -468,6 +529,11 @@ class ConfigField(CabalField):
class CabalConfigFieldXRef(CabalFieldXRef):
section_key = 'cabal:cfg-section'
#
# Cabal domain
#
class ConfigFieldIndex(Index):
name = 'projectindex'
localname = "Cabal reference"
......@@ -525,7 +591,6 @@ class ConfigFieldIndex(Index):
sort by (document, index)
group on (document, doc_section)
in groups sort so sections are first
TODO: Check how to extract section numbers from (document,doc_section)
and add it as annotation to titles
......@@ -646,7 +711,7 @@ def make_title(typ, key, meta):
def make_full_name(typ, key, meta):
'''
Return an ancor name for object type
Return an anchor name for object type
'''
if typ == 'pkg-section':
return 'pkg-section-' + key
......@@ -665,13 +730,18 @@ def make_full_name(typ, key, meta):
raise ValueError('Unknown object type: ' + typ)
class CabalDomain(Domain):
'''
Sphinx domain for cabal
needs Domain.merge_doc for parallel building, just union all dicts
'''
name = 'cabal'
label = 'Cabal'
object_types = {
'pkg-section': ObjType(l_('pkg-section'), 'pkg-section'),
'pkg-field' : ObjType(l_('pkg-field') , 'pkg-field' ),
'cfg-section': ObjType(l_('cfg-section'), 'cfg-section'),
'cfg-field' : ObjType(l_('cfg-field') , 'cfg-field' ),
'cfg-field' : ObjType(l_('cfg-field') , 'cfg-field' ),
}
directives = {
'pkg-section': CabalPackageSection,
......@@ -690,8 +760,8 @@ class CabalDomain(Domain):
'pkg-sections': {},
'pkg-fields' : {},
'cfg-sections': {},
'index-num' : {}, #per document number of object
# used to order references page
'index-num' : {}, #per document number of objects
# used to order references page
'cfg-fields' : {},
'cfg-flags' : {},
}
......@@ -718,8 +788,9 @@ class CabalDomain(Domain):
def resolve_xref(self, env, fromdocname, builder, type, target, node, contnode):
objtypes = self.objtypes_for_role(type)
for typ, key in ((typ, key) for typ in objtypes
for key in make_data_keys(typ, target, node)):
for typ, key in ((typ, key)
for typ in objtypes
for key in make_data_keys(typ, target, node)):
try:
data = env.domaindata['cabal'][self.types[typ]][key]
except KeyError:
......@@ -729,6 +800,9 @@ class CabalDomain(Domain):
return make_refnode(builder, fromdocname, doc, ref, contnode, title)
def get_objects(self):
'''
Used for search functionality
'''
for typ in ['pkg-section', 'pkg-field',
'cfg-section', 'cfg-field', 'cfg-flag']:
key = self.types[typ]
......
......@@ -986,6 +986,11 @@ Library
^^^^^^^
.. pkg-section:: library
:synopsis: Library build information.
Build information for libraries. There can be only one library in a
package, and it's name is the same as package name set by global
:pkg-field:`name` field.
The library section should contain the following fields:
......@@ -1145,12 +1150,13 @@ For example, given the following dependencies specified in
Executables
^^^^^^^^^^^
.. pkg-section:: executable
.. pkg-section:: executable name
:synopsis: Exectuable build info section.
Executable sections (if present) describe executable programs contained
in the package and must have an argument after the section label, which
defines the name of the executable. This is a freeform argument but may
not contain spaces.
Executable sections (if present) describe executable programs contained
in the package and must have an argument after the section label, which
defines the name of the executable. This is a freeform argument but may
not contain spaces.
The executable may be described using the following fields, as well as
build information fields (see the section on `build information`_).
......@@ -1183,14 +1189,15 @@ can pass to ``cabal run``.
Test suites
^^^^^^^^^^^
.. pkg-section:: test
.. pkg-section:: test name
:synopsis: Test suit build information.
Test suite sections (if present) describe package test suites and must
have an argument after the section label, which defines the name of the
test suite. This is a freeform argument, but may not contain spaces. It
should be unique among the names of the package's other test suites, the
package's executables, and the package itself. Using test suite sections
requires at least Cabal version 1.9.2.
Test suite sections (if present) describe package test suites and must
have an argument after the section label, which defines the name of the
test suite. This is a freeform argument, but may not contain spaces. It
should be unique among the names of the package's other test suites, the
package's executables, and the package itself. Using test suite sections
requires at least Cabal version 1.9.2.
The test suite may be described using the following fields, as well as
build information fields (see the section on `build information`_).
......@@ -1209,7 +1216,7 @@ error channels. The ``exitcode-stdio-1.0`` type requires the ``main-is``
field.
.. pkg-field:: main-is: filename
.. :name: test-main-is
:synopsis: Module containing tests main function.
:required: ``exitcode-stdio-1.0``
:disallowed: ``detailed-0.9``
......@@ -1335,15 +1342,17 @@ to ``cabal test``.
Benchmarks
^^^^^^^^^^
.. pkg-section:: benchmark
.. pkg-section:: benchmark name
:since: 1.9.2
:synopsis: Benchmark build information.
Benchmark sections (if present) describe benchmarks contained in the
package and must have an argument after the section label, which defines
the name of the benchmark. This is a freeform argument, but may not
contain spaces. It should be unique among the names of the package's
other benchmarks, the package's test suites, the package's executables,
and the package itself. Using benchmark sections requires at least Cabal
version 1.9.2.
Benchmark sections (if present) describe benchmarks contained in the
package and must have an argument after the section label, which defines
the name of the benchmark. This is a freeform argument, but may not
contain spaces. It should be unique among the names of the package's
other benchmarks, the package's test suites, the package's executables,
and the package itself. Using benchmark sections requires at least Cabal
version 1.9.2.
The benchmark may be described using the following fields, as well as
build information fields (see the section on `build information`_).
......@@ -1843,10 +1852,12 @@ Example: Using explicit braces rather than indentation for layout
Configuration Flags
"""""""""""""""""""
.. pkg-section:: flags
.. pkg-section:: flag name
:synopsis: Flag declaration.
Flag section declares a flag which can be used in `conditional blocks`_.
A flag section takes the flag name as an argument and may contain the
following fields.
A flag section may contain the following fields:
.. pkg-field:: description: freeform
......@@ -1858,13 +1869,15 @@ following fields.
The default value of this flag.
Note that this value may be `overridden in several
ways <installing-packages.html#controlling-flag-assignments>`__. The
rationale for having flags default to True is that users usually
want new features as soon as they are available. Flags representing
features that are not (yet) recommended for most users (such as
experimental features or debugging support) should therefore
explicitly override the default to False.
.. note::
This value may be `overridden in several
ways <installing-packages.html#controlling-flag-assignments>`__. The
rationale for having flags default to True is that users usually
want new features as soon as they are available. Flags representing
features that are not (yet) recommended for most users (such as
experimental features or debugging support) should therefore
explicitly override the default to False.
.. pkg-field:: manual: boolean
......@@ -2176,10 +2189,11 @@ Custom setup scripts
--------------------
.. pkg-section:: custom-setup
:synopsis: Custom Setup.hs build information.
:since: 1.24
The optional :pkg-section:`custom-setup` stanza contains information needed for
the compilation of custom ``Setup.hs`` scripts,
The optional :pkg-section:`custom-setup` stanza contains information needed
for the compilation of custom ``Setup.hs`` scripts,
::
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment