Repository: roskakori/pygount (python)

Issue:
List for exceptions in the plain_text regex
Files like `CMakeLists.txt` fall into `pygount`'s plain_text reg-ex check, gets classified as `Text`, and counted as comment. We could modify the part [here](https://github.com/roskakori/pygount/blob/43137b40b4030c09cf64bb2a8da9efd50adcebab/pygount/analysis.py#L122) as,
```python
_STANDARD_PLAIN_TEXT_EXCEPTIONS = (
    "CMakeLists.txt",
)
_PLAIN_TEXT_PATTERN = "(?=(^" + "$)|(^".join(_STANDARD_PLAIN_TEXT_NAMES) + "$))" + "(?=(?!(^" + "$)|(^".join(_STANDARD_PLAIN_TEXT_EXCEPTIONS) + "$)))"
```
and fix this.

P.S. although this will make `CMakeLists.txt` count as code, it'll still get listed as `Text Only`. But that is a [bug in pygments/guess_lexer_for_filename](https://github.com/pygments/pygments/issues/523).

Pull request description:
#53 Improve text file detection
Close #53 .

Patch:
diff --git a/dev-requirements.txt b/dev-requirements.txt
index 5e7bf2b..4c21f46 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -2,10 +2,10 @@ black==19.10b0; python_version >= '3.6'
 chardet==3.0.4
 coverage==5.1
 coveralls==2.0.0
-pre-commit==2.5.1; python_version >= '3.6'  # pre-commit 2.1 requires Python 3.6+
+pre-commit==2.6.0; python_version >= '3.6'  # pre-commit 2.1 requires Python 3.6+
 pygments==2.6.1  # Pygments 2.5.0 changed Java's "{}" from Operator to Punctuation, earlier versions would break tests.
 pytest==5.4.3
 pytest-cov==2.10.0
-setuptools==47.3.1
-twine==3.1.1; python_version >= '3.6'  # twine 3.1 requires Python 3.6+
+setuptools==49.1.0
+twine==3.2.0; python_version >= '3.6'  # twine 3.1 requires Python 3.6+
 wheel==0.34.2
diff --git a/docs/changes.rst b/docs/changes.rst
index edd2c65..fd0a3de 100644
--- a/docs/changes.rst
+++ b/docs/changes.rst
@@ -5,7 +5,18 @@ Changes
 
 This chapter describes the changes coming with each new version of pygount.
 
-Version 1.2.1, 2020-06-24
+Version 1.2.3, 2020-07-05
+
+* Improved detection of text files by trying to guess a lexer for
+  :file:`*.txt` before assuming it is text. This basically fixes the detection
+  of :file:`CMakelists.txt` as CMake file
+  `#53 <https://github.com/roskakori/pygount/issues/53>`_). However, it will
+  only work with some files due to multiple issues with the regular expression
+  Pygments uses in versions up to 2.6.1 to detect CMake headers. This should
+  be fixed once pull request
+  `#1491 <https://github.com/pygments/pygments/pull/1491>`_ is applied.
+
+Version 1.2.2, 2020-06-24
 
 * Changed preprocessor statements to count as code, unlike Pygments which
   treats them as special comments (contributed by nkr0, issue
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 73c0b9b..df576e7 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,2 +1,2 @@
-Sphinx==2.4.4
-sphinx_rtd_theme==0.4.3
+Sphinx==3.1.2
+sphinx_rtd_theme==0.5.0
diff --git a/pygount/analysis.py b/pygount/analysis.py
index 770f10c..cd4a6d2 100644
--- a/pygount/analysis.py
+++ b/pygount/analysis.py
@@ -100,7 +100,7 @@ _BOM_TO_ENCODING_MAP = collections.OrderedDict(
 _XML_PROLOG_REGEX = re.compile(r'<\?xml\s+.*encoding="(?P<encoding>[-_.a-zA-Z0-9]+)".*\?>')
 _CODING_MAGIC_REGEX = re.compile(r".+coding[:=][ \t]*(?P<encoding>[-_.a-zA-Z0-9]+)\b", re.DOTALL)
 
-_STANDARD_PLAIN_TEXT_NAMES = (
+_STANDARD_PLAIN_TEXT_NAME_PATTERNS = (
     # Text files for (moribund) gnits standards.
     "authors",
     "bugs",
@@ -117,9 +117,8 @@ _STANDARD_PLAIN_TEXT_NAMES = (
     "readme\\.1st",
     "read\\.me",
     "todo",
-    ".*\\.txt",
 )
-_PLAIN_TEXT_PATTERN = "(^" + "$)|(^".join(_STANDARD_PLAIN_TEXT_NAMES) + "$)"
+_PLAIN_TEXT_PATTERN = "(^" + "$)|(^".join(_STANDARD_PLAIN_TEXT_NAME_PATTERNS) + "$)"
 #: Regular expression to detect plain text files by name.
 _PLAIN_TEXT_NAME_REGEX = re.compile(_PLAIN_TEXT_PATTERN, re.IGNORECASE)
 
@@ -129,6 +128,7 @@ _SUFFIX_TO_FALLBACK_LEXER_MAP = {
     "fex": pygount.lexers.MinimalisticWebFocusLexer(),
     "idl": pygount.lexers.IdlLexer(),
     "m4": pygount.lexers.MinimalisticM4Lexer(),
+    "txt": pygount.lexers.PlainTextLexer(),
     "vbe": pygount.lexers.MinimalisticVBScriptLexer(),
     "vbs": pygount.lexers.MinimalisticVBScriptLexer(),
 }
diff --git a/pygount/common.py b/pygount/common.py
index 75d32a6..603a25c 100644
--- a/pygount/common.py
+++ b/pygount/common.py
@@ -11,7 +11,7 @@ import warnings
 from typing import Generator, List, Optional, Pattern, Sequence, Union
 
 
-__version__ = "1.2.2"
+__version__ = "1.2.3"
 
 
 #: Pseudo pattern to indicate that the remaining pattern are an addition to the default patterns.
diff --git a/setup.py b/setup.py
index 7dabcd0..b1f426c 100644
--- a/setup.py
+++ b/setup.py
@@ -13,7 +13,7 @@ Upload release to PyPI::
 
   $ python3 setup.py bdist_wheel
   $ twine check dist/*.whl
-  $ twine upload --config-file ~/.pypyrc dist/*.whl
+  $ twine upload --config-file ~/.pypirc dist/*.whl
 """
 # Copyright (c) 2016-2020, Thomas Aglassinger.
 # All rights reserved. Distributed under the BSD License.


Test patch:
diff --git a/tests/test_analysis.py b/tests/test_analysis.py
index cdbaf25..fbd1957 100644
--- a/tests/test_analysis.py
+++ b/tests/test_analysis.py
@@ -231,6 +231,21 @@ def test_can_guess_lexer_for_plain_text():
     assert lexer.name == "Text"
 
 
+def test_can_guess_lexer_for_cmakelists():
+    source_code = "\n".join(
+        [
+            "cmake_minimum_required(VERSION 2.6)",
+            "project(example)",
+            "set(CMAKE_CXX_STANDARD 14)",
+            "set(SOURCE_FILES example.cpp)",
+            "add_executable(example ${SOURCE_FILES})",
+        ]
+    )
+    lexer = guess_lexer("CMakeLists.txt", source_code)
+    assert lexer is not None
+    assert lexer.name == "CMake"
+
+
 def test_can_use_deprecated_counts():
     source_analysis = analysis.SourceAnalysis("some.py", "Python", "some", 1, 2, 3, 4, analysis.SourceState.analyzed)
     assert source_analysis.code == source_analysis.code_count