aiida_vasp.parsers.content_parsers package¶
Submodules¶
Base classes for the VASP content parsers.
- class aiida_vasp.parsers.content_parsers.base.BaseFileParser(*, handler=None, data=None, settings=None, options=None)[source]¶
Bases:
object
Base class for all the content parsers which parse (read and write) VASP files.
The actually read, interpret and write to/from files is handled by parsevasp and this interface ensures that the parsing framework in AiiDA and preparation before submission is successful. The specific content parser interfaces are always childs of this class.
We assume that there are two main paths when parsing of VASP files takes place. One is when a file is present and we want to interpret it and convert its content into one of the usable data structures in AiiDA. The second is when we already have an AiiDA data structure and want to write a file based on its content. In the former case we basically read from a file, while in the latter we write to a file.
The first approach is enabled if we initialize the parser with the argument
handler
. This should be a file like handler, i.e. from a context manager telling where the content can be located. The respective quantities can then be fetched using theget_quantity
function of the instance with the key representing the quantity. The content of the handler is parsed after initialization. The valid keys representing fetchable quantities is defined for each content parser class using the ~`PARSABLE_QUANTITIES~` class parameter.The second approach is enabled if we initialize with an argument
data
. This should be a valid AiiDA data structure node. Using theget_quantity('somekey')
function of the instance return the same AiiDA data structure node back as was supplied todata
.One can write the parsed content or the content of the StructureData using the function
write
of the class instance.Parameters¶
- handlerobject, optional
A file like object, for instance a file handler representing the file or object containing content to be parsed. Typically used when parsing completed calculations and is also the parameter used during initialization of the content parser, when the
parse
function of this AiiDA plugin is executed.- dataobject. optional
An AiiDA data structure node. Typically used when one later want to write VASP input files.
- settingsdict, optional
Parser settings. Used to set parser settings, e.g. which quantities to compose into nodes etc.
- optionsdict, optional
Parser options. Used to set extra options to the content parsers. For instance for the
POSCAR
/CONTAR
parser one setoptions.positions_dof
to supply selective tags to enable proper construction of selective dynamicsPOSCAR
/CONTCAR
from aStructureData
. TheStructureData
does not contain this type of possibilities.
- DEFAULT_SETTINGS = {'quantities_to_parse': []}¶
- OPEN_MODE = 'r'¶
- PARSABLE_QUANTITIES = {}¶
- get_quantity(quantity_key)[source]¶
Fetch the required quantity from the content parser.
Either fetch it from an existing AiiDA data structure, a parsed content dictionary if that exists, otherwise parse this specific quantity using the loaded instance, which is now a specific content parser.
Parameters¶
- quantity_keystr
A string specifying the key of the quantity to be fetched.
Returns¶
- resultobject
If we have initialized the content parser with an AiiDA data structure, we return it in its original form. If the
quantity_key
is not find to be parsable by this content parser None is returned. Finally, if the content parser was initialized with a file like object and the requestedquantity_key
is found to be parsable we return the quantity.
- property parsable_quantities¶
Fetch the quantities that this content parser can provide.
The CHGCAR
parser interface.
- class aiida_vasp.parsers.content_parsers.chgcar.ChgcarParser(*, handler=None, data=None, settings=None, options=None)[source]¶
Bases:
BaseFileParser
The parser interface that enables parsing of
CHGCAR
content.The parser is triggered by using the
charge_density
and/ormagnetization_density
quantity key.- DEFAULT_SETTINGS = {'quantities_to_parse': ['charge_density']}¶
- PARSABLE_QUANTITIES = {'charge_density': {'inputs': [], 'name': 'charge_density', 'prerequisites': []}, 'magnetization_density': {'inputs': [], 'name': 'magnetization_density', 'prerequisites': []}}¶
- property charge_density¶
Return the charge density.
Returns¶
- charge_densityndarray
A NumPy array containing the charge density in the unit cell in C order.
- property magnetization_density¶
Return the magnetization density.
Returns¶
- magnetization_densitydict or ndarray
If collinear spin calculations have been performed, a NumPy array containing the magnetization density in the unit cell in C order is returned. If however a non-collinear spin calculation have been performed, a dictionary is returned with keys x, y and z, each containing the same NumPy array, but for each direction.
The DOSCAR
parser interface.
- class aiida_vasp.parsers.content_parsers.doscar.DoscarParser(*, handler=None, data=None, settings=None, options=None)[source]¶
Bases:
BaseFileParser
The parser interface that enables parsing of
DOSCAR
content.The parser is triggered by using the
doscar-dos
quantity key. The quantity keydos
will on the other hand parse the structure using the XML parser.- DEFAULT_SETTINGS = {'quantities_to_parse': ['doscar-dos']}¶
- PARSABLE_QUANTITIES = {'doscar-dos': {'inputs': [], 'name': 'dos', 'prerequisites': []}}¶
The EIGENVAL
parser interface.
- class aiida_vasp.parsers.content_parsers.eigenval.EigenvalParser(*, handler=None, data=None, settings=None, options=None)[source]¶
Bases:
BaseFileParser
The parser interface that enables parsing of
EIGENVAL
content.The parser is triggered by using the
eigenval-eigenvalues
and/oreigenval-kpoints
quantity key. The quantity keyseigenvalues
andkpoints
will on the other hand parse the eigenvalues and/or kpoints using the XML parser.- DEFAULT_SETTINGS = {'quantities_to_parse': ['eigenval-eigenvalues', 'eigenval-kpoints']}¶
- PARSABLE_QUANTITIES = {'eigenval-eigenvalues': {'inputs': [], 'name': 'eigenvalues', 'prerequisites': []}, 'eigenval-kpoints': {'inputs': ['structure'], 'name': 'kpoints', 'prerequisites': ['structure']}}¶
The INCAR
parser interface.
- class aiida_vasp.parsers.content_parsers.incar.IncarParser(*args, validate_tags=True, **kwargs)[source]¶
Bases:
BaseFileParser
The parser interface that enables parsing of
INCAR
content.The parser is triggered by using the
incar
quantity key.- DEFAULT_SETTINGS = {'quantities_to_parse': ['incar']}¶
- PARSABLE_QUANTITIES = {'incar': {'inputs': [], 'name': 'incar', 'prerequisites': []}}¶
The KPOINTS
parser interface.
- class aiida_vasp.parsers.content_parsers.kpoints.KpointsParser(*, handler=None, data=None, settings=None, options=None)[source]¶
Bases:
BaseFileParser
The parser interface that enables parsing of
KPOINTS
content.The parser is triggered by using the
kpoints-kpoints
quantity key. The quantity keykpoints
will on the other hand parse the k-points using the XML parser.- DEFAULT_SETTINGS = {'quantities_to_parse': ['kpoints-kpoints']}¶
- PARSABLE_QUANTITIES = {'kpoints-kpoints': {'inputs': [], 'name': 'kpoints', 'prerequisites': []}}¶
- property kpoints¶
Return kpoints that is ready to be consumed by the the AiiDA
KpointsData
.AiiDA does not support the line mode used in VASP, so we give a warning that parsing this is not supported.
Returns¶
- aiida_kpointsdict
A dict that contain keys
comment
,divisions
,shifts
,points
,tetra
,tetra_volume
,mode
centering
,num_kpoints
,weights
andcartesian
which are compatible with consumption of the initialization of the AiiDA KpointsData.
- aiida_vasp.parsers.content_parsers.kpoints.parsevasp_to_aiida(kpoints, logger)[source]¶
parsevasp
to AiiDA conversion.Generate an AiiDA data structure that can be consumed by
KpointsData
on initialization from theparsevasp
instance of theKpoints
class.Parameters¶
- kpointsobject
An instance of the
Kpoints
class inparsevasp
.
Returns¶
- kpoints_dictdict
A dictionary representation which are ready to be used when creating an AiiDA
KpointsData
instance.
The OUTCAR
parser interface.
- class aiida_vasp.parsers.content_parsers.outcar.OutcarParser(*, handler=None, data=None, settings=None, options=None)[source]¶
Bases:
BaseFileParser
The parser interface that enables parsing of
OUTCAR
content.The parser is triggered by using the
elastic_moduli
,magnetization
orsite-magnetization
run_stats
orrun_status
quantity keys.- DEFAULT_SETTINGS = {'quantities_to_parse': ['run_status', 'run_stats']}¶
- PARSABLE_QUANTITIES = {'elastic_moduli': {'inputs': [], 'name': 'elastic_moduli', 'prerequisites': []}, 'magnetization': {'inputs': [], 'name': 'magnetization', 'prerequisites': []}, 'run_stats': {'inputs': [], 'name': 'run_stats', 'prerequisites': []}, 'run_status': {'inputs': [], 'name': 'run_status', 'prerequisites': []}, 'site_magnetization': {'inputs': [], 'name': 'site_magnetization', 'prerequisites': []}, 'symmetries': {'inputs': [], 'name': 'symmetries', 'prerequisites': []}}¶
- property elastic_moduli¶
Fetch the elastic moduli tensor.
Returns¶
- modulidict
A dictionary containing ndarrays with the rigid ion elastic moduli, both symmetrized and non-symmetrized for the keys
symmetrized
andnon_symmetrized
respectively. The keytotal
contain both the rigid ion and the ionic contributions to the elastic tensor for the symmetrized case.
- property magnetization¶
Fetch the full cell magnetization.
Returns¶
- magnetizationlist
A list containing an entry that is the total magnetization in the cell in unit of Bohr magneton. The magnetization returned is the one associated with the electrons for the last electronic step.
- property run_stats¶
Fetch the run statistics, which included timings and memory consumption.
Returns¶
- statsdict
A dictionary containing timing and memory consumption information that are parsed from the end of the
OUTCAR
file. The key names are mostly preserved, except for the memory which is prefixed withmem_usage_
. Units are preserved fromOUTCAR
and there are some differences between VASP 5 and 6.
- property run_status¶
Fetch status of calculations.
Returns¶
- statusdict
A dictionary containing the keys
finished
, which is True if the VASP calculation contain timing information in the end of theOUTCAR
. The keyionic_converged
is True if the number of ionic steps detected is smaller than the supplied NSW. The keyelectronic_converged
is True if the number of electronic steps is smaller than NELM (defaults to 60 in VASP). It is also possible to check if all the ionic steps did reached NELM and thus did not converged if the keyconsistent_nelm_breach
isTrue
, whilecontains_nelm_breach
is True if one or more ionic steps reached NELM and thus did not converge electronically.
- property site_magnetization¶
Fetch the site dependent magnetization.
Returns¶
- magnetizationdict
A dictionary containing the key
sphere
which contains the integrated magnetization in units of Bohr magneton. Additional keys undersphere
are given for each direction and for non-collinear calculations all of them are used. Thesite_moment
yields the magnetization per site, with a key describing the site number and then thes
,p
,d
etc. the projections of the site magnetization andtot
containing the total magnetization for that site. Thetotal_magnetization
gives the sum of each magnetization projection and magnetization total for each site. Thefull_cell
key yields the magnetization from the electronic part of the last electronic step in a list.
- property symmetries¶
Fetch some basic symmetry data.
Returns¶
- symdict
A dictionary containing the number of space group operations in the key
num_space_group_operations
and the detected supplied cell inoriginal_cell_type
. Insymmetrized_cell_type
the cell on which VASP performs the calculation has been included. Each value in the dictionary is a list, where each entry represent one ionic step.
- class aiida_vasp.parsers.content_parsers.outcar.VtstNebOutcarParser(*args, **kwargs)[source]¶
Bases:
OutcarParser
Parser for processing OUTCAR generated by VASP with VTST
- DEFAULT_SETTINGS = {'quantities_to_parse': ['run_status', 'run_stats', 'neb_data']}¶
- PARSABLE_QUANTITIES = {'elastic_moduli': {'inputs': [], 'name': 'elastic_moduli', 'prerequisites': []}, 'magnetization': {'inputs': [], 'name': 'magnetization', 'prerequisites': []}, 'neb_data': {'inputs': [], 'name': 'neb_data', 'prerequisites': []}, 'outcar-cell': {'inputs': [], 'name': 'cell', 'prerequisites': []}, 'outcar-forces': {'inputs': [], 'name': 'forces', 'prerequisites': []}, 'outcar-positions': {'inputs': [], 'name': 'positions', 'prerequisites': []}, 'run_stats': {'inputs': [], 'name': 'run_stats', 'prerequisites': []}, 'run_status': {'inputs': [], 'name': 'run_status', 'prerequisites': []}, 'site_magnetization': {'inputs': [], 'name': 'site_magnetization', 'prerequisites': []}, 'symmetries': {'inputs': [], 'name': 'symmetries', 'prerequisites': []}}¶
- property cell¶
Parsed cell vectors
- property forces¶
Parsed forces
- property neb_data¶
Parsed NEB results
- property positions¶
Parsed forces
The POSCAR
/CONTCAR
parser interface.
- class aiida_vasp.parsers.content_parsers.poscar.PoscarParser(*, precision=12, **kwargs)[source]¶
Bases:
BaseFileParser
The parser interface that enables parsing of
POSCAR
/CONTCAR
content.The parser is triggered by using the
poscar-structure
quantity key. The quantity keystructure
will on the other hand parse the structure using the XML parser.Parameters¶
- precisionint, optional
An integer specifying the number of digits for floating point numbers that will be written to
POSCAR
/CONTCAR
. Defaults to 12.
- DEFAULT_SETTINGS = {'quantities_to_parse': ['poscar-structure']}¶
- PARSABLE_QUANTITIES = {'poscar-structure': {'inputs': [], 'name': 'structure', 'prerequisites': []}}¶
- aiida_vasp.parsers.content_parsers.poscar.fetch_symbols_from_elements(elmnts)[source]¶
Fetch the symbol entry in the elements dictionary in Aiida.
- aiida_vasp.parsers.content_parsers.poscar.parsevasp_to_aiida(poscar)[source]¶
parsevasp
to AiiDA conversion.Generate an AiiDA structure that can be consumed by
StructureData
on initialization from theparsevasp
instance of thePoscar
class.Parameters¶
- poscarobject
An instance of the
Poscar
class inparsevasp
.
Returns¶
- poscar_dictdict
A dictionary representation which are ready to be used when creating an AiiDA
StructureData
instance.
POTCAR parser.
- class aiida_vasp.parsers.content_parsers.potcar.MultiPotcarIo(potcars=None)[source]¶
Bases:
object
Handle file i/o for POTCAR files with one or more potentials.
- classmethod count_kinds(structure)[source]¶
Count consecutive kinds that compose the different sites.
- Returns:
[(kind_name, num), … ]
- property element_symbols¶
- classmethod from_structure(structure, potentials_dict)[source]¶
Create a MultiPotcarIo from an AiiDA StructureData object and a dictionary with a potential for each kind in the structure.
- get_potentials_dict(structure)[source]¶
Get a dictionary {kind_name: PotcarData} that would fit the structure.
If the PotcarData contained in MultiPotcarIo do not match the structure, an exception is raised.
- property potcars¶
- class aiida_vasp.parsers.content_parsers.potcar.PotcarIo(**kwargs)[source]¶
Bases:
object
Deals with VASP input output of POTCAR files.
Instanciate with one of the following kwargs:
- Parameters:
path – (string) absolute path to the POTCAR file
potcar_node – a PotcarData node
potcar_file_node – a PotcarFileNode
contents – a string with the POTCAR content
- property content¶
- property file_node¶
- classmethod from_(potcar)[source]¶
Determine the best guess at how the input represents a POTCAR file and construct a PotcarIo instance based on that.
- property node¶
- class aiida_vasp.parsers.content_parsers.potcar.PotcarParser(*, handler=None, data=None, settings=None, options=None)[source]¶
Bases:
BaseFileParser
A lightweight interface that provides access to POTCAR metadata parsing.
Similar to the other content parser for VASP in structure, but only used directly in the POTCAR handling logic.
- DEFAULT_SETTINGS = {}¶
- PARSABLE_QUANTITIES = {}¶
- property metadata¶
Return the metadata Potcar instance.
The standard stream parser interface for VASP.
- class aiida_vasp.parsers.content_parsers.stream.StreamParser(*, handler=None, data=None, settings=None, options=None)[source]¶
Bases:
BaseFileParser
Parser used for parsing errors and warnings from VASP.
- DEFAULT_SETTINGS = {'quantities_to_parse': ['notifications']}¶
- PARSABLE_QUANTITIES = {'notifications': {'inputs': [], 'name': 'notifications', 'prerequisites': []}}¶
- property errors¶
Fetch the errors that VASP generated.
Returns¶
- errorslist
A list of all errors from VASP. Each entry is a dict with the keys
name
,kind
,message
andregex
containing name of the message, what kind it is (ERROR
orWARNING
), a description of the error and the regular expression detected as string values.
- property has_entries¶
Check if there are notifications from VASP present according to the config after parsning.
Returns¶
- entriesbool
True
if notifications was detected,False
otherwise.
- property notifications¶
Fetch the notifications that VASP generated.
Returns¶
- notificationslist
A list of all notifications from VASP. Each entry is a dict with the keys
name
,kind
,message
andregex
containing name of the message, what kind it is (ERROR
orWARNING
), a description of the notification and the regular expression detected as string values.
- property number_of_entries¶
Find the number of unique notifications from VASP.
Returns¶
- number_of_entriesint
The number of unique notification entries that VASP generated.
- property warnings¶
Fetch the warnings that VASP generated.
Returns¶
- warningslist
A list of all warnings from VASP. Each entry is a dict with the keys
name
,kind
,message
andregex
containing name of the message, what kind it is (ERROR
orWARNING
), a description of the error and the regular expression detected as string values.
The vasprun.xml parser interface.
- class aiida_vasp.parsers.content_parsers.vasprun.VasprunParser(*, handler=None, data=None, settings=None, options=None)[source]¶
Bases:
BaseFileParser
The parser interface that enables parsing of
vasprun.xml
content.The parser is triggered by using the keys listed in
PARSABLE_QUANTITIES
.- DEFAULT_SETTINGS = {'electronic_step_energies': False, 'energy_type': ['energy_extrapolated'], 'quantities_to_parse': ['structure', 'eigenvalues', 'dos', 'kpoints', 'occupancies', 'trajectory', 'energies', 'projectors', 'dielectrics', 'born_charges', 'hessian', 'dynmat', 'forces', 'stress', 'total_energies', 'maximum_force', 'maximum_stress', 'band_properties', 'version']}¶
- ENERGY_MAPPING = {'energy_extrapolated': 'energy_extrapolated_final', 'energy_extrapolated_electronic': 'energy_extrapolated', 'energy_free': 'energy_free_final', 'energy_free_electronic': 'energy_free', 'energy_no_entropy': 'energy_no_entropy_final', 'energy_no_entropy_electronic': 'energy_no_entropy'}¶
- ENERGY_MAPPING_VASP5 = {'energy_extrapolated': 'energy_no_entropy_final', 'energy_extrapolated_electronic': 'energy_extrapolated', 'energy_free': 'energy_free_final', 'energy_free_electronic': 'energy_free', 'energy_no_entropy': 'energy_extrapolated_final', 'energy_no_entropy_electronic': 'energy_no_entropy'}¶
- OPEN_MODE = 'rb'¶
- PARSABLE_QUANTITIES = {'band_properties': {'inputs': [], 'name': 'band_properties', 'prerequisites': []}, 'born_charges': {'inputs': [], 'name': 'born_charges', 'prerequisites': []}, 'dielectrics': {'inputs': [], 'name': 'dielectrics', 'prerequisites': []}, 'dos': {'alternatives': ['doscar-dos'], 'inputs': [], 'name': 'dos', 'prerequisites': []}, 'dynmat': {'inputs': [], 'name': 'dynmat', 'prerequisites': []}, 'eigenvalues': {'alternatives': ['eigenval-eigenvalues'], 'inputs': [], 'name': 'eigenvalues', 'prerequisites': []}, 'energies': {'inputs': [], 'name': 'energies', 'prerequisites': []}, 'fermi_level': {'inputs': [], 'name': 'fermi_level', 'prerequisites': []}, 'forces': {'inputs': [], 'name': 'forces', 'prerequisites': []}, 'hessian': {'inputs': [], 'name': 'hessian', 'prerequisites': []}, 'kpoints': {'alternatives': ['kpoints-kpoints'], 'inputs': [], 'name': 'kpoints', 'prerequisites': []}, 'maximum_force': {'inputs': [], 'name': 'maximum_force', 'prerequisites': []}, 'maximum_stress': {'inputs': [], 'name': 'maximum_stress', 'prerequisites': []}, 'occupancies': {'inputs': [], 'name': 'occupancies', 'prerequisites': []}, 'projectors': {'inputs': [], 'name': 'projectors', 'prerequisites': []}, 'stress': {'inputs': [], 'name': 'stress', 'prerequisites': []}, 'structure': {'alternatives': ['poscar-structure'], 'inputs': [], 'name': 'structure', 'prerequisites': []}, 'total_energies': {'inputs': [], 'name': 'total_energies', 'prerequisites': []}, 'trajectory': {'inputs': [], 'name': 'trajectory', 'prerequisites': []}, 'version': {'inputs': [], 'name': 'version', 'prerequisites': []}}¶
- property band_properties¶
Fetch key properties of the electronic structure.
- property born_charges¶
Fetch the Born effective charges.
- property dielectrics¶
Fetch the dielectric function.
- property dos¶
Fetch the total density of states.
- property dynmat¶
Fetch the dynamical eigenvectors and eigenvalues.
- property eigenvalues¶
Fetch eigenvalues.
- property energies¶
Fetch the total energies.
- property fermi_level¶
Fetch Fermi level.
- property final_forces¶
Fetch forces.
After or at the last recorded ionic step.
- property final_stress¶
Fetch stress.
After or at the last recorded ionic step.
- property final_structure¶
Fetch the structure.
After or at the last recorded ionic step. Should in principle be the same as the method above.
- property forces¶
Fetch forces.
This container should contain all relevant forces. Currently, it only contains the final forces, which can be obtain by the id final_forces.
- property hessian¶
Fetch the Hessian matrix.
- property kpoints¶
Fetch the kpoints an prepare for consumption by the NodeComposer.
- property last_forces¶
Fetch forces.
After or at the last recorded ionic step.
- property last_stress¶
Fetch stess.
After or at the last recorded ionic step.
- property last_structure¶
Fetch the structure.
After or at the last recorded ionic step.
- property maximum_force¶
Fetch the maximum force of at the last ionic run.
- property maximum_stress¶
Fetch the maximum stress of at the last ionic run.
- property occupancies¶
Fetch occupancies.
- property projectors¶
Fetch the projectors.
- property run_status¶
Fetch run_status information
- property stress¶
Fetch stress.
This container should contain all relevant stress. Currently, it only contains the final stress, which can be obtain by the id final_stress.
- property structure¶
Fetch a given structure.
Which structure to fetch is controlled by inputs.
eFL: Need to clean this so that we can set different structures to pull from the outside. Could be usefull not pulling the whole trajectory.
Currently defaults to the last structure.
- property total_energies¶
Fetch the total energies after the last ionic run.
- property trajectory¶
Fetch unitcells, positions, species, forces and stress.
For all calculation steps.
- property version¶
Fetch the VASP version from
parsevasp
and return it as a string object.
The .win parser interface.
- class aiida_vasp.parsers.content_parsers.win.BaseKeyValueParser[source]¶
Bases:
object
Common codebase for all parser utilities.
- empty_line = re.compile('[\\r\\n]\\s*[\\r\\n]')¶
- class aiida_vasp.parsers.content_parsers.win.KeyValueParser[source]¶
Bases:
BaseKeyValueParser
Key and value parser.¶
This baseclass has some utility functions for parsing files that are (mostly) in a key = value format. This class does not integrate with the VaspParser class currently. A simple example, which tries to convert values to python objects on a best effort basis. Usage:
import re from aiida_vasp.parsers.file_parsers.parser import KeyValueParser ParamParser(KeyValueParser): def __init__(self, file_path): self._file_path = py.path.local(file_path) super().__init__() self.result = {} def convert_or_not(self, value): for converter in self.get_converter_iter(): converted = self.try_convert(value, converter) if converted and 'value' in converted: return converted['value'] return value def parse_file(self): assignments = re.findall(self.assignment, self._file_path.read()) return {key: self.convert_or_not(value)}
- Parses files like::
StrParam = value_1 FloatParam = 1.0 BoolParam = True
- assignment = re.compile('(\\w+)\\s*[=: ]\\s*([^;\\n]*);?')¶
- bool_false = re.compile('^F$')¶
- bool_true = re.compile('^T$')¶
- comment = True¶
- classmethod int_unit(string_)[source]¶
Convert a string into a python value, associated unit and optional comment.
- classmethod retval(*args, **kwargs)[source]¶
Normalize return values from value conversion functions.
- class aiida_vasp.parsers.content_parsers.win.WinParser(path)[source]¶
Bases:
KeyValueParser
Parses wannier90 input.
- block = re.compile('begin (?P<name>\\w*)\\s*\\n\\s*(?P<content>[\\w\\W]*)\\s*\\n\\s*end \\1')¶
- comment = re.compile('(!.*)\\n?')¶