Index: pluginconf/__init__.py ================================================================== --- pluginconf/__init__.py +++ pluginconf/__init__.py @@ -286,11 +286,11 @@ # Try via pkgutil first, # find any plugins.* modules, or main packages if module: search = plugin_base + kwargs.get("extra_base", []) - for base, sfx in itertools.product(search, [".py"]): + for base, sfx in itertools.product(search, [".py", "/__init__.py"]): try: #log.debug(f"mod={base} fn={filename}.py") src = get_data(filename=module+sfx, decode=True, file_root=base) if src: break @@ -361,10 +361,11 @@ } # Extract coherent comment block src = src.replace("\r", "") if not literal: + src = rx.header.sub("", src) src = rx.comment.search(src) if not src: log.warning("Couldn't read source meta information: %s", filename) return meta src = src.group(0) @@ -468,12 +469,25 @@ Pretty crude comment splitting approach. But works well enough already. Technically a YAML parser would do better; but is likely overkill. """ - comment = re.compile(r"""(^ {0,4}#.*\n)+""", re.M) - hash = re.compile(r"""(^ {0,4}#{1,2} {0,3}\r*)""", re.M) + header = re.compile(r""" + (\A ( + \#! \s+ /.+ | # shebang + <\?php .* + ) $)+ + """, re.M | re.X) + comment = re.compile(r""" + (^ [ ]{0,4} \# .*\n)+ | # general + (^ [ ]{0,4} // .*\n)+ | # C++-style + /\* [\s\S]+? \*/ | # C-multiline + <\# [\s\S]+? \#> | \{\# [\s\S]+? \#\} # PS/Perl + """, re.M | re.X) + hash = re.compile(r""" + (^ [ ]{0,4} [#*/]{1,2} [ ]{0,3}) + """, re.M | re.X) keyval = re.compile(r""" ^([\w-]+):(.*$(?:\n(?![\w-]+:).+$)*) # plain key:value lines """, re.M | re.X) config = re.compile(r""" \{ ((?: [^\{\}]+ | \{[^\}]*\} )+) \} # JSOL/YAML scheme {...} dicts ADDED test/config_altsyntax.py Index: test/config_altsyntax.py ================================================================== --- test/config_altsyntax.py +++ test/config_altsyntax.py @@ -0,0 +1,59 @@ +# type: test +# title: alternative syntaxes +# description: other comment types +# version: 0.7.8 +# +# Kinda have to do snippets here. + +import pytest +import re +import textwrap +import pluginconf + +def _parse(text): + text = re.sub(r"\A\n", "", text) + text = textwrap.dedent(text) + return pluginconf.plugin_meta(src=text) + + +def multiline_c(): + c_style= """ + /** + * api: c + * title: example + * version: 3.5.1 + * category: multiline + * + * Do we get a comment? + */ + """ + assert _parse(c_style).version == "3.5.1" + assert _parse(c_style).doc == "Do we get a comment?" + +def multiline_ps1(): + ps1_style= """ + <# + # api: cpp + # title: second + version: 2.1 + # category: nonpython + # + # Won't work without hashes + #> + """ + print(_parse(ps1_style)) + assert _parse(ps1_style).version == "2.1" + # requires adapting the continuation line detection (including spaced points) + # and detecting multiline markers, and stripping them (end up in doc else) + +def indent_cpp(): + cpp_style= """ + // api: cpp + // title: third + // version: 3.3 + // category: doubleprefix + // + // Basically just // instead of # + """ + assert _parse(cpp_style).version == "3.3" +