# abstract_search

Standalone string search across files and directories with allow/exclude
filtering. Stdlib-only at import time — pdf, office, and spreadsheet readers
load lazily and are optional extras.

```python
from abstract_search import findContent

# search every readable file under a directory
hits = findContent("/path/to/project", strings=["needle"], get_lines=True)

# narrow by extension, merge extra excludes with the defaults
hits = findContent("/path/to/project", strings=["needle"],
                   allowed_exts="py", exclude_dirs="tests", add=True)

# exact multi-line match locations
locs = findContent("/path/to/project", strings=["def main(", "return"],
                   structured=True)
```

Filter semantics: passing a filter kwarg **replaces** its default set;
`add=True` **merges** with the defaults instead. Defaults skip
`node_modules`, `__pycache__`, backups, media/binary extensions, and
`__init__*` files (see `constants.py`).

```python
from abstract_search import make_allowed_predicate, filter_allowed_items, search_files

allowed = make_allowed_predicate(exclude_exts=".log", add=True)
kept = filter_allowed_items(paths, allowed_exts=[".py", ".md"])
hits = search_files("needle", "/path/to/project")   # line-level SearchHit records
```

Optional readers: `pip install abstract_search[pdf]` (pdfplumber),
`[ocr]`, `[xls]`, `[xlsb]`, `[dbf]`, `[parquet]`, or `[all]`.
