# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['eyecite']

package_data = \
{'': ['*']}

install_requires = \
['courts-db>=0.9.7,<0.10.0',
 'diff_match_patch_python>=1.0.2,<2.0.0',
 'lxml>=4.6.3,<5.0.0',
 'pyahocorasick>=1.2',
 'reporters-db>=3,<4']

setup_kwargs = {
    'name': 'eyecite',
    'version': '2.0.2',
    'description': 'Tool for extracting legal citations from text strings.',
    'long_description': 'eyecite\n==========\n\neyecite is an open source tool for extracting legal citations from text strings. Originally built for use with `Courtlistener.com <https://www.courtlistener.com/>`_, it is now a freestanding package.\n\nIts main purpose is to facilitate the conversion of raw text into structured citation entities. It includes mechanisms to recognize and extract "full" citation references (e.g., :code:`Bush v. Gore, 531 U.S. 98`), "short form" references (e.g., :code:`531 U.S., at 99`), "supra" references (e.g., :code:`Bush, supra, at 100`), "id." references (e.g., :code:`Id., at 101`), and "ibid." references (e.g., :code:`Ibid.`).\n\nFurther development is intended and all contributors, corrections, and additions are welcome.\n\nBackground\n==========\nThis project is the culmination of `years <https://free.law/2012/05/11/building-a-citator-on-courtlistener/>`_ `of <https://free.law/2015/11/30/our-new-citation-finder/>`_ `work <https://free.law/2020/03/05/citation-data-gets-richer/>`_ to build a citator within Courtlistener.com. This project represents the next step in that development: Decoupling the parsing logic and exposing it for third-party use as a standalone Python package.\n\nQuickstart\n==========\n\nSimply feed in a raw string of text (or HTML), and receive a list of structured citation objects, ordered in the sequence that they appear in the text.\n\n\n::\n\n    from eyecite import get_citations\n\n    text = \'bob lissner v. test 1 U.S. 12, 347-348 (4th Cir. 1982)\'\n    found_citations = get_citations(text)\n\n    returns:\n    [FullCaseCitation(plaintiff=\'lissner\', defendant=\'test\', volume=1,\n               reporter=\'U.S.\', page=\'12\', year=1982,\n               extra=\'347-348\', court=\'ca4\',\n               canonical_reporter=\'U.S.\', lookup_index=0,\n               token_index=5, reporter_found=\'U.S.\')]\n\n\nOptions\n=======\n:code:`get_citations()`, the main executable function, takes several parameters.\n\n1. :code:`do_post_citation` ==> bool; whether additional, post-citation information should be extracted (e.g., the court, year, and/or date range of the citation)\n2. :code:`do_defendant` ==> bool; whether the pre-citation defendant (and possibily plaintiff) reference should be extracted\n3. :code:`disambiguate` ==> bool; whether each citation\'s (possibly ambiguous) reporter should be resolved to its (unambiguous) form\n4. :code:`tokenizer` ==> Tokenizer; an instance of a Tokenizer object (see "Tokenizers" below)\n\nSome notes\n----------\nSome things to keep in mind are:\n\n1. This project depends on information made available in two other Free Law Project packages, `reporters-db <https://github.com/freelawproject/reporters-db>`_ and `courts-db <https://github.com/freelawproject/courts-db>`_.\n2. This package performs no matching or resolution action. In other words, it is up to the user to decide what to do with the "short form," "supra," "id.," and "ibid." citations that this tool extracts. In theory, these citations are all references to "full" citations also mentioned in the text -- and are therefore in principle resolvable to those citations -- but this task is beyond the scope of this parsing package. See `here <https://github.com/freelawproject/courtlistener/tree/master/cl/citations>`_ for an example of how Courtlistener implements this package and handles this problem.\n\n\nCleaning Input Text\n===================\n\nFor a given citation text such as "... 1 Baldwin\'s Rep. 1 ...", eyecite expects that the text\nwill be "clean" before being passed to :code:`get_citation`. This means:\n\n* Spaces will be single space characters, not multiple spaces or other whitespace.\n* Quotes and hyphens will be standard quote and hyphen characters.\n* No junk such as HTML tags inside the citation.\n\nYou can use :code:`clean_text` to help with this:\n\n::\n\n    from eyecite import clean_text, get_citations\n\n    source_text = \'<p>foo   1  U.S.  1   </p>\'\n    plain_text = clean_text(text, [\'html\', \'inline_whitespace\', my_func])\n    found_citations = get_citations(plain_text)\n\nSee the Annotating Citations section for how to insert links into the original text using\ncitations extracted from the cleaned text.\n\n:code:`clean_text` currently accepts these values as cleaners:\n\n1. :code:`inline_whitespace`: replace all runs of tab and space characters with a single space character\n2. :code:`all_whitespace`: replace all runs of any whitespace character with a single space character\n3. :code:`underscores`: remove two or more underscores, a common error in text extracted from PDFs\n4. :code:`html`: remove non-visible HTML content using the lxml library\n5. Custom function: any function taking a string and returning a string.\n\n\nAnnotating Citations\n====================\n\nFor simple plain text, you can insert links to citations using the :code:`annotate` function:\n\n::\n\n    from eyecite import get_citations, annotate\n\n    plain_text = \'bob lissner v. test 1 U.S. 12, 347-348 (4th Cir. 1982)\'\n    citations = get_citations(plain_text)\n    linked_text = annotate(plain_text, [[c.span(), "<a>", "</a>"] for c in citations])\n\n    returns:\n    \'bob lissner v. test <a>1 U.S. 12</a>, 347-348 (4th Cir. 1982)\'\n\nEach citation returned by get_citations keeps track of where it was found in the source text.\nAs a result, :code:`annotate` must be called with the *same* cleaned text used by :code:`get_citations`\nto extract citations. If you do not, the offsets returned by the citation\'s :code:`span` method will\nnot align with the text, and your annotations will be in the wrong place.\n\nIf you want to clean text and then insert annotations into the original text, you can pass\nthe original text in as :code:`source_text`:\n\n::\n\n    from eyecite import get_citations, annotate, clean_text\n\n    source_text = \'<p>bob lissner v. <i>test   1 U.S.</i> 12,   347-348 (4th Cir. 1982)</p>\'\n    plain_text = clean_text(source_text, [\'html\', \'inline_whitespace\'])\n    citations = get_citations(plain_text)\n    linked_text = annotate(plain_text, [[c.span(), "<a>", "</a>"] for c in citations], source_text=source_text)\n\n    returns:\n    \'<p>bob lissner v. <i>test   <a>1 U.S.</i> 12</a>,   347-348 (4th Cir. 1982)</p>\'\n\nThe above example extracts citations from :code:`plain_text` and applies them to\n:code:`source_text`, using a diffing algorithm to insert annotations in the correct locations\nin the original text.\n\nWrapping HTML Tags\n------------------\n\nNote that the above example includes mismatched HTML tags: "<a>1 U.S.</i> 12</a>".\nTo specify handling for unbalanced tags, use the :code:`unbalanced_tags` parameter:\n\n* :code:`unbalanced_tags="skip"`: annotations that would result in unbalanced tags will not be inserted.\n* :code:`unbalanced_tags="wrap"`: unbalanced tags will be wrapped, resulting in :code:`<a>1 U.S.</a></i><a> 12</a>`\n\n**Important:** :code:`unbalanced_tags="wrap"` uses a simple regular expression and will only work for HTML where\nangle brackets are properly escaped, such as the HTML emitted by :code:`lxml.html.tostring`. It is intended for\nregularly formatted documents such as case text published by courts. It may have\nunpredictable results for deliberately-constructed challenging inputs such as citations containing partial HTML\ncomments or :code:`<pre>` tags.\n\nCustomizing Annotation\n----------------------\n\nIf inserting text before and after isn\'t sufficient, supply a callable under the :code:`annotator` parameter\nthat takes :code:`(before, span_text, after)` and returns the annotated text:\n\n::\n\n    def annotator(before, span_text, after):\n        return before + span_text.lower() + after\n    linked_text = annotate(plain_text, [[c.span(), "<a>", "</a>"] for c in citations], annotator=annotator)\n\n    returns:\n    \'bob lissner v. test <a>1 u.s. 12</a>, 347-348 (4th Cir. 1982)\'\n\nTokenizers\n==========\n\nInternally, eyecite works by applying a list of regular expressions to the source text to convert it to a list\nof tokens:\n\n::\n\n    In [1]: from eyecite.tokenizers import default_tokenizer\n\n    In [2]: list(default_tokenizer.tokenize("Foo v. Bar, 123 U.S. 456 (2016). Id. at 457."))\n    Out[2]:\n    [\'Foo\',\n     StopWordToken(data=\'v.\', stop_word=\'v\'),\n     \'Bar,\',\n     CitationToken(data=\'123 U.S. 456\', volume=\'123\', reporter=\'U.S.\', page=\'456\' ...),\n     \'(2016).\',\n     IdToken(data=\'Id.\'),\n     \'at\',\n     \'457.\']\n\nTokens are then scanned to determine values like the citation year or case name for citation resolution.\n\nAlternate tokenizers can be substituted by providing a tokenizer instance to :code:`get_citations()`:\n\n::\n\n    from eyecite.tokenizers import HyperscanTokenizer\n    hyperscan_tokenizer = HyperscanTokenizer(cache_dir=\'.hyperscan\')\n    cites = get_citations(text, tokenizer=hyperscan_tokenizer)\n\ntest_FindTest.py includes a simplified example of using a custom tokenizer that uses modified\nregular expressions to extract citations with OCR errors.\n\neyecite ships with two tokenizers:\n\nAhocorasickTokenizer (default)\n------------------------------\n\nThe default tokenizer uses the pyahocorasick library to filter down eyecite\'s list of\nextractor regexes. It then performs extraction using the builtin :code:`re` library.\n\nHyperscanTokenizer\n------------------\n\nThe alternate HyperscanTokenizer compiles all extraction regexes into a hyperscan database\nso they can be extracted in a single pass. This is far faster than the default tokenizer\n(exactly how much faster depends on how many citation formats are included in the target text),\nbut requires the optional :code:`hyperscan` dependency that is limited to the x86 platform.\n\nCompiling the hyperscan database takes several seconds, so short-running scripts may want to\nprovide a cache directory where the database can be stored. The directory should be writeable\nonly by the user:\n\n::\n\n    hyperscan_tokenizer = HyperscanTokenizer(cache_dir=\'.hyperscan\')\n\nInstallation\n============\nInstalling eyecite is easy.\n\n\n::\n\n    poetry add eyecite\n\n\nOr via pip:\n\n::\n\n    sh\n    pip install eyecite\n\n\nOr install the latest dev version from github\n\n::\n\n    sh\n    pip install git+https://github.com/freelawproject/eyecite.git@master\n\n\n\nDeployment\n==========\n\n1. Update version info in :code:`pyproject.toml`.\n\nFor an automated deployment, tag the commit with vx.y.z, and push it to master.\nAn automated deploy will be completed for you.\n\nFor a manual deployment, run:\n\n::\n\n    sh\n    poetry publish --build\n\n\n\nTesting\n=======\neyecite comes with a robust test suite of different citation strings that it is equipped to handle. Run these tests as follows:\n\n::\n\n    python3 -m unittest discover -s tests -p \'test_*.py\'\n\nIf you would like to create mock citation objects to assist you in writing your own local tests, import and use the following functions for convenience:\n\n::\n\n    from eyecite.test_factories import (\n        case_citation,\n        id_citation,\n        nonopinion_citation,\n        supra_citation,\n    )\n\nLicense\n=======\nThis repository is available under the permissive BSD license, making it easy and safe to incorporate in your own libraries.\n\nPull and feature requests welcome. Online editing in GitHub is possible (and easy!).\n',
    'author': 'Free Law Project',
    'author_email': 'info@free.law',
    'maintainer': 'Free Law Project',
    'maintainer_email': 'info@free.law',
    'url': 'https://github.com/freelawproject/eyecite',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.7,<4.0',
}


setup(**setup_kwargs)
