# Path: src/holocron/_processors/import_processors.py
# def process(app, items, *, imports, from_=None):
#     def passgen(app, items):
# 
# Path: src/holocron/_processors/when.py
# def _re_match(value, pattern, flags=0):
#     def __init__(self):
#     def eval(self, cond, **context):
# def process(app, stream, processor, *_condition, condition=None):
#     def smartstream():
# class _ConditionEvaluator:
# 
# Path: src/holocron/_core/application.py
# class Application:
#     """Application instance orchestrates processors execution."""
# 
#     _processor_reserved_props = {"name", "args"}
# 
#     def __init__(self, metadata=None):
#         # Metadata is a KV store shared between processors. It serves two
#         # purposes: first, metadata contains an application level data, and
#         # secondly, it's the only way to consume artifacts produced by one
#         # processor from another processor.
#         #
#         # ChainMap is used to prevent writes to original metadata mapping,
#         # and thus making it easier to distinguish initial metadata values
#         # from the one set by processors in the mid of troubleshooting.
#         self._metadata = collections.ChainMap({}, metadata or {})
# 
#         # Processors are (normally) stateless functions that receive an input
#         # stream of items and produce an output stream of items. This property
#         # keeps track of known processors, and is used to retrieve processors
#         # one someone asked to execute a pipe.
#         self._processors = {}
# 
#         # Processor wrappers are processors that somehow wrap another
#         # processor. They receive wrapped processor as input argument and are
#         # fully responsible to invoke it when necessary. The only reason why
#         # this special type of processors exists in the first place is because
#         # Holocron implements syntax sugar for them. Other than that, there is
#         # no difference indeed.
#         self._processor_wrappers = set()
# 
#         # Pipes are sets of processors connected in series, where the output
#         # of one processor is the input of the next one. This property keeps
#         # track of known pipes, and is used to execute processors in sequence
#         # when invoked.
#         self._pipes = {}
# 
#     @property
#     def metadata(self):
#         return self._metadata
# 
#     def add_processor(self, name, processor):
#         if name in self._processors:
#             _logger.warning("processor override: '%s'", name)
#         self._processors[name] = processor
# 
#     def add_processor_wrapper(self, name, processor):
#         if name in self._processor_reserved_props:
#             raise ValueError(f"illegal wrapper name: {name}")
# 
#         self.add_processor(name, processor)
#         self._processor_wrappers.add(name)
# 
#     def add_pipe(self, name, pipe):
#         if name in self._pipes:
#             _logger.warning("pipe override: '%s'", name)
#         self._pipes[name] = pipe
# 
#     def invoke(self, pipe, stream=None):
#         # A given 'pipe' may be either a pipe name or an actual
#         # pipe definition. That's why need this ugly type check because any
#         # string value is considered as a name. Passing an actual pipe is
#         # very handy in couple of use cases, such as running a sub pipe
#         # from some processor.
#         if isinstance(pipe, str):
#             if pipe not in self._pipes:
#                 raise ValueError(f"no such pipe: '{pipe}'")
#             pipe = self._pipes[pipe]
# 
#         # Since processors expect an input stream to be an iterator, we cast a
#         # given stream explicitly to an iterator even though everything will
#         # probably work even if it's not. We just want to respect and enforce
#         # established contracts.
#         stream = iter(stream or [])
# 
#         for processor in pipe:
#             # Resolve every JSON reference we encounter in a processor's
#             # parameters. Please note, we're doing this so late because we
#             # want to take into account metadata and other changes produced
#             # by previous processors in the pipe.
#             processor = _misc.resolve_json_references(
#                 processor, {"metadata:": self.metadata}
#             )
# 
#             name, args, kwargs = _unpack_and_wrap_processor(
#                 processor, self._processor_reserved_props
#             )
# 
#             if name not in self._processors:
#                 raise ValueError(f"no such processor: '{name}'")
# 
#             processfn = self._processors[name]
#             stream = processfn(self, stream, *args, **kwargs)
# 
#         yield from stream


from .._processors import import_processors, when
from . import Application
    # instance. This is, to be honest, the main purpose of this factory
    # function, because otherwise one must create an Application instance
    # directly.
    import_processors.process(
        instance,
        [],
        imports=[
            "archive = holocron._processors.archive:process",
            "chain = holocron._processors.chain:process",
            "commonmark = holocron._processors.commonmark:process",
            "feed = holocron._processors.feed:process",
            "frontmatter = holocron._processors.frontmatter:process",
            "import-processors = holocron._processors.import_processors:process",
            "jinja2 = holocron._processors.jinja2:process",
            "markdown = holocron._processors.markdown:process",
            "metadata = holocron._processors.metadata:process",
            "pipe = holocron._processors.pipe:process",
            "prettyuri = holocron._processors.prettyuri:process",
            "restructuredtext = holocron._processors.restructuredtext:process",
            "save = holocron._processors.save:process",
            "sitemap = holocron._processors.sitemap:process",
            "source = holocron._processors.source:process",
            "todatetime = holocron._processors.todatetime:process",
        ],
    )

    # When is the only known processor wrapper, and, frankly, we don't expect
    # more. Processor wrappers are mere hacks to avoid hardcoding yet provide
    # better syntax for wrapping processors. So let's hardcode that knowledge
    # here, and think later about general approach when the need arise.

# Path: src/holocron/_processors/import_processors.py
# def process(app, items, *, imports, from_=None):
#     def passgen(app, items):
# 
# Path: src/holocron/_processors/when.py
# def _re_match(value, pattern, flags=0):
#     def __init__(self):
#     def eval(self, cond, **context):
# def process(app, stream, processor, *_condition, condition=None):
#     def smartstream():
# class _ConditionEvaluator:
# 
# Path: src/holocron/_core/application.py
# class Application:
#     """Application instance orchestrates processors execution."""
# 
#     _processor_reserved_props = {"name", "args"}
# 
#     def __init__(self, metadata=None):
#         # Metadata is a KV store shared between processors. It serves two
#         # purposes: first, metadata contains an application level data, and
#         # secondly, it's the only way to consume artifacts produced by one
#         # processor from another processor.
#         #
#         # ChainMap is used to prevent writes to original metadata mapping,
#         # and thus making it easier to distinguish initial metadata values
#         # from the one set by processors in the mid of troubleshooting.
#         self._metadata = collections.ChainMap({}, metadata or {})
# 
#         # Processors are (normally) stateless functions that receive an input
#         # stream of items and produce an output stream of items. This property
#         # keeps track of known processors, and is used to retrieve processors
#         # one someone asked to execute a pipe.
#         self._processors = {}
# 
#         # Processor wrappers are processors that somehow wrap another
#         # processor. They receive wrapped processor as input argument and are
#         # fully responsible to invoke it when necessary. The only reason why
#         # this special type of processors exists in the first place is because
#         # Holocron implements syntax sugar for them. Other than that, there is
#         # no difference indeed.
#         self._processor_wrappers = set()
# 
#         # Pipes are sets of processors connected in series, where the output
#         # of one processor is the input of the next one. This property keeps
#         # track of known pipes, and is used to execute processors in sequence
#         # when invoked.
#         self._pipes = {}
# 
#     @property
#     def metadata(self):
#         return self._metadata
# 
#     def add_processor(self, name, processor):
#         if name in self._processors:
#             _logger.warning("processor override: '%s'", name)
#         self._processors[name] = processor
# 
#     def add_processor_wrapper(self, name, processor):
#         if name in self._processor_reserved_props:
#             raise ValueError(f"illegal wrapper name: {name}")
# 
#         self.add_processor(name, processor)
#         self._processor_wrappers.add(name)
# 
#     def add_pipe(self, name, pipe):
#         if name in self._pipes:
#             _logger.warning("pipe override: '%s'", name)
#         self._pipes[name] = pipe
# 
#     def invoke(self, pipe, stream=None):
#         # A given 'pipe' may be either a pipe name or an actual
#         # pipe definition. That's why need this ugly type check because any
#         # string value is considered as a name. Passing an actual pipe is
#         # very handy in couple of use cases, such as running a sub pipe
#         # from some processor.
#         if isinstance(pipe, str):
#             if pipe not in self._pipes:
#                 raise ValueError(f"no such pipe: '{pipe}'")
#             pipe = self._pipes[pipe]
# 
#         # Since processors expect an input stream to be an iterator, we cast a
#         # given stream explicitly to an iterator even though everything will
#         # probably work even if it's not. We just want to respect and enforce
#         # established contracts.
#         stream = iter(stream or [])
# 
#         for processor in pipe:
#             # Resolve every JSON reference we encounter in a processor's
#             # parameters. Please note, we're doing this so late because we
#             # want to take into account metadata and other changes produced
#             # by previous processors in the pipe.
#             processor = _misc.resolve_json_references(
#                 processor, {"metadata:": self.metadata}
#             )
# 
#             name, args, kwargs = _unpack_and_wrap_processor(
#                 processor, self._processor_reserved_props
#             )
# 
#             if name not in self._processors:
#                 raise ValueError(f"no such processor: '{name}'")
# 
#             processfn = self._processors[name]
#             stream = processfn(self, stream, *args, **kwargs)
# 
#         yield from stream


# Path: src/holocron/_core/factories.py
from .._processors import import_processors, when
from . import Application

    # instance. This is, to be honest, the main purpose of this factory
    # function, because otherwise one must create an Application instance
    # directly.
    import_processors.process(
        instance,
        [],
        imports=[
            "archive = holocron._processors.archive:process",
            "chain = holocron._processors.chain:process",
            "commonmark = holocron._processors.commonmark:process",
            "feed = holocron._processors.feed:process",
            "frontmatter = holocron._processors.frontmatter:process",
            "import-processors = holocron._processors.import_processors:process",
            "jinja2 = holocron._processors.jinja2:process",
            "markdown = holocron._processors.markdown:process",
            "metadata = holocron._processors.metadata:process",
            "pipe = holocron._processors.pipe:process",
            "prettyuri = holocron._processors.prettyuri:process",
            "restructuredtext = holocron._processors.restructuredtext:process",
            "save = holocron._processors.save:process",
            "sitemap = holocron._processors.sitemap:process",
            "source = holocron._processors.source:process",
            "todatetime = holocron._processors.todatetime:process",
        ],
    )

    # When is the only known processor wrapper, and, frankly, we don't expect
    # more. Processor wrappers are mere hacks to avoid hardcoding yet provide
    # better syntax for wrapping processors. So let's hardcode that knowledge
    # here, and think later about general approach when the need arise.

    instance.add_processor_wrapper("when", when.process)