Source code for sphinx_doc_snip

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) 2019, Wolfgang Scherer, <Wolfgang.Scherer at gmx.de>
#
# This file is part of Documentation Standard.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# (progn (forward-line 1) (snip-insert "py_doc.main" t t "python") (insert "\n"))
r"""
sphinx_doc_snip.py - process sphinx-doc document snippets.

======  ====================
usage:  sphinx_doc_snip.py [OPTIONS] file-to-process ...
or      import sphinx_doc_snip
======  ====================

Options
=======

  ===================== ==================================================
  --force               overwrite existing files.
                        :rem:`space`
  --no-defaults         do not read default configuration files.
  -c, --config CFG      add CFG to list of configuration files.

  -i, --include INC     add INC as document to parse for snippets
                        only. The document is not resolved.
  -r, --replace REPL    add replacement `WHAT=WITH`. `@WHAT@` is
                        replaced by string `WITH` after resolving
                        snippets.

  -f, --format FMT      format for output documents. Default:
                        `{dir}/{base}-x{ext}`.
                        Placeholders: `path`, `dir`, `file`, `base`,
                        `ext`, `sbase` (secondary base of `base`),
                        `sext`.
                        If format is `-`, standard output is used.
                        :rem:`space`
  --html                convert to HTML with sphinx-readme.sh(1)
  --pdf                 convert to PDF with sphinx-readme.sh(1)

  -q, --quiet           suppress warnings
  -v, --verbose         verbose test output
  -d, --debug[=NUM]     show debug information
  -h, --help            display this help message

  --template list       show available templates.
  --eide[=COMM]         Emacs IDE template list (implies --template list).
  --template[=NAME]     extract named template to standard
                        output. Default NAME is ``-``.
  --extract[=DIR]       extract adhoc files to directory DIR (default: ``.``)
  --explode[=DIR]       explode script with adhoc in directory DIR
                        (default ``__adhoc__``)
  --setup[=install]     explode script into temporary directory and call
                        `python setup.py install`
  --implode             implode script with adhoc

  -t, --test            run doc tests
  ===================== ==================================================

Description
===========

:program:`sphinx_doc_snip.py` parses a set of documents for
document snippet defintions and resolves document snippet references
accordingly. The specification is in |chapter-document-snippets|.

Configuration Files
-------------------

The configuration files

- doc/.doc-snip.rc.default
- .doc-snip.rc.default
- doc/.doc-snip.rc
- .doc-snip.rc

are read in that order.

Example::

    FORCE=no
    FORMAT='{sbase}{sext}'
    INCLUDE='
    README.txt
    README-stations.txt
    '
    REPLACE='
    user=Max Benutzer
    user_short=mb
    '

Replacements
------------

The replacement facility allows to specify arbitrary replacement text
for placeholders enclosed in ``@``. With the following replacement
options:

+-----------------------------------------------------+--------------------------+--------------------------------+
| replacement option                                  | placeholder              | replacement                    |
+=====================================================+==========================+================================+
| --replace 'user=Max Benutzer'                       | `@`\ `user`\ `@`         | Max Benutzer                   |
+-----------------------------------------------------+--------------------------+--------------------------------+
| --replace 'user_short=mb'                           | `@`\ `user_short`\ `@`   | mb                             |
+-----------------------------------------------------+--------------------------+--------------------------------+
| --replace 'hostname_pfx=laptop-'                    | `@`\ `hostname_pfx`\ `@` | laptop-                        |
+-----------------------------------------------------+--------------------------+--------------------------------+
| --replace 'hostname=@\ hostname_pfx@@\ user_short@' | `@`\ `hostname`\ `@`     | @\ hostname_pfx@@\ user_short@ |
+-----------------------------------------------------+--------------------------+--------------------------------+

the placeholder `@`\ `hostname`\ `@` is replaced recursively
accordingly:

  @hostname@ => `laptop-mb`

- |:todo:| recursive snippet resolution

Module
======

Automatic Exports
=================

>>> for ex in __all__: printf(sformat('from {0} import {1}', __name__, ex))
from sphinx_doc_snip import Documentation
from sphinx_doc_snip import Document
from sphinx_doc_snip import Snippet
from sphinx_doc_snip import Section

Explicit Exports
================

>>> if '__all_internal__' in globals():
...   for ex in __all_internal__:
...     printf(sformat('from {0} import {1}', __name__, ex))

.. _END_OF_HELP_sphinx_doc_snip:

Details
=======
"""

# (progn (forward-line 1) (snip-insert "py.b.future.with" t t "python") (insert "\n"))
# for python 2.5
from __future__ import with_statement

# (progn (forward-line 1) (snip-insert "py.main.pyramid.activate" t t "py") (insert ""))

# --------------------------------------------------
# |||:sec:||| COMPATIBILITY
# --------------------------------------------------

import sys
# (progn (forward-line 1) (snip-insert "py.b.printf" t t "py") (insert "\n"))
# adapted from http://www.daniweb.com/software-development/python/code/217214
try:
    printf = eval("print") # python 3.0 case
except SyntaxError:
    printf_dict = dict()
    try:
        exec("from __future__ import print_function\nprintf=print", printf_dict)
        printf = printf_dict["printf"] # 2.6 case
    except SyntaxError:
        def printf(*args, **kwd): # 2.4, 2.5, define our own Print function
            fout = kwd.get("file", sys.stdout)
            w = fout.write
            if args:
                w(str(args[0]))
            sep = kwd.get("sep", " ")
            for a in args[1:]:
                w(sep)
                w(str(a))
            w(kwd.get("end", "\n"))
    del printf_dict

# (progn (forward-line 1) (snip-insert "py.b.sformat" t t "py") (insert "\n"))
try:
    ('{0}').format(0)
    def sformat (fmtspec, *args, **kwargs):
        return fmtspec.format(*args, **kwargs)
except AttributeError:
    try:
        import stringformat
        def sformat (fmtspec, *args, **kwargs):
            return stringformat.FormattableString(fmtspec).format(
                *args, **kwargs)
    except ImportError:
        printf('error: stringformat missing. Try `easy_install stringformat`.', file=sys.stderr)

# (progn (forward-line 1) (snip-insert "py.b.isstring" t t "python") (insert "\n"))
try:
    from ws_seq_type import isstring, issequence, sequence_type, UCHAR_FMT
except ImportError:
    # (progn (forward-line 1) (snip-insert "py.f.isstring" t t "py") (insert "\n"))
    exec('''
    def isstring(obj):
        return isinstance(obj, basestring)
    '''.strip())
    try:
        isstring("")
        UCHAR_FMT = 'u"{0}u{1:04x}"'
    except NameError:
        def isstring(obj):
            return isinstance(obj, str) or isinstance(obj, bytes)
        UCHAR_FMT = '"{0}u{1:04x}"'
    # (progn (forward-line 1) (snip-insert "py.f.issequence" t t "py") (insert "\n"))
    def issequence(arg, or_dict=False, or_seq=True):           # ||:fnc:||
        if not isstring(arg):
            if hasattr(arg, 'items'):
                return or_dict
            if hasattr(arg, '__getitem__'):
                return True
            if hasattr(arg, '__iter__'):
                return or_seq
        return False
    # (progn (forward-line 1) (snip-insert-mode "py.f.sequence_type" t) (insert "\n"))
    _st_strg = (True,  False, False, False)
    _st_list = (False, True,  False, False)
    _st_dict = (False, False, True,  False)
    _st_seq  = (False, False, False, True)
    _st_none = (False, False, False, False)
    def sequence_type(value):                                  # ||:fnc:||
        if isstring(value):
            return _st_strg
        if hasattr(value, 'items'):
            return _st_dict
        if hasattr(value, '__getitem__'):
            return _st_list
        if hasattr(value, '__iter__'):
            return _st_seq
        return _st_none

# (progn (forward-line 1) (snip-insert-mode "py.f.uchar" t) (insert "\n"))
def uchar(num):
    '''Make UNICODE character.'''
    return eval(sformat(UCHAR_FMT,'\\', num))

# (progn (forward-line 1) (snip-insert "py.b.dict.items" t t "py") (insert "\n"))
try:
    getattr(dict(), 'iteritems')
except AttributeError:
    ditems  = lambda d: getattr(d, 'items')()
    dkeys   = lambda d: getattr(d, 'keys')()
    dvalues = lambda d: getattr(d, 'values')()
else:
    ditems  = lambda d: getattr(d, 'iteritems')()
    dkeys   = lambda d: getattr(d, 'iterkeys')()
    dvalues = lambda d: getattr(d, 'itervalues')()

# (progn (forward-line 1) (snip-insert "py.b.xrange" t t "py") (insert "\n"))
# `xrange` returns a generator, which `range` already does for python3
# note: use l.. and g.. to get list/generator versions
try:
    xrange(0)
    lrange = lambda *args, **kwargs: range(*args, **kwargs)
except NameError:
    xrange = range
    lrange = lambda *args, **kwargs: list(range(*args, **kwargs))
grange = xrange

# `xfilter` returns a list, `filter` may return a generator. This is
# different from the range/xrange semantics!
if isinstance(filter(str, []), list):
    xfilter = filter
    gfilter = lambda _f, _s, *args, **kwargs: (_e for _e in _s if _f(_e))
else:
    xfilter = lambda *args, **kwargs: list(filter(*args, **kwargs))
    gfilter = filter
lfilter = xfilter

# `xmap` returns a list, `map` may return a generator. This is
# different from the range/xrange semantics!
if isinstance(map(str, []), list):
    xmap = map
    gmap = lambda _f, _s, *args, **kwargs: (_f(_e) for _e in _s)
else:
    xmap = lambda *args, **kwargs: list(map(*args, **kwargs))
    gmap = map
lmap = xmap

# `long` is gone in python3
try:
    isinstance(int, long)
except NameError:
    long = int

# (progn (forward-line 1) (snip-insert "py_f.lfind" t t "python") (insert "\n"))
def lfind(l, elt):
    try:
        return l.index(elt)
    except ValueError:
        return -1

import os
import re

# --------------------------------------------------
# |||:sec:||| CONFIGURATION
# --------------------------------------------------

__all__ = []
__all_internal__ = []

# (progn (forward-line 1) (snip-insert "py.b.dbg.def" t t "python") (insert ""))
dbg_fwid = globals().get('dbg_fwid', 15)

# (progn (forward-line 1) (snip-insert "py.b.canonize.module" t t "python") (insert ""))
def _canonize_module_(module_or_name, full=None, drop=None):
    if isstring(module_or_name):
        module = sys.modules[module_or_name]
    else:
        module = module_or_name
    module_name = module.__name__
    # flag for __main__
    _is_main_ = (module_name == '__main__')
    if not hasattr(module, '_is_main_'):
        module._is_main_ = _is_main_
    if not full:
        return _is_main_
    # module file name -> canonical name
    try:
        mfile = module.__file__
    except AttributeError:
        return
    canon_name_ = mfile
    canon_name_ = os.path.basename(canon_name_)
    canon_name_, _ext = os.path.splitext(canon_name_)
    # adhoc compiliation xx_.py -> xx.py
    if canon_name_.endswith('_') and not canon_name_.endswith('__'):
        canon_name_ = canon_name_[:-1]
    canon_name_ = re.sub('[^0-9A-Za-z_]+', '_', canon_name_)
    # find parent module |:check:| distutils/pkg_resources?
    mdir = os.path.abspath(os.path.dirname(mfile))
    mparts = []
    while mdir and os.path.exists(os.path.join(mdir, '__init__.py')):
        mdir, pfx = os.path.split(mdir)
        mparts.insert(0, pfx)
    parent = '.'.join(mparts)
    if canon_name_ != '__init__':
        mparts.append(canon_name_)
    if drop:
        mparts = mparts[:-drop]
    canon_name = '.'.join(mparts)
    if module_name != canon_name:
        if parent != canon_name or drop: # |:check:| why?
            if parent:
                # fix parent module
                exec('import ' + parent)
                if parent in (sys.modules):
                    setattr(sys.modules[parent], canon_name_, module)
            sys.modules[canon_name] = module
        module.__name__ = canon_name
        # adjust module members
        for t in dvalues(vars(module)):
            try:
                if '__module__' in vars(t) and t.__module__ == module_name:
                    t.__module__ = canon_name
            except TypeError:
                pass
    return _is_main_

#_canonize_module_(__name__, __name__ == '__main__')

# (progn (forward-line 1) (snip-insert "py.b.strings" t t "py") (insert "\n"))
# (progn (forward-line 1) (snip-insert "py.f.strclean" t t "py") (insert "\n"))
# (progn (forward-line 1) (snip-insert "py.b.logging" t t "python") (insert ""))
# (progn (forward-line 1) (snip-insert "py.b.ordereddict" t t "py") (insert "\n"))
# (progn (forward-line 1) (snip-insert "py.b.dbg.setup" t t "py") (insert "\n"))
# (progn (forward-line 1) (snip-insert "py.main.project.libdir" t t "py") (insert "\n"))
# (progn (forward-line 1) (snip-insert "py.main.sql.alchemy" t t "py") (insert "\n"))
# (progn (forward-line 1) (snip-insert "py.main.sql.ws" t t "py") (insert "\n"))

# @:adhoc_run_time:@
#import adhoc                                               # @:adhoc:@

# (progn (forward-line 1) (snip-insert "py.b.posix" t t "py") (insert "\n"))
# (progn (forward-line 1) (snip-insert "py.b.os.system.sh" t t "py") (insert "\n"))
# (progn (forward-line 1) (snip-insert "py.b.prog.path" t t "py") (insert "\n"))
# (progn (forward-line 1) (snip-insert "py_b.line-loop" t t "py") (insert "\n"))
# (progn (forward-line 1) (snip-insert "py_b.table_standalone" t t "python") (insert ""))

# (progn (forward-line 1) (snip-insert "py.wsrfid.pylons.imports" t t "python") (insert ""))
# (progn (forward-line 1) (snip-insert "py.main.wsgi.get.app" t t "python") (insert ""))

# (progn (forward-line 1) (snip-insert "py_wsrfid.config_delayed" t t "python") (insert "\n"))
# (progn (forward-line 1) (snip-insert "py_b.wsrfid.config_translate_shortcuts" t t "python") (insert "\n"))

# (progn (forward-line 1) (snip-insert "py_b.dba_imports" t t "python") (insert "\n"))
# (progn (forward-line 1) (snip-insert "py_b.dba_datainit" t t "python") (insert "\n"))
# (progn (forward-line 1) (snip-insert "py_jsmo.imports" t t "python") (insert "\n"))
import pyjsmo                                              # @:adhoc:@
# (progn (forward-line 1) (snip-insert "py_jsmo.compat" t t "python") (insert "\n"))
from pyjsmo.compat import OrderedDict
from pyjsmo.compat import ucs, u8s, nts
from pyjsmo.compat import BytesIO, StringIO
# (progn (forward-line 1) (snip-insert "py_jsmo.result" t t "python") (insert "\n"))
from pyjsmo.result import ERR_WARNING, ERR_NONE, ERR_UNKNOWN
from pyjsmo.result import Result, IResult, vmsg
# (progn (forward-line 1) (snip-insert "py_jsmo.translate" t t "python") (insert "\n"))
from pyjsmo.translate import trans_identity, trans_string, trans_empty_null, trans_null_empty
from pyjsmo.translate import trans_int, trans_bool_int, trans_bool_check, trans_to_crlf, trans_from_crlf
from pyjsmo.translate import trans_list_space_comma_bar, trans_list_space_comma, trans_list_space_bar, trans_list_comma_bar, trans_list_bar
from pyjsmo.translate import parse_isodate, parse_isodate_naive, trans_date_str, trans_str_date

# (progn (forward-line 1) (snip-insert "py_jsmo.formatv" t t "python") (insert "\n"))
# (progn (forward-line 1) (snip-insert "py_jsmo.quick" t t "python") (insert "\n"))

import datetime

try:
    from urllib2 import URLError # as URLError
    from urllib import urlopen # as urlopen
    pass
except ImportError:
    from urllib.error import URLError # as URLError
    from urllib.request import urlopen # as urlopen
    pass

from pyjsmo.config import ConfigIO, cfs, LConfigParser
from pyjsmo.config import config_from_rc_files, rc_string_from_config
import pyjsmo.tags
import pyjsmo.sections

# |||:here:|||

# --------------------------------------------------
# |||:sec:||| DATA
# --------------------------------------------------

# =====
# Title
# =====
# Subtitle
# --------
# Titles are underlined (or over-
# and underlined) with a printing
# nonalphanumeric 7-bit ASCII
# character. Recommended choices
# are "``= - ` : ' " ~ ^ _ * + # < >``".
# The underline/overline must be at
# least as long as the title text.

SECTION_UNDERLINE_CHAR_RX = '[!-/:-@[-`{-~]'

SNIP_RX = re.escape('|<-snip->|')
HEADER_CHARS = '-#=~.+'
SNAP_RX = re.escape('|<-sn') + '([' + HEADER_CHARS + 'a0-9])' + re.escape('p->|')
BULLET_RX = '( *([-+* ]|(?:[#]|[0-9]+)[.]) +)'
COMM_RX = re.escape('.. ')
COMM_BS_RX = COMM_RX + re.escape('\\')

# cannot make the backslash optional, since the substitution
# definition would be recognized as snippet section by :class:`SectPart`
SEC_RX = re.compile('^(' + COMM_BS_RX + ')?' + SNIP_RX)

ITM_RX = re.compile('^(' + COMM_RX + ')?' + BULLET_RX + SNIP_RX)

# backslash can be optional, since the substitution definition can be
# reliably detected in :meth:`resolve
REF_RX = re.compile('^(' + COMM_BS_RX + '?)?' + BULLET_RX + '?' + SNAP_RX)

FLAGS_RX = '[-]'

SEARCH_PATH_DOC = [
    '@input_file_dir@',
    '@here@',
]

SEARCH_PATH_RC = [
    '@input_file_dir@/doc',
    '@here@/doc',
]
SEARCH_PATH_RC.extend(SEARCH_PATH_DOC)

RC_FILES = [
    '.doc-snip.rc.default',
    '.doc-snip.rc',
]

# |||:here:|||
DOC_SNIPPET_TEST = r'''
.. \|<-snip->|
.. _Labeled Section Label:

--------------------------------------------------
:rem:`||:sec:||`\ Labeled Section
--------------------------------------------------

Section body filled with labeled stuff.
Section body filled with labeled stuff.
Section body filled with labeled stuff.

field: value
field: value
.. \|<-snip->|

field: value
field: value

.. \|<-snip->| -

--------------------------------------------------
:rem:`||:sec:||`\ Unlabeled Section
--------------------------------------------------

Section body filled with unlabeled stuff.
Section body filled with unlabeled stuff.
Section body filled with unlabeled stuff.
.. \|<-snip->|

.. \|<-snip->| named paragraph

Section body filled with named stuff.
Section body filled with named stuff.
Section body filled with named stuff.

.. \|<-snip->|

- |<-snip->| some item

  item body filled with stuff.
  item body filled with stuff.
  .. \|<-snip->| item 1

  * |<-snip->| some indented item

    indented item body filled with stuff.
    indented item body filled with stuff.
    .. \|<-snip->| item 2

.. |<-snap->| named paragraph

- |<-snap->| see :ref:`Labeled Section Label`
- |<-sn1p->| see `Unlabeled Section`_

  #. |<-snap->| item 2
  #. |<-snap->| item 1

  |<-sn1p->| item 2

  |<-sn3p->| item 2
  |<-sn3p->| item 1

  |<-sn5p->| item 2
  |<-sn5p->| item 1

  |<-sn4p->| item 2
  |<-sn6p->| item 2

'''.strip()

# |||:here:|||

# --------------------------------------------------
# |||:sec:||| CLASSES
# --------------------------------------------------

__all__.append('Section')
[docs]class Section(pyjsmo.sections.Section): # ||:cls:|| r"""Text section. Behaves like a :class:`pyjsmo.sections.Section`. The method :meth:`resolve` replaces snippet references with snippets. """ _pyjsmo_versions = [ (1, {'bases': [0], 'order': ['is_snippet', ], 'defaults': OrderedDict(( ('is_snippet', None), )), 'amap': [], 'expand': None, }), ] def __init__(self, *args, **kwargs): # |:mth:| super(Section, self).__init__(*args, **kwargs)
[docs] def resolve(self, snippets): # |:mth:| r"""Resolve snippets in section body. """ _body = [] for _line in self.body: _mo = REF_RX.search(_line) if not _mo: _body.append(_line) continue _title = _line[_mo.end(0):].strip() if _title.startswith('replace::'): # skip substitution definition _body.append(_line) continue for _rx, _group in (('`([^`]*)`_', 1), (':ref:`([^`]*)`', 1)): _tmo = re.search(_rx, _title) if _tmo: _title = _tmo.group(_group) break _snippet = snippets.get(_title.lower()) if _snippet is None: printe(sformat("# |"":WRN:| warning: snippet `{0}` not found", _title)) _body.append(_line) continue _pfx = _mo.group(2) or '' _pfx_len = len(_pfx) _ref_type = _mo.group(3) _tag_type = _mo.group(4) if not _ref_type and _pfx_len: _ref_type = ' ' _feat_no_item = _tag_type == '0' if _feat_no_item: _pfx = '' _pfx_len = 0 _ref_type = '' _tag_type = '' # |:info:| # >>> print("" in "st") # True # >>> print("" in ("s", "t")) # False _feat_bold_title = (_tag_type and _tag_type in '12') _feat_definition_list = (_tag_type and _tag_type in '34') _feat_field_list = (_tag_type and _tag_type in '56') _feat_replace_bullet = (_tag_type and _tag_type in '246') _add_indent_len = 0 _feat_title = _feat_bold_title _feat_title_sep_line = False _feat_title_delim = '' if _feat_bold_title: _feat_title_delim = '**' _feat_title_sep_line = True if _feat_definition_list or _feat_field_list: _feat_title = True if _feat_field_list: _feat_title_delim = ':' _add_indent_len = 2 if _feat_replace_bullet: if _ref_type == ' ': _pfx = _pfx[:-2] else: _pfx = _pfx.rstrip()[:-1] _pfx_len = len(_pfx) _is_item = _ref_type or (_tag_type and _tag_type in '12345') if _debug: printe(sformat("# "":DBG: {1:<{0}s}: ]{2!s}[", dbg_fwid, "_mo.groups", (_mo.groups()))) # |||||:here:||||| reference features _indent = ''.join((' ' for _i in xrange(_pfx_len))) _body_indent = _indent + ''.join((' ' for _i in xrange(_add_indent_len))) if not _is_item: _body.append('') _body.append(_indent + '.. Source: ' + _line) if _snippet.label and not _snippet.label_done: _body.append('') _body.append(_indent + _snippet.label) _snippet.label_done = True if _snippet.header: if _tag_type and _tag_type in HEADER_CHARS: _header = list(_snippet.header) _underline_len = len(_header[-1]) _underline = ''.join((_tag_type for _i in xrange(_underline_len))) _header[-1] = _underline if len(_header) > 2: _header[0] = _underline else: _header = _snippet.header _body.append('') _body.extend((_indent + _l for _l in _header)) _body.append('') if _feat_title: _body.append(_pfx + _feat_title_delim + _snippet.title + _feat_title_delim) if _feat_title_sep_line: _body.append('') _pfx = _body_indent _prefixes = [_pfx] _body.extend((((_prefixes and _prefixes.pop()) or _body_indent) + _l for _l in _snippet.body)) if _is_item: _body.append('') _body.append(_body_indent + '.. Source: ' + _line) _body.append('') self.body = _body
__all__.append('Snippet')
[docs]class Snippet(Section): # ||:cls:|| r"""Snippet section. Behaves like a standard :class:`Section` instance until method :meth:`prepare` is called, which converts the section to a snippet. """ _pyjsmo_versions = [ (1, {'bases': [0], 'order': ['title', 'label', 'header', 'drop', 'titles', 'pfx', 'label_done'], 'defaults': OrderedDict(( ('is_snippet', True), ('title', None), ('label', None), ('drop', None), ('titles', []), ('pfx', ''), ('label_done', None), )), 'amap': [], 'expand': None, }), ] def __init__(self, *args, **kwargs): # |:mth:| super(Snippet, self).__init__(*args, **kwargs) self.prepare()
[docs] def reset(self): # |:mth:| r"""Reset snippet for new resolution. """ self.label_done = False
[docs] def prepare(self, section=None): # |:mth:| r"""Prepare snippet. """ if section is not None: self.update(section) elif not self.start and not self.end and not self.body: # empty snippet return self.body = list(self.body) _pfx = self.pfx or '' _pfx_len = len(_pfx) _titles = self.titles # handle item snippets if _pfx_len: self.body = [_l[_pfx_len:] for _l in self.body] self.end = self.end[_pfx_len:] try: _line = self.body[0] _mo = SEC_RX.search(_line) if _mo: self.body[0] = _line[_mo.end(0):].lstrip() except: pass # snippet flags and explicit title for _marker in (self.start or '', self.end or ''): _mo = SEC_RX.search(_marker) if _mo: _flag_title = _marker[_mo.end(0):].strip() _mo = re.match('(' + FLAGS_RX + ')' + '( +|$)', _flag_title) if _mo: _flags = _mo.group(1) _flag_title = _flag_title[_mo.end(0):] if '-' in _flags: self.drop = True if _flag_title: _titles.append(_flag_title) # detect first label and/or first section _label_indx = None _label_title = None _header_start = None _header_end = None _header_title = None _body = self.body _body_len = len(_body) _body_bound = _body_len - 2 for _indx, _line in enumerate(_body): if not _line: continue # detect label _mo = re.match('[.][.] _(.*): *$', _line) if _mo: if _label_indx is None: _label_indx = _indx if _label_title is None: _label_title = re.sub('`$', '', re.sub('^`', '', _mo.group(1))).strip() continue # |||||:here:||||| detect section _hchar = _line[0] if re.search(SECTION_UNDERLINE_CHAR_RX, _hchar): _underline_rx = '^' + re.escape(_hchar) + '+$' _mo = re.search(_underline_rx, _line) if _mo: _line_len = len(_line) if _indx < _body_bound and _body[_indx + 1]: _underline = _body[_indx + 2] if re.search(_underline_rx, _underline): _underline_len = len(_underline) if _line_len != _underline_len: printe(sformat("# |"":WRN:| warning: over/underline do not match:\n# {0}\n# {1}", _line, _underline)) if len(_body[_indx + 1]) > max(_line_len, _underline_len): printe(sformat("# |"":WRN:| warning: over/underline too short:\n# {0}\n# {1}\n# {2}", _line, _body[_indx + 1], _underline)) _header_start = _indx _header_end = _indx + 3 break if _indx > 0 and _body[_indx - 1]: if len(_body[_indx - 1]) > _line_len: printe(sformat("# |"":WRN:| warning: underline too short:\n# {0}\n# {1}", _body[_indx + 1], _line)) _header_start = _indx - 1 _header_end = _indx + 1 break # header must be removed before label _header = None if _header_start is not None: _header = _body[_header_start:_header_end] _line = _body[_header_end - 2] _mo = re.match(':rem:`[|]+:sec:[|]+`[\\\\] ', _line) if _mo: _header_title = _line[_mo.end(0):].strip() else: _header_title = _line del(self.body[_header_start:_header_end]) self.header = _header _label = None if _label_indx is not None: _label = self.body[_label_indx] del(self.body[_label_indx]) self.label = _label if _header_title: _titles.append(_header_title) if _label_title: _titles.append(_label_title) if _titles: self.title = _titles[0] self.start = None self.end = None self.strip() return
[docs] def dump(self, file=None): # |:mth:| r"""Dump snippet. """ if file is None: file = sys.stderr _title = self.title or '<unnamed document snippet>' _titles = ' | '.join(self.titles or (_title, )) if self.drop: _flag = '- ' else: _flag = '' printf(sformat(".. \\|<-snip->| {0}{1}", _flag, _titles), file=file) if self.label: printf(self.label, file=file) if self.header: printf('\n'.join(self.header), file=file) printf(self, file=file)
# (progn (forward-line -1) (insert "\n") (snip-insert "py.s.meth" t t "py") (backward-symbol-tag 1 "fillme" "::")) # (progn (forward-line -2) (insert "\n") (snip-insert "py.s.property" t t "py") (backward-symbol-tag 1 "fillme" "::")) __all__.append('Document')
[docs]class Document(pyjsmo.PyJsMo): # ||:cls:|| r""" .. \|||:here:||| Initialize document, parse text or load from file handle/filename:: _doc = Document() _doc.parse(TEXT) _doc.load(file_handle) _doc.load(filename) Initialize document from filename (automatically loads file):: _doc = Document((1, 'filename')) Initialize document from filename and text. Text is parsed and file is not loaded: >>> _doc = Document((1, 'filename', DOC_SNIPPET_TEST)) >>> printf(_doc) #doctest: +ELLIPSIS { "filename": "filename", "text": ".. \\|<-snip->|\n.. _Labeled Section Label:... |<-sn4p->| item 2\n |<-sn6p->| item 2", "partition": { "start_rx": {...}, "end_rx": {...}, "this": [], "that": [], "sections": [ ... ] }, "body": { "start_rx": null, "end_rx": null, "this": [], "that": [], "sections": [ { "start": ".. \\|<-snip->|", "body": [ ".. _Labeled Section Label:", "", "--------------------------------------------------", ":rem:`||:sec:||`\\ Labeled Section", "--------------------------------------------------", "", "Section body filled with labeled stuff.", "Section body filled with labeled stuff.", "Section body filled with labeled stuff.", "", "field: value", "field: value" ], "end": ".. \\|<-snip->|", "fsep": ": ", "is_snippet": true, "title": null, "label": null, "header": null, "drop": null, "titles": [ "Labeled Section", "Labeled Section Label" ], "pfx": "", "label_done": null }, { "start": null, "body": [ "", "field: value", "field: value", "" ], "end": null, "fsep": ": ", "is_snippet": null }, { "start": null, "body": [ "" ], "end": null, "fsep": ": ", "is_snippet": null }, { "start": ".. \\|<-snip->| named paragraph", "body": [ "", "Section body filled with named stuff.", "Section body filled with named stuff.", "Section body filled with named stuff.", "" ], "end": ".. \\|<-snip->|", "fsep": ": ", "is_snippet": true, "title": null, "label": null, "header": null, "drop": null, "titles": [ "named paragraph" ], "pfx": "", "label_done": null }, { "start": null, "body": [ "" ], "end": null, "fsep": ": ", "is_snippet": null }, { "start": null, "body": [ "- |<-snip->| some item", "", " item body filled with stuff.", " item body filled with stuff." ], "end": " .. \\|<-snip->| item 1", "fsep": ": ", "is_snippet": "-", "title": null, "label": null, "header": null, "drop": null, "titles": [ "item 1" ], "pfx": "- ", "label_done": null }, { "start": null, "body": [ "" ], "end": null, "fsep": ": ", "is_snippet": null }, { "start": null, "body": [ " * |<-snip->| some indented item", "", " indented item body filled with stuff.", " indented item body filled with stuff." ], "end": " .. \\|<-snip->| item 2", "fsep": ": ", "is_snippet": "*", "title": null, "label": null, "header": null, "drop": null, "titles": [ "item 2" ], "pfx": " * ", "label_done": null }, { "start": null, "body": [ "", ".. |<-snap->| named paragraph", "", "- |<-snap->| see :ref:`Labeled Section Label`", "- |<-sn1p->| see `Unlabeled Section`_", "", " #. |<-snap->| item 2", " #. |<-snap->| item 1", "", " |<-sn1p->| item 2", "", " |<-sn3p->| item 2", " |<-sn3p->| item 1", "", " |<-sn5p->| item 2", " |<-sn5p->| item 1", "", " |<-sn4p->| item 2", " |<-sn6p->| item 2" ], "end": null, "fsep": ": ", "is_snippet": null } ] }, "snippets": { "start_rx": null, "end_rx": null, "this": [], "that": [], "sections": [ { "start": null, "body": [ "Section body filled with labeled stuff.", "Section body filled with labeled stuff.", "Section body filled with labeled stuff.", "", "field: value", "field: value" ], "end": null, "fsep": ": ", "is_snippet": true, "title": "Labeled Section", "label": null, "header": [ "--------------------------------------------------", ":rem:`||:sec:||`\\ Labeled Section", "--------------------------------------------------" ], "drop": null, "titles": [ "Labeled Section", "Labeled Section Label" ], "pfx": "", "label_done": null }, { "start": null, "body": [ "Section body filled with unlabeled stuff.", "Section body filled with unlabeled stuff.", "Section body filled with unlabeled stuff." ], "end": null, "fsep": ": ", "is_snippet": true, "title": "Unlabeled Section", "label": null, "header": [ "--------------------------------------------------", ":rem:`||:sec:||`\\ Unlabeled Section", "--------------------------------------------------" ], "drop": true, "titles": [ "Unlabeled Section" ], "pfx": "", "label_done": null }, { "start": null, "body": [ "Section body filled with named stuff.", "Section body filled with named stuff.", "Section body filled with named stuff." ], "end": null, "fsep": ": ", "is_snippet": true, "title": "named paragraph", "label": null, "header": null, "drop": null, "titles": [ "named paragraph" ], "pfx": "", "label_done": null }, { "start": null, "body": [ "some item", "", "item body filled with stuff.", "item body filled with stuff." ], "end": null, "fsep": ": ", "is_snippet": "-", "title": "item 1", "label": null, "header": null, "drop": null, "titles": [ "item 1" ], "pfx": "- ", "label_done": null }, { "start": null, "body": [ "some indented item", "", "indented item body filled with stuff.", "indented item body filled with stuff." ], "end": null, "fsep": ": ", "is_snippet": "*", "title": "item 2", "label": null, "header": null, "drop": null, "titles": [ "item 2" ], "pfx": " * ", "label_done": null } ] }, "resolved": null } .. \|||:here:||| >>> _doc.dump_snippets(file=sys.stdout) .. .. -------------------------------------------------- .. \|<-snip->| Labeled Section | Labeled Section Label -------------------------------------------------- :rem:`||:sec:||`\ Labeled Section -------------------------------------------------- Section body filled with labeled stuff. Section body filled with labeled stuff. Section body filled with labeled stuff. <BLANKLINE> field: value field: value .. .. -------------------------------------------------- .. \|<-snip->| - Unlabeled Section -------------------------------------------------- :rem:`||:sec:||`\ Unlabeled Section -------------------------------------------------- Section body filled with unlabeled stuff. Section body filled with unlabeled stuff. Section body filled with unlabeled stuff. .. .. -------------------------------------------------- .. \|<-snip->| named paragraph Section body filled with named stuff. Section body filled with named stuff. Section body filled with named stuff. .. .. -------------------------------------------------- .. \|<-snip->| item 1 some item <BLANKLINE> item body filled with stuff. item body filled with stuff. .. .. -------------------------------------------------- .. \|<-snip->| item 2 some indented item <BLANKLINE> indented item body filled with stuff. indented item body filled with stuff. .. \|||:here:||| >>> printf(str(_doc.partition.sections) == DOC_SNIPPET_TEST) True >>> printf(str(_doc.body.sections) == DOC_SNIPPET_TEST) False .. \|||:here:||| >>> _resolved = _doc.resolve() >>> printf(str(_resolved.sections)) .. \|<-snip->| .. _Labeled Section Label: <BLANKLINE> -------------------------------------------------- :rem:`||:sec:||`\ Labeled Section -------------------------------------------------- <BLANKLINE> Section body filled with labeled stuff. Section body filled with labeled stuff. Section body filled with labeled stuff. <BLANKLINE> field: value field: value .. \|<-snip->| <BLANKLINE> field: value field: value <BLANKLINE> <BLANKLINE> .. \|<-snip->| named paragraph <BLANKLINE> Section body filled with named stuff. Section body filled with named stuff. Section body filled with named stuff. <BLANKLINE> .. \|<-snip->| <BLANKLINE> - |<-snip->| some item <BLANKLINE> item body filled with stuff. item body filled with stuff. .. \|<-snip->| item 1 <BLANKLINE> * |<-snip->| some indented item <BLANKLINE> indented item body filled with stuff. indented item body filled with stuff. .. \|<-snip->| item 2 <BLANKLINE> <BLANKLINE> .. Source: .. |<-snap->| named paragraph <BLANKLINE> Section body filled with named stuff. Section body filled with named stuff. Section body filled with named stuff. <BLANKLINE> <BLANKLINE> - Section body filled with labeled stuff. Section body filled with labeled stuff. Section body filled with labeled stuff. <BLANKLINE> field: value field: value <BLANKLINE> .. Source: - |<-snap->| see :ref:`Labeled Section Label` <BLANKLINE> - **Unlabeled Section** <BLANKLINE> Section body filled with unlabeled stuff. Section body filled with unlabeled stuff. Section body filled with unlabeled stuff. <BLANKLINE> .. Source: - |<-sn1p->| see `Unlabeled Section`_ <BLANKLINE> <BLANKLINE> #. some indented item <BLANKLINE> indented item body filled with stuff. indented item body filled with stuff. <BLANKLINE> .. Source: #. |<-snap->| item 2 <BLANKLINE> #. some item <BLANKLINE> item body filled with stuff. item body filled with stuff. <BLANKLINE> .. Source: #. |<-snap->| item 1 <BLANKLINE> <BLANKLINE> **item 2** <BLANKLINE> some indented item <BLANKLINE> indented item body filled with stuff. indented item body filled with stuff. <BLANKLINE> .. Source: |<-sn1p->| item 2 <BLANKLINE> <BLANKLINE> item 2 some indented item <BLANKLINE> indented item body filled with stuff. indented item body filled with stuff. <BLANKLINE> .. Source: |<-sn3p->| item 2 <BLANKLINE> item 1 some item <BLANKLINE> item body filled with stuff. item body filled with stuff. <BLANKLINE> .. Source: |<-sn3p->| item 1 <BLANKLINE> <BLANKLINE> :item 2: some indented item <BLANKLINE> indented item body filled with stuff. indented item body filled with stuff. <BLANKLINE> .. Source: |<-sn5p->| item 2 <BLANKLINE> :item 1: some item <BLANKLINE> item body filled with stuff. item body filled with stuff. <BLANKLINE> .. Source: |<-sn5p->| item 1 <BLANKLINE> <BLANKLINE> item 2 some indented item <BLANKLINE> indented item body filled with stuff. indented item body filled with stuff. <BLANKLINE> .. Source: |<-sn4p->| item 2 <BLANKLINE> :item 2: some indented item <BLANKLINE> indented item body filled with stuff. indented item body filled with stuff. <BLANKLINE> .. Source: |<-sn6p->| item 2 <BLANKLINE> .. \|||:here:||| """ _pyjsmo_versions = [ (1, {'bases': [0], 'order': ['filename', 'text', 'partition', 'body', 'snippets', 'resolved'], 'defaults': OrderedDict(( ('filename', None), ('text', None), ('partition', None), ('body', None), ('snippets', None), )), 'amap': [], 'expand': None, }), ] def __init__(self, *args, **kwargs): # |:mth:| super(Document, self).__init__(*args, **kwargs) if self.text is not None or self.partition is not None: self.parse(self.text, self.partition) elif self.filename: self.load(self.filename) else: self.parse()
[docs] def parse(self, text=None, partition=None): # |:mth:| r"""Parse document for document snippets. """ if self.body is not None: return if text is None: if partition is None: text = '' else: text = str(partition) self.text = text if partition is None: partition = pyjsmo.sections.SectPart((1, SEC_RX, SEC_RX)) partition.parse(text) partition.this = [] partition.that = [] self.partition = partition # detect document snippets _sections = partition.sections.__class__() for _sec in partition.sections: # mark section snippets if _sec.start is not None: _nsec = Snippet() _nsec.update(_sec) _sections.append(_nsec) continue # detect item document snippets _nsec = Section() _body = _nsec.body _itm_end_rx = None _pfx_len = 0 for _line in _sec.body: if _itm_end_rx: _mo = _itm_end_rx.search(_line[_pfx_len:]) if _mo: _nsec.end = _line _sections.append(_nsec) _nsec = Section() _body = _nsec.body _itm_end_rx = None _pfx_len = 0 continue else: _mo = ITM_RX.search(_line) if _mo: _type = _mo.group(3) _pfx = _mo.group(2) _pfx_len = len(_pfx) if _body: _sections.append(_nsec) _nsec = Snippet() _nsec.is_snippet = _type _nsec.pfx = _pfx _body = _nsec.body _itm_end_rx = SEC_RX _body.append(_line) if _body: _sections.append(_nsec) partition.sections = _sections # construct body and snippets self.body = body = pyjsmo.sections.SectPart() self.snippets = snippets = pyjsmo.sections.SectPart() for _sec in partition.sections: if not _sec.is_snippet: body.sections.append(_sec) continue _snippet = Snippet() _snippet.prepare(_sec) if not _snippet.drop: _snippet.label = None body.sections.append(_sec) snippets.sections.append(_snippet)
[docs] def load(self, file_or_name): # |:mth:| r"""Load document from file. :param file_or_name: file handle or filename. """ if not isstring(file_or_name): _filename = self.filename _fh = file_or_name _do_close = False else: _filename = file_or_name if _filename == '-': _fh = sys.stdin _do_close = False else: _fh = None _filename = re.sub('^file:/+(?i)', '/', _filename) if os.path.exists(_filename): _fh = open(_filename, 'rb') elif re.match('[^:/]+:/', _filename): try: _fh = urlopen(_filename) except: (_t, _e, _tb) = sys.exc_info() _msg = sformat('{0}: {1}', _t.__name__, _e) printe(sformat("# ||"":ERR:|| error: cannot open `{0}`: {1}", _filename, _msg)) del(_tb) raise _do_close = _fh is not None if _fh is None: raise IOError(sformat("# ||"":ERR:|| error: could not open {0}", _filename)) self.clear() self.filename = _filename self.parse(_fh.read()) if _do_close: _fh.close()
[docs] def register_snippets_with(self, snippets, include=None): # |:mth:| r"""Register document snippets in snippets dict. :param snippets: snippets dictionary. """ for _snippet in self.snippets.sections: _title = _snippet.title if not _title: printe(sformat("# |"":WRN:| warning: snippet without title ignored {0}", '')) continue if include: _snippet.label = None for _key in (_t.lower() for _t in set(_snippet.titles)): if _key in snippets: printe(sformat("# |"":WRN:| warning: snippet `{0}` already defined ", _key)) continue snippets[_key] = _snippet return snippets
[docs] def map_snippets(self, include=None): # |:mth:| r"""Get document snippets dictionary. """ return self.register_snippets_with(OrderedDict(), include)
[docs] def resolve(self, snippets=None): # |:mth:| r"""Resolve snippets in document. :returns: :class:`pyjsmo.sections.SectPart` instance with resolved body. :param snippets: snippet section dictionary. I None, the document snippets are """ if snippets is None: snippets = self.map_snippets() self.resolved = _resolved = pyjsmo.sections.SectPart((1, SEC_RX, SEC_RX)) _sections = _resolved.sections for _section in self.body.sections: _nsec = _section.copy() _sections.append(_nsec) _nsec.resolve(snippets) return _resolved
[docs] def dump_snippets(self, file=None): # |:mth:| r"""Dump document snippets. """ if file is None: file = sys.stderr for _snippet in self.snippets.sections: printf('..', file=file) printf(".. --------------------------------------------------") _snippet.dump(file=file)
# (progn (forward-line -1) (insert "\n") (snip-insert "py.s.meth" t t "py") (backward-symbol-tag 1 "fillme" "::")) # (progn (forward-line -2) (insert "\n") (snip-insert "py.s.property" t t "py") (backward-symbol-tag 1 "fillme" "::")) __all__.append('Documentation')
[docs]class Documentation(pyjsmo.PyJsMo): # ||:cls:|| r""" >>> _docs = Documentation() >>> _docs.register(Document((1, 'doc_snippet_test.rst', DOC_SNIPPET_TEST))) True >>> _docs.dump_snippets(file=sys.stdout) .. .. -------------------------------------------------- .. \|<-snip->| Labeled Section | Labeled Section Label -------------------------------------------------- :rem:`||:sec:||`\ Labeled Section -------------------------------------------------- Section body filled with labeled stuff. Section body filled with labeled stuff. Section body filled with labeled stuff. <BLANKLINE> field: value field: value .. .. -------------------------------------------------- .. \|<-snip->| - Unlabeled Section -------------------------------------------------- :rem:`||:sec:||`\ Unlabeled Section -------------------------------------------------- Section body filled with unlabeled stuff. Section body filled with unlabeled stuff. Section body filled with unlabeled stuff. .. .. -------------------------------------------------- .. \|<-snip->| named paragraph Section body filled with named stuff. Section body filled with named stuff. Section body filled with named stuff. .. .. -------------------------------------------------- .. \|<-snip->| item 1 some item <BLANKLINE> item body filled with stuff. item body filled with stuff. .. .. -------------------------------------------------- .. \|<-snip->| item 2 some indented item <BLANKLINE> indented item body filled with stuff. indented item body filled with stuff. """ _pyjsmo_versions = [ (1, {'bases': [0], 'order': ['format', 'docs', 'includes', 'snippets'], 'defaults': OrderedDict(( ('format', None), ('docs', []), ('includes', []), ('snippets', OrderedDict()), )), 'amap': [], 'expand': None, }), ] def __init__(self, *args, **kwargs): # |:mth:| super(Documentation, self).__init__(*args, **kwargs)
[docs] def register(self, doc_or_filename, include=None): # |:mth:| r""" :returns: self for chaining. """ if isstring(doc_or_filename): _doc = Document((1, doc_or_filename)) else: _doc = doc_or_filename if include: self.includes.append(_doc) else: self.docs.append(_doc) snippets = self.snippets _doc.register_snippets_with(snippets, include) return True
[docs] def dump_snippets(self, file=None): # |:mth:| r""" :returns: self for chaining. """ if file is None: file = sys.stderr _seen = set() for _key, _snip in ditems(self.snippets): if _snip in _seen: continue _seen.add(_snip) printf('..', file=file) printf(".. --------------------------------------------------", file=file) _snip.dump(file=file)
[docs] def resolve(self, snippets=None, continued=None): # |:mth:| r"""Resolve snippets in all registered documents. """ if snippets is None: snippets = self.snippets if not continued: for _snippet in dvalues(snippets): _snippet.reset() for _doc in self.docs: _doc.resolve(snippets)
# (progn (forward-line -1) (insert "\n") (snip-insert "py.s.meth" t t "py") (backward-symbol-tag 1 "fillme" "::")) # (progn (forward-line -2) (insert "\n") (snip-insert "py.s.property" t t "py") (backward-symbol-tag 1 "fillme" "::")) # (progn (forward-line -1) (insert "\n") (snip-insert "py.s.meth" t t "py") (backward-symbol-tag 1 "fillme" "::")) # (progn (forward-line -2) (insert "\n") (snip-insert "py.s.property" t t "py") (backward-symbol-tag 1 "fillme" "::")) # (progn (forward-line -1) (insert "\n") (snip-insert "py.s.class" t t "py") (backward-symbol-tag 1 "fillme" "::")) # -------------------------------------------------- # |||:sec:||| FUNCTIONS # -------------------------------------------------- # (progn (forward-line 1) (snip-insert "py_f.search_path" t t "python" " --key xwith_docstrings --key xwith_all_append") (insert "\n")) class SimpleSubst(object): # ||:cls:|| def __init__(self): self.replacements = dict() def add(self, placeholder, replacement): self.replacements[placeholder] = replacement def replace(self, string): while True: _string = string for _ph, _rp in ditems(self.replacements): string = string.replace(_ph, _rp) if _string == string: break return string def search_path_expand(search_path, replacements=None, reverse=None): # ||:fnc:|| if replacements is None: replacements = SimpleSubst() x_search_path = [] for _sd in (replacements.replace(_d) for _d in reversed(search_path)): if _sd not in x_search_path: x_search_path.append(_sd) if not reverse: return list(reversed(x_search_path)) return x_search_path def search_candidates(search_path, files): # ||:fnc:|| candidates = [] for _file in files: if not os.path.isabs(_file): _candidates = [os.path.join(_sd, _file) for _sd in search_path] else: _candidates = [_file] for _candidate in _candidates: if _candidate not in candidates: candidates.append(_candidate) return candidates def search_files(search_path, files): # ||:fnc:|| return [_file for _file in search_candidates(search_path, files) if os.path.exists(_file)] def search_first(search_path, file_): # ||:fnc:|| try: return search_files(search_path, [file_])[0] except IndexError: return None def search_last(search_path, file_): # ||:fnc:|| try: return search_files(search_path, [file_])[-1] except IndexError: return None # (progn (forward-line -1) (insert "\n") (snip-insert "py.s.func" t t "py") (backward-symbol-tag 1 "fillme" "::")) # (progn (forward-line 1) (snip-insert "py_wsrfid.customization" t t "python" " --key cust_delayed_skipx") (insert "\n")) # (progn (forward-line 1) (snip-insert "py_b.dba_setup_sql" t t "python") (insert "\n")) # (progn (forward-line 1) (snip-insert "py_b.dba_id_maps" t t "python") (insert "\n")) # (progn (forward-line 1) (snip-insert "py_b.dba_commands_init" t t "python") (insert "\n")) # (progn (forward-line 1) (snip-insert "py.wsrfid.module.route" t t "py") (insert "")) # -------------------------------------------------- # |||:sec:||| UTILITIES # -------------------------------------------------- # (progn (forward-line 1) (snip-insert "py.wsrfid.dispatch.request" t t "py") (insert "")) # (progn (forward-line 1) (snip-insert "py.f.findfile" t t "py") (insert "")) # (progn (forward-line 1) (snip-insert "py_f.add_prefix_indent" t t "python") (insert "\n")) # (progn (forward-line 1) (snip-insert "py.c.placeholder.template" t t "py") (insert "\n")) # (progn (forward-line 1) (snip-insert "py.c.key.hash.ordered.dict" t t "py") (insert "\n")) # (progn (forward-line 1) (snip-insert "py.c.progress" t t "py") (insert "\n")) # (progn (forward-line 1) (snip-insert "py.f.hl" t t "py") (insert "\n")) # (progn (forward-line 1) (snip-insert "py.f.single.quote" t t "py") (insert "\n")) def single_quote(string, enclose=True): if enclose: pfx="'" sfx="'" else: pfx='' sfx='' return ''.join((pfx, re.sub("'", """'\\''""", string), sfx)) # (progn (forward-line 1) (snip-insert "py.f.remove.match" t t "py") (insert "\n")) # (progn (forward-line 1) (snip-insert "py.f.printenv" t t "py") (insert "\n")) # (progn (forward-line 1) (snip-insert "py.f.uname.s" t t "py") (insert "\n")) # (progn (forward-line 1) (snip-insert "py_f.decoded_email_headers" t t "python") (insert "\n")) # (progn (forward-line 1) (snip-insert "py_f.print_utf8" t t "python") (insert "\n")) # (progn (forward-line 1) (snip-insert "py.f.printe" t t "py") (insert "")) def printe_(*args, **kwargs): kwargs['file'] = kwargs.get('file', sys.stderr) printf(*args, **kwargs) if 'printe' not in globals(): # or globals().get('_is_main_', (__name__ == '__main__')): printe = printe_ printd = printe_ printw = printe_ printx = printe_ # (progn (forward-line 1) (snip-insert "py.f.dbg.squeeze" t t "py") (insert "\n")) # (progn (forward-line 1) (snip-insert "py.f.dbg.indent" t t "py") (insert "\n")) # (progn (forward-line 1) (snip-insert "py.f.quick.dump" t t "python") (insert "\n")) # (progn (forward-line 1) (snip-insert "py_b.all.reverse" t t "python") (insert "\n")) if '__all_internal__' in globals(): import sys if 'sphinx.directives' in sys.modules: __all__[:0] = __all_internal__ __all_internal__ = list(reversed(__all_internal__)) __all__ = list(reversed(__all__)) def run(parameters): # ||:fnc:|| """Application runner, when called as __main__.""" # (progn (forward-line 1) (snip-insert "py.bf.sql.ws" t t "py") (insert "\n")) # (progn (forward-line 1) (snip-insert "py.bf.file.arg.loop" t t "py") (insert "\n")) documentation = Documentation() _rc_files = [] if not parameters.no_defaults: _rc_files.extend(RC_FILES) _rc_files.extend(parameters.config) if parameters.args: input_file_dir = os.path.dirname(parameters.args[0]) or '.' else: input_file_dir = '.' here = '.' # |||:here:||| _path_replacements = pyjsmo.tags.SubstAt() _path_replacements.add('input_file_dir', os.path.abspath(input_file_dir)) _path_replacements.add('here', os.path.abspath(here)) search_path_rc = search_path_expand(SEARCH_PATH_RC, _path_replacements) rc_files = search_candidates(search_path_rc, _rc_files) search_path_doc = search_path_expand(SEARCH_PATH_DOC, _path_replacements, True) if _debug: printe(sformat("# "":DBG: {1:<{0}s}: ]{2!s}[", dbg_fwid, "search_path_rc", (search_path_rc))) printe(sformat("# "":DBG: {1:<{0}s}: ]{2!s}[", dbg_fwid, "search_path_doc", (search_path_doc))) printe(sformat("# "":DBG: {1:<{0}s}: ]{2!s}[", dbg_fwid, "_rc_files", (_rc_files))) printe(sformat("# "":DBG: {1:<{0}s}: ]{2!s}[", dbg_fwid, "rc_files", (rc_files))) CFG = config_from_rc_files(rc_files, cfg=LConfigParser()) CFGS = CFG['DEFAULT'] # |||:here:||| opt_force = parameters.force if opt_force is None: opt_force = trans_bool_int(CFGS.get('force', 0)) opt_format = parameters.format if opt_format is None: opt_format = CFGS.get('format', None) if opt_format is None: opt_format = '{dir}/{base}-x{ext}' def split_non_blank_lines(value): return [_l for _l in value.strip().splitlines() if _l.strip()] opt_include = [] opt_include.extend(parameters.include) opt_include.extend(split_non_blank_lines(CFGS.get('include', ''))) opt_replace = [] opt_replace.extend(split_non_blank_lines(CFGS.get('replace', ''))) opt_replace.extend(parameters.replace) replacements = pyjsmo.tags.SubstAt() if _debug: printe(sformat("# "":DBG: {1:<{0}s}: ]{2!s}[", dbg_fwid, "opt_replace", (opt_replace))) for _replace_def in opt_replace: try: _what, _with = _replace_def.split('=', 1) except ValueError: printe(sformat("# ||"":ERR:|| error: invalid replacement definition `{0}` in `{1}`", _replace_def, opt_replace)) return 1 replacements.add(_what, _with) filenames = parameters.args if len(filenames) == 0: filenames.append('-') for _filename in opt_include: if not documentation.register( search_first(search_path_doc, _filename) or _filename, include=True): continue for _filename in filenames: if not documentation.register(_filename): continue # |:here:| documentation.resolve() if _debug: printe("# --------------------------------------------------") printe(sformat("# ||"":sec:|| Snippets{0}", "")) printe("# --------------------------------------------------") documentation.dump_snippets() printe("# --------------------------------------------------") printe(sformat("# |||"":LOG:||| {date} Resolved{0}", "", date=datetime.datetime.now())) printe("# --------------------------------------------------") for _doc in documentation.docs: _path = _doc.filename _dir = os.path.dirname(_path) or '.' _file = os.path.basename(_path) _base, _ext = os.path.splitext(_file) _sbase, _sext = os.path.splitext(_base) _kwargs = dict(( ('path', _path), ('file', _file), ('dir', _dir), ('base', _base), ('ext', _ext), ('sbase', _sbase), ('sext', _sext), )) output_name = sformat(opt_format, **_kwargs) if _debug: printe("# --------------------------------------------------") printe(sformat("# ||"":sec:|| Document `{0}` => `{1}`", _doc.filename, output_name)) printe("# --------------------------------------------------") doc_text = replacements.replace(str(_doc.resolved.sections)) if output_name == '-': printf(doc_text) else: if not opt_force and os.path.exists(output_name): printe(sformat("# ||"":ERR:|| error: output file `{0}` exists", output_name)) continue with open(output_name, 'w') as _fh: printf(doc_text, file=_fh) if parameters.convert: _cmd = sformat("sphinx-readme.sh --format {0} {1}", parameters.convert, single_quote(output_name)) os.system(_cmd) #printe(sformat("# "":DBG: {1:<{0}s}: ]{2!s}[", dbg_fwid, "DONE", ('DONE'))) # |||:here:||| # (progn (forward-line 1) (snip-insert "py.wsrfid.wsuvv.run" t t "py" " --key py_wsrfid.wsuvv_run --key skip_for_new") (insert "\n")) # (progn (forward-line 1) (snip-insert "py_shell.run" t t "python") (insert "\n")) # from pyjsmo.result import Result, IResult, ERR_NONE # result = IResult() # |:here:| return # result.report() # return max(result.error, ERR_NONE) # -------------------------------------------------- # |||:sec:||| MAIN # -------------------------------------------------- _quiet = False _verbose = False _debug = False # (progn (forward-line 1) (snip-insert "py_f.argparse_callbacks" t t "python") (insert "\n")) _argparse_have_sub_commands = False def _argparse_begin(parser, context=None): # ||:fnc:|| r""" :returns: parser """ if context is None: context = globals() # |:here:| parser.add_argument( '--force', action='store_true', default=None, help='overwrite existing files.') parser.add_argument( '--no-defaults', action='store_true', default=None, help='do not read default configuration files.') parser.add_argument( '-c', '--config', action='append', type=str, metavar='CFG', default=[], help='add file to list of configuration files.') parser.add_argument( '-i', '--include', action='append', type=str, metavar='INC', default=[], help='add include document to parse for snippets.' ' The document is not resolved.') parser.add_argument( '-r', '--replace', action='append', type=str, metavar='REPL', default=[], help='add replacement `WHAT=WITH`.' ' `@WHAT@` is replaced with `WITH` after resolving snippets.') parser.add_argument( '-f', '--format', action='store', type=str, metavar='FMT', default=None, help='format for output documents.' ' Default: `{dir}/{base}-x{ext}`.' ' Placeholders: `path`, `dir`, `file`, `base`, `ext`, `sext`.' ' If format is `-`, standard output is used.') parser.add_argument( '--html', action='store_const', const='singlehtml', dest='convert', default=None, help='convert to HTML with sphinx-readme.sh(1)') parser.add_argument( '--pdf', action='store_const', const='pdf', dest='convert', default=None, help='convert to PDF with sphinx-readme.sh(1)') return parser def _argparse_end(parser, context=None): # ||:fnc:|| r""" :returns: parser """ if context is None: context = globals() # |:here:| return parser # (progn (forward-line 1) (snip-insert "py_main.py" t t "python") (insert "\n")) # (progn (forward-line 1) (snip-insert "py.f.setdefaultencoding" t t "py") (insert "\n")) #file_encoding_is_clean = False def setdefaultencoding(encoding=None, quiet=False, context=None): if context is None: context = globals() if context.get('file_encoding_is_clean'): return if encoding is None: encoding='utf-8' try: isinstance('', basestring) if not hasattr(sys, '_setdefaultencoding'): if not quiet: printf('''\ Add this to /etc/python2.x/sitecustomize.py, or put it in local sitecustomize.py and adjust PYTHONPATH=".:${PYTHONPATH}":: try: import sys setattr(sys, '_setdefaultencoding', getattr(sys, 'setdefaultencoding')) except AttributeError: pass Running with reload(sys) hack ... ''', file=sys.stderr) reload(sys) setattr(sys, '_setdefaultencoding', getattr(sys, 'setdefaultencoding')) sys._setdefaultencoding(encoding) except NameError: # python3 already has utf-8 default encoding ;-) pass def main(argv=None, context=None): # ||:fnc:|| if argv is None: argv = sys.argv if context is None: context = globals() context.get( 'setup_logger', globals().get( 'setup_logger', lambda *args: None))(context, True) try: import argparse except ImportError: printe('error: argparse missing. Try `easy_install argparse`.') sys.exit(1) parser = argparse.ArgumentParser(add_help=False) # parser.add_argument('--sum', dest='accumulate', action='store_const', # const=sum, default=max, # help='sum the integers (default: find the max)') # |:opt:| add options context.get('_argparse_begin', lambda _p, *_args: _p)(parser, context) parser.add_argument( '-q', '--quiet', action='store_const', const=-2, dest='debug', default=0, help='suppress warnings') parser.add_argument( '-v', '--verbose', action='store_const', const=-1, dest='debug', default=0, help='verbose test output') parser.add_argument( '-d', '--debug', nargs='?', action='store', type=int, metavar='NUM', default = 0, const = 1, help='show debug information') parser.add_argument( '-t', '--test', action='store_true', help='run doc tests') class AdHocAction(argparse.Action): options = ('implode', 'setup', 'explode', 'extract', 'template', 'eide') def __call__(self, parser, namespace, values, option_string=None): for _opt in self.options: setattr(namespace, 'adhoc_' + _opt, False) setattr(namespace, 'adhoc_' + option_string[2:], True) setattr(namespace, 'adhoc_arg', values) parser.add_argument( '--implode', nargs=0, action=AdHocAction, dest='adhoc_implode', default=False, help='implode script with adhoc') parser.add_argument( '--setup', nargs='?', action=AdHocAction, type=str, metavar='install', dest='adhoc_setup', default=False, const='install', help='explode script into temporary directory and call' ' `python setup.py install`') parser.add_argument( '--explode', nargs='?', action=AdHocAction, type=str, metavar='DIR', dest='adhoc_explode', default=False, const='__adhoc__', help='explode script with adhoc in directory DIR' ' (default: `__adhoc__`)') parser.add_argument( '--extract', nargs='?', action=AdHocAction, type=str, metavar='DIR', dest='adhoc_extract', default=False, const = '.', help='extract files to directory DIR (default: `.`)') parser.add_argument( '--template', nargs='?', action=AdHocAction, type=str, metavar='NAME', dest='adhoc_template', default=False, const = '-', help='extract named template to standard output. default NAME is ``-``') parser.add_argument( '--eide', nargs='?', action=AdHocAction, type=str, metavar='COMM', dest='adhoc_eide', default=False, const = '', help='Emacs IDE template list (implies --template list).') parser.add_argument( '-h', '--help', action='store_true', help="display this help message") parser.add_argument( '--ap-help', action='store_true', help="internal help message") context.get('_argparse_end', lambda _p, *_args: _p)(parser, context) if not context.get('_argparse_have_sub_commands'): # all options and arguments are known # all non-option arguments are consumed by `_parameters.args` parser.add_argument( 'args', nargs='*', metavar='arg', #'args', nargs='+', metavar='arg', #type=argparse.FileType('r'), default=sys.stdin, help='a series of arguments') _parameters = parser.parse_args(argv[1:]) else: # (progn (forward-line 1) (snip-insert "py_f.args_split_range" t t "python") (insert "\n")) def args_split_range(args): next_range = [] for arg in args: next_range.append(arg) if not arg.startswith('-'): break if next_range and not next_range[0].startswith('-'): next_range = [] return next_range, args[len(next_range):] # for sub-commands with their own options: pre-parse to first # non-option argument _parameters = None args = argv[1:] while True: next_range, args = args_split_range(args) if not next_range and not _parameters is None: break _parameters, unknown_args = parser.parse_known_args(next_range, _parameters) if unknown_args: unknown_args.extend(args) args = unknown_args next_range = [] break _parameters.args = args # generate argparse help if _parameters.ap_help: parser.print_help() return 0 # standard help if _parameters.help: help_ = re.sub('\n+[.][.] _END_OF_HELP.*(?s)', '', context['__doc__']) sys.stdout.write(help_ + '\n') return 0 context['_debug'] = _parameters.debug if context['_debug'] > 0: context['_verbose'] = True context['_quiet'] = False elif context['_debug'] < 0: context['_verbose'] = (context['_debug'] == -1) context['_quiet'] = not(context['_verbose']) context['_debug'] = 0 _parameters.debug = context['_debug'] _parameters.verbose = context['_verbose'] _parameters.quiet = context['_quiet'] if context['_debug']: cmd_line = argv sys.stderr.write(sformat( "{0}{3:^{1}} {4:<{2}s}: ]{5!s}[\n", context.get('dbg_comm', '# '), context.get('dbg_twid', 11), context.get('dbg_fwid', 15), ':DBG:', 'cmd_line', cmd_line)) # at least use `quiet` to suppress the setdefaultencoding warning setdefaultencoding(quiet=context['_quiet'] or _parameters.test) # |:opt:| handle options # adhoc: implode/setup/explode/extract adhoc_get_opt = lambda opt: getattr( _parameters, 'adhoc_' + opt, None) adhoc_op = sum(((adhoc_get_opt(_opt) and 1) or 0 for _opt in AdHocAction.options)) if adhoc_op: for _opt in AdHocAction.options: setattr(_parameters, _opt, adhoc_get_opt(_opt)) adhoc_export = ( _parameters.setup or _parameters.explode or _parameters.extract) file_ = context['__file__'] source = None have_adhoc = 'AdHoc' in context have_rt_adhoc = 'RtAdHoc' in context # shall adhoc be imported if _parameters.implode or not have_rt_adhoc: # shall this file be compiled adhoc_compile = not (have_rt_adhoc) os_path = os.defpath for pv in ('PATH', 'path'): try: os_path = os.environ[pv] break except KeyError: pass os_path = os_path.split(os.pathsep) for path_dir in os_path: if not path_dir: continue if path_dir not in sys.path: sys.path.append(path_dir) if not have_adhoc: try: import adhoc context['AdHoc'] = adhoc.AdHoc except ImportError: adhoc_compile = False try: from rt_adhoc import RtAdHoc as Adhoc context['AdHoc'] = AdHoc except ImportError: pass else: adhoc_compile = False context['AdHoc'] = context['RtAdHoc'] AdHoc = context['AdHoc'] AdHoc.quiet = context['_quiet'] AdHoc.verbose = context['_verbose'] AdHoc.debug = context['_debug'] AdHoc.include_path.append(os.path.dirname(file_)) AdHoc.extra_templates = [ ] AdHoc.template_process_hooks = { } if _parameters.eide: AdHoc.tt_ide = True AdHoc.tt_comment = _parameters.adhoc_arg or '' AdHoc.tt_prefix = '. (shell-command "' AdHoc.tt_suffix = '")' _parameters.template = True _parameters.adhoc_arg = 'list' if adhoc_compile: ah = AdHoc() source = ah.compileFile(file_) else: file_, source = AdHoc.std_source_param(file_) # implode if _parameters.implode: # @:adhoc_enable:@ # if not context['_quiet']: # map(sys.stderr.write, # ["warning: ", os.path.basename(file_), # " already imploded!\n"]) # @:adhoc_enable:@ AdHoc.write_source('-', source) # explode elif _parameters.setup or _parameters.explode: _here = os.path.abspath('.') _clean_dir = False AdHoc.export_dir = _parameters.adhoc_arg if _parameters.setup: import tempfile _clean_dir = True AdHoc.export_dir = tempfile.mkdtemp('_setup', '__adhoc__') try: AdHoc.export(file_, source) if _parameters.setup: sq = lambda string: ''.join(("'", re.sub("'", """'\\''""", string), "'")) os.chdir(AdHoc.export_dir) os.system(sformat('{0} setup.py {1}', sq(sys.executable), sq(_parameters.adhoc_arg))) finally: if _clean_dir: try: os.chdir(_here) except: pass import shutil shutil.rmtree(AdHoc.export_dir) # extract elif _parameters.extract: AdHoc.extract_dir = _parameters.adhoc_arg AdHoc.extract(file_, source) # template elif _parameters.template: template_name = _parameters.adhoc_arg if not template_name: template_name = '-' if template_name == 'list': sys.stdout.write( '\n'.join(AdHoc.template_table(file_, source)) + '\n') else: template = AdHoc.get_named_template( template_name, file_, source) AdHoc.write_source('-', template) # restore for subsequent calls to main if not have_adhoc: del(AdHoc) return 0 # run doc tests if _parameters.test: import warnings warnings.simplefilter('default') import doctest # for :file:`__init__.py`, :func:`_canonize_module_` does not register the module in `sys.modules`. _module_name = context['__name__'] context.get('_canonize_module_', globals().get( '_canonize_module_', lambda *args: None))(context['__name__'], context['__name__'] == '__main__') if context['__name__'] not in sys.modules: sys.modules[context['__name__']] = sys.modules[_module_name] try: logger = logging.getLogger() logger.setLevel(logging.DEBUG) except NameError: pass context.get('_doctest_hook_', lambda *args, **kwargs: None)(context) result = doctest.testmod(sys.modules[context['__name__']], verbose = context['_verbose']) return result.failed # |:opt:| handle options final = False ecode = 0 try: try: ecode = context['run'](_parameters) except IOError: (t, e, tb) = sys.exc_info() del(tb) # ignore SIGPIPE import errno if e.errno != errno.EPIPE: raise except SystemExit: raise except: # |:info:| this is used, since module cgitb does not work so well ... (t, e, tb) = sys.exc_info() if not final or context['_debug']: import traceback printf(''.join(traceback.format_tb(tb)), file=sys.stderr, end='') printf(sformat('{0}: {1}', t.__name__, e), file=sys.stderr) del(tb) ecode = 1 return ecode if globals().get('_is_main_', (__name__ == '__main__')): #sys.argv.insert(1, '--debug') # |:debug:| result = main(sys.argv, globals()) sys.exit(result) # |:here:| # (progn (forward-line 1) (snip-insert "py.t.ide" t t "py") (insert "\n")) # # :ide-menu: Emacs IDE Main Menu - Buffer @BUFFER@ # . M-x `eIDE-menu' (eIDE-menu "z") # :ide: CSCOPE ON # . (cscope-minor-mode) # :ide: CSCOPE OFF # . (cscope-minor-mode (quote ( nil ))) # :ide: TAGS: forced update # . (compile (concat "cd /home/ws/project/ws-rfid && make -k FORCED=1 tags")) # :ide: TAGS: update # . (compile (concat "cd /home/ws/project/ws-rfid && make -k tags")) # :ide: +-#+ # . Utilities () # :ide: TOC: Generate TOC with py-toc.py # . (progn (save-buffer) (compile (concat "py-toc.py ./" (file-name-nondirectory (buffer-file-name)) " "))) # :ide: CMD: Fold region with line continuation # . (shell-command-on-region (region-beginning) (region-end) "fold --spaces -width 79 | sed 's, $,,;1!s,^, ,;$!s,$,\\\\,'" nil nil nil t) # :ide: CMD: Fold region and replace with line continuation # . (shell-command-on-region (region-beginning) (region-end) "fold --spaces --width 79 | sed 's, $,,;1!s,^, ,;$!s,$,\\\\,'" t nil nil t) # :ide: +-#+ # . Fold () # :ide: CMD: Remove 8 spaces and add `>>> ' to region # . (shell-command-on-region (region-beginning) (region-end) "sed 's,^ ,,;/^[ ]*##/d;/^[ ]*#/{;s,^ *# *,,p;d;};/^[ ]*$/!s,^,>>> ,'" nil nil nil t) # :ide: CMD: Remove 4 spaces and add `>>> ' to region # . (shell-command-on-region (region-beginning) (region-end) "sed 's,^ ,,;/^[ ]*##/d;/^[ ]*#/{;s,^ *# *,,p;d;};/^[ ]*$/!s,^,>>> ,'" nil nil nil t) # :ide: +-#+ # . Doctest () # :ide: LINT: Check 80 column width ignoring IDE Menus # . (let ((args " | /srv/ftp/pub/check-80-col.sh -")) (compile (concat "sed 's,^\\(\\|. \\|.. \\|... \\)\\(:ide\\|[.] \\).*,,' " (buffer-file-name) " " args " | sed 's,^-," (buffer-file-name) ",'"))) # :ide: LINT: Check 80 column width # . (let ((args "")) (compile (concat "/srv/ftp/pub/check-80-col.sh " (buffer-file-name) " " args))) # :ide: +-#+ # . Lint Tools () # :ide: DELIM: @: SYM :@ @:fillme:@ adhoc tag # . (symbol-tag-normalize-delimiter (cons (cons nil "@:") (cons ":@" nil)) t) # :ide: +-#+ # . Delimiters () # :ide: COMPILE: Run with --ap-help # . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --ap-help"))) # :ide: COMPILE: Run with --help # . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --help"))) # :ide: COMPILE: Run with --test # . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --test"))) # :ide: COMPILE: Run with --test --verbose # . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --test --verbose"))) # :ide: COMPILE: Run with --debug # . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --debug"))) # :ide: +-#+ # . Compile with standard arguments () # :ide: OCCUR-OUTLINE: Python Source Code # . (x-symbol-tag-occur-outline "sec" '("|||:" ":|||") (cons (cons "^\\([ \t\r]*\\(def\\|class\\)[ ]+\\|[A-Za-z_]?\\)" nil) (cons nil "\\([ \t\r]*(\\|[ \t]*=\\)"))) # :ide: MENU-OUTLINE: Python Source Code # . (x-eIDE-menu-outline "sec" '("|||:" ":|||") (cons (cons "^\\([ \t\r]*\\(def\\|class\\)[ ]+\\|[A-Za-z_]?\\)" nil) (cons nil "\\([ \t\r]*(\\|[ \t]*=\\)"))) # :ide: +-#+ # . Outline () # :ide: INFO: SQLAlchemy - SQL Expression Language - Reference # . (let ((ref-buffer "*sqa-expr-ref*")) (if (not (get-buffer ref-buffer)) (shell-command (concat "w3m -dump -cols " (number-to-string (1- (window-width))) " 'http://www.sqlalchemy.org/docs/05/reference/sqlalchemy/expressions.html'") ref-buffer) (display-buffer ref-buffer t))) # :ide: INFO: SQLAlchemy - SQL Expression Language - Tutorial # . (let ((ref-buffer "*sqa-expr-tutor*")) (if (not (get-buffer ref-buffer)) (shell-command (concat "w3m -dump -cols " (number-to-string (1- (window-width))) " 'http://www.sqlalchemy.org/docs/05/sqlexpression.html'") ref-buffer) (display-buffer ref-buffer t))) # :ide: INFO: SQLAlchemy - Query # . (let ((ref-buffer "*sqa-query*")) (if (not (get-buffer ref-buffer)) (shell-command (concat "w3m -dump -cols " (number-to-string (1- (window-width))) " 'http://www.sqlalchemy.org/docs/orm/query.html'") ref-buffer) (display-buffer ref-buffer t))) # :ide: +-#+ # . SQLAlchemy Reference () # :ide: INFO: Python - argparse # . (let ((ref-buffer "*python-argparse*")) (if (not (get-buffer ref-buffer)) (shell-command (concat "w3m -dump -cols " (number-to-string (1- (window-width))) " 'http://docs.python.org/library/argparse.html'") ref-buffer) (display-buffer ref-buffer t))) # :ide: INFO: Python Documentation # . (let ((ref-buffer "*w3m*")) (if (get-buffer ref-buffer) (display-buffer ref-buffer t)) (other-window 1) (w3m-goto-url "http://docs.python.org/index.html" nil nil)) # :ide: INFO: Python Reference # . (let* ((ref-buffer "*python-ref*") (local "/home/ws/project/ws-util/python/reference/PQR2.7.html") (url (or (and (file-exists-p local) local) "'http://rgruet.free.fr/PQR27/PQR2.7.html'"))) (unless (get-buffer ref-buffer) (get-buffer-create ref-buffer) (with-current-buffer ref-buffer (shell-command (concat "snc txt.py.reference 2>/dev/null") ref-buffer) (goto-char (point-min)) (if (eobp) (shell-command (concat "w3m -dump -cols " (number-to-string (1- (window-width))) " " url) ref-buffer)))) (display-buffer ref-buffer t)) # :ide: +-#+ # . Python Reference () # :ide: COMPILE: Run with --eide # . (progn (save-buffer) (shell-command (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --eide") (concat "*templates: " (file-name-nondirectory (buffer-file-name)) "*"))) # :ide: COMPILE: Run with python3 --test # . (progn (save-buffer) (compile (concat "python3 ./" (file-name-nondirectory (buffer-file-name)) " --test"))) # :ide: COMPILE: Run with python3 w/o args # . (progn (save-buffer) (compile (concat "python3 ./" (file-name-nondirectory (buffer-file-name)) " "))) # :ide: COMPILE: Run w/o args # . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " "))) # :ide: COMPILE: Run with --debug --force --replace 'user=Max Benutzer' --replace 'user_short=mb' --replace 'hostname_pfx=laptop-' --replace 'hostname=@hostname_pfx@@user_short@' ../README-document-snippets.txt # . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --debug --force --replace 'user=Max Benutzer' --replace 'user_short=mb' --replace 'hostname_pfx=laptop-' --replace 'hostname=@hostname_pfx@@user_short@' ../README-document-snippets.txt"))) # :ide: COMPILE: Run with --force --replace 'user=Max Benutzer' --replace 'user_short=mb' --replace 'hostname_pfx=laptop-' --replace 'hostname=@hostname_pfx@@user_short@' ../README-document-snippets.txt # . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --force --replace 'user=Max Benutzer' --replace 'user_short=mb' --replace 'hostname_pfx=laptop-' --replace 'hostname=@hostname_pfx@@user_short@' ../README-document-snippets.txt"))) # :ide: COMPILE: Run with --test # . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --test"))) # :ide: COMPILE: Run with --debug=1 --force --config README-inst-tagideasy-station.rc --include README-stations.txt --format '{dir}/{base}-x.txt' '../../ws-admin/tagideasy/README-inst-tagideasy-station.src' # . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --debug=1 --force --config README-inst-tagideasy-station.rc --include README-stations.txt --format '{dir}/{base}-x.txt' '../../ws-admin/tagideasy/README-inst-tagideasy-station.src'"))) # :ide: +-#+ # . Compile () # # Local Variables: # mode: python # comment-start: "#" # comment-start-skip: "#+" # comment-column: 0 # truncate-lines: t # End: