codero 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- codero/__init__.py +15 -0
- codero/cli.py +60 -0
- codero/decider.py +30 -0
- codero/features/__init__.py +8 -0
- codero/features/horizontal.py +49 -0
- codero/features/result.py +30 -0
- codero/features/text.py +49 -0
- codero/finalize.py +50 -0
- codero/loc.py +167 -0
- codero/strategy/__init__.py +8 -0
- codero/strategy/lines.py +170 -0
- codero/strategy/text/__init__.py +140 -0
- codero/strategy/text/numbers.py +187 -0
- codero-1.0.0.dist-info/METADATA +29 -0
- codero-1.0.0.dist-info/RECORD +19 -0
- codero-1.0.0.dist-info/WHEEL +5 -0
- codero-1.0.0.dist-info/entry_points.txt +2 -0
- codero-1.0.0.dist-info/licenses/LICENSE +21 -0
- codero-1.0.0.dist-info/top_level.txt +1 -0
codero/__init__.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#==============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
#------------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2021-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
#==============================================================================
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
|
|
12
|
+
__version__ = '0.6.3'
|
|
13
|
+
|
|
14
|
+
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
|
15
|
+
PROCESS = 'codero'
|
codero/cli.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2021-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
import utilo
|
|
11
|
+
|
|
12
|
+
import codero
|
|
13
|
+
|
|
14
|
+
DESCRIPTION = 'TODO'
|
|
15
|
+
|
|
16
|
+
SOURCES = [
|
|
17
|
+
utilo.ResultFile('rawmaker', 'oneline_text_text'),
|
|
18
|
+
utilo.ResultFile('rawmaker', 'oneline_text_positions'),
|
|
19
|
+
utilo.ResultFile('rawmaker', 'oneline_fonts_header'),
|
|
20
|
+
utilo.ResultFile('rawmaker', 'oneline_fonts_content'),
|
|
21
|
+
utilo.ResultFile('rawmaker', 'border_pages'),
|
|
22
|
+
utilo.ResultFile('groupme', 'footer_footerheader'),
|
|
23
|
+
utilo.ResultFile('rawmaker', 'horizontals_horizontals'),
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
WORKPLAN = [
|
|
27
|
+
utilo.create_step(
|
|
28
|
+
'horizontal',
|
|
29
|
+
inputs=SOURCES,
|
|
30
|
+
output=('horizontal',),
|
|
31
|
+
),
|
|
32
|
+
utilo.create_step(
|
|
33
|
+
'text',
|
|
34
|
+
inputs=SOURCES,
|
|
35
|
+
output=('text',),
|
|
36
|
+
),
|
|
37
|
+
utilo.create_step(
|
|
38
|
+
'result',
|
|
39
|
+
inputs=[
|
|
40
|
+
utilo.ResultFile('codero', 'horizontal_horizontal'),
|
|
41
|
+
utilo.ResultFile('codero', 'text_text'),
|
|
42
|
+
],
|
|
43
|
+
output=('result',),
|
|
44
|
+
),
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def main():
|
|
49
|
+
utilo.featurepack(
|
|
50
|
+
root=codero.ROOT,
|
|
51
|
+
workplan=WORKPLAN,
|
|
52
|
+
featurepackage='codero.features',
|
|
53
|
+
config=utilo.FeaturePackConfig(
|
|
54
|
+
description=DESCRIPTION,
|
|
55
|
+
multiprocessed=True,
|
|
56
|
+
name=codero.PROCESS,
|
|
57
|
+
pages=True,
|
|
58
|
+
version=codero.__version__,
|
|
59
|
+
),
|
|
60
|
+
)
|
codero/decider.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2021-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
import iamraw
|
|
11
|
+
import utilo
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def decide(horizontal, text):
|
|
15
|
+
data = (horizontal, text)
|
|
16
|
+
result = []
|
|
17
|
+
for pagenumber, (horizontalx, textx) in utilo.sync_pages(iterators=data,):
|
|
18
|
+
horizontalx = horizontalx.content if horizontalx else []
|
|
19
|
+
textx = textx.content if textx else []
|
|
20
|
+
best = horizontalx if score(horizontalx) > score(textx) else textx
|
|
21
|
+
result.append(iamraw.PageContent(content=best, page=pagenumber))
|
|
22
|
+
return result
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def score(items) -> int:
|
|
26
|
+
result = 0
|
|
27
|
+
for item in items:
|
|
28
|
+
result += len(item.caption)
|
|
29
|
+
result += len(item.tokens)
|
|
30
|
+
return result
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2021-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2022-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
import serializeraw
|
|
11
|
+
|
|
12
|
+
import codero.finalize
|
|
13
|
+
import codero.strategy.lines
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def work(
|
|
17
|
+
oneline_text: str,
|
|
18
|
+
oneline_textposition: str,
|
|
19
|
+
oneline_font_header: str,
|
|
20
|
+
oneline_font_content: str,
|
|
21
|
+
sizeandborder: str,
|
|
22
|
+
headerfooter: str,
|
|
23
|
+
horizontalx: str,
|
|
24
|
+
pages: tuple = None,
|
|
25
|
+
) -> str:
|
|
26
|
+
ptcns = serializeraw.ptcn_fromfile(
|
|
27
|
+
oneline_text,
|
|
28
|
+
oneline_textposition,
|
|
29
|
+
sizeandborder,
|
|
30
|
+
headerfooter,
|
|
31
|
+
oneline_font_header,
|
|
32
|
+
oneline_font_content,
|
|
33
|
+
horizontals=horizontalx,
|
|
34
|
+
pages=pages,
|
|
35
|
+
)
|
|
36
|
+
parsed = run(ptcns)
|
|
37
|
+
dumped = serializeraw.dump_codes(parsed)
|
|
38
|
+
return dumped
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def run(ptcns) -> list:
|
|
42
|
+
result = []
|
|
43
|
+
for ptn in ptcns:
|
|
44
|
+
parsed = codero.strategy.lines.parse(ptn)
|
|
45
|
+
if not parsed.content:
|
|
46
|
+
continue
|
|
47
|
+
result.append(parsed)
|
|
48
|
+
result = codero.finalize.run(result, ptcns)
|
|
49
|
+
return result
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2021-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
import serializeraw
|
|
11
|
+
|
|
12
|
+
import codero.decider
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def work(
|
|
16
|
+
horizontalx: str,
|
|
17
|
+
textx: str,
|
|
18
|
+
pages: tuple = None,
|
|
19
|
+
) -> str:
|
|
20
|
+
horizontalx = serializeraw.load_codes(
|
|
21
|
+
horizontalx,
|
|
22
|
+
pages=pages,
|
|
23
|
+
)
|
|
24
|
+
textx = serializeraw.load_codes(
|
|
25
|
+
textx,
|
|
26
|
+
pages=pages,
|
|
27
|
+
)
|
|
28
|
+
result = codero.decider.decide(horizontalx, textx)
|
|
29
|
+
dumped = serializeraw.dump_codes(result)
|
|
30
|
+
return dumped
|
codero/features/text.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2021-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
import serializeraw
|
|
11
|
+
|
|
12
|
+
import codero.finalize
|
|
13
|
+
import codero.strategy.text
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def work(
|
|
17
|
+
oneline_text: str,
|
|
18
|
+
oneline_textposition: str,
|
|
19
|
+
oneline_font_header: str,
|
|
20
|
+
oneline_font_content: str,
|
|
21
|
+
sizeandborder: str,
|
|
22
|
+
headerfooter: str,
|
|
23
|
+
horizontalx: str,
|
|
24
|
+
pages: tuple = None,
|
|
25
|
+
) -> str:
|
|
26
|
+
ptcns = serializeraw.ptcn_fromfile(
|
|
27
|
+
oneline_text,
|
|
28
|
+
oneline_textposition,
|
|
29
|
+
sizeandborder,
|
|
30
|
+
headerfooter,
|
|
31
|
+
oneline_font_header,
|
|
32
|
+
oneline_font_content,
|
|
33
|
+
horizontals=horizontalx,
|
|
34
|
+
pages=pages,
|
|
35
|
+
)
|
|
36
|
+
parsed = run(ptcns)
|
|
37
|
+
dumped = serializeraw.dump_codes(parsed)
|
|
38
|
+
return dumped
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def run(ptcns) -> list:
|
|
42
|
+
result = []
|
|
43
|
+
for ptn in ptcns:
|
|
44
|
+
parsed = codero.strategy.text.parse(ptn)
|
|
45
|
+
if not parsed.content:
|
|
46
|
+
continue
|
|
47
|
+
result.append(parsed)
|
|
48
|
+
result = codero.finalize.run(result, ptcns)
|
|
49
|
+
return result
|
codero/finalize.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2022-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
import iamraw
|
|
11
|
+
import texmex
|
|
12
|
+
import utilo
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def run(codes: iamraw.PeaceOfCodes, ptns):
|
|
16
|
+
codes = insert_code_boundings(codes, ptns)
|
|
17
|
+
codes = horizontals_remove(codes, ptns)
|
|
18
|
+
return codes
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def insert_code_boundings(codes: iamraw.PeaceOfCodes, ptns):
|
|
22
|
+
for page in codes:
|
|
23
|
+
ptn = utilo.select_page(ptns, page=page.page)
|
|
24
|
+
for code in page.content:
|
|
25
|
+
for caption in code.caption:
|
|
26
|
+
code.caption_bounding.append(tuple(ptn[caption].bounding))
|
|
27
|
+
for token in code.tokens:
|
|
28
|
+
code.tokens_bounding.append(tuple(ptn[token].bounding))
|
|
29
|
+
return codes
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def horizontals_remove(codes: iamraw.PeaceOfCodes, ptns):
|
|
33
|
+
"""Adjust indexes of caption and token to ptns without horizontals."""
|
|
34
|
+
for page in codes:
|
|
35
|
+
ptn = utilo.select_page(ptns, page=page.page)
|
|
36
|
+
before = horizontals_before(ptn)
|
|
37
|
+
for code in page.content:
|
|
38
|
+
code.caption = {item - before[item] for item in code.caption}
|
|
39
|
+
code.tokens = {item - before[item] for item in code.tokens}
|
|
40
|
+
return codes
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def horizontals_before(ptn):
|
|
44
|
+
before = 0
|
|
45
|
+
result = []
|
|
46
|
+
for item in ptn:
|
|
47
|
+
result.append(before)
|
|
48
|
+
if item.text == texmex.HORIZONTAL:
|
|
49
|
+
before += 1
|
|
50
|
+
return result
|
codero/loc.py
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2021-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
import re
|
|
11
|
+
|
|
12
|
+
import utilo
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def determine(text: str) -> bool:
|
|
16
|
+
"""\
|
|
17
|
+
>>> determine('print("hello")')
|
|
18
|
+
True
|
|
19
|
+
"""
|
|
20
|
+
text = text.lower().strip()
|
|
21
|
+
methods = [
|
|
22
|
+
isjs,
|
|
23
|
+
ispython,
|
|
24
|
+
isbash,
|
|
25
|
+
isobjectc,
|
|
26
|
+
]
|
|
27
|
+
if any(method(text) for method in methods):
|
|
28
|
+
return True
|
|
29
|
+
return False
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def prepare(keys, left=r'\b', right=r'\b', escape: bool = False):
|
|
33
|
+
if escape:
|
|
34
|
+
keys = (re.escape(item) for item in keys)
|
|
35
|
+
items = [left + item + right for item in keys]
|
|
36
|
+
result = utilo.compiles('(' + '|'.join(items) + ')')
|
|
37
|
+
return result
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
PYTHON_KEYWORDS = utilo.splititems("""assert async await break continue
|
|
41
|
+
del elif else except finally for global if lambda pass raise nonlocal
|
|
42
|
+
return try while yield yield from as with import""")
|
|
43
|
+
PYTHON_KEYWORDS = prepare(PYTHON_KEYWORDS)
|
|
44
|
+
PYTHON_METHODS = utilo.splititems("""
|
|
45
|
+
__import__ abs all any bin bool bytearray bytes chr classmethod compile
|
|
46
|
+
complex delattr dict dir divmod enumerate eval filter float format
|
|
47
|
+
frozenset getattr globals hasattr hash hex id input int isinstance
|
|
48
|
+
issubclass iter len list locals map max memoryview min next object oct
|
|
49
|
+
open ord pow print property range repr reversed round set setattr slice
|
|
50
|
+
sorted staticmethod str sum super tuple namedtuple
|
|
51
|
+
""")
|
|
52
|
+
PYTHON_METHODS = prepare(PYTHON_METHODS, right='\\(')
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def ispython(text: str) -> bool:
|
|
56
|
+
"""\
|
|
57
|
+
>>> ispython('Abc = collections.namedtuple("Abc a b c")')
|
|
58
|
+
True
|
|
59
|
+
"""
|
|
60
|
+
if PYTHON_KEYWORDS.search(text):
|
|
61
|
+
return True
|
|
62
|
+
if PYTHON_METHODS.search(text):
|
|
63
|
+
return True
|
|
64
|
+
return False
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
JAVASCRIPT_KEYWORDS = utilo.splitlines("""for own in of while until loop
|
|
68
|
+
break return continue switch when then if unless else throw try catch
|
|
69
|
+
finally new delete typeof instanceof super true false yes no on off null
|
|
70
|
+
NaN Infinity undefined void val map apply length split sum""")
|
|
71
|
+
JAVASCRIPT_KEYWORDS = prepare(JAVASCRIPT_KEYWORDS)
|
|
72
|
+
# .reduce(
|
|
73
|
+
JAVASCRIPT_METHODS = utilo.compiles(r'\.[a-z]{3,15}\(')
|
|
74
|
+
JAVASCRIPT_START = utilo.splititems("""// /** /* * ) } )} val""")
|
|
75
|
+
JAVASCRIPT_START = prepare(
|
|
76
|
+
keys=JAVASCRIPT_START,
|
|
77
|
+
left=r'^',
|
|
78
|
+
right='',
|
|
79
|
+
escape=True,
|
|
80
|
+
)
|
|
81
|
+
# 2 val tfidf
|
|
82
|
+
JAVASCRIPT_ASSIGNMENT = utilo.compiles(r"""
|
|
83
|
+
^
|
|
84
|
+
(var|val)
|
|
85
|
+
[ ]{0,3}
|
|
86
|
+
\w[\w\d]{1,40}
|
|
87
|
+
[\:\=]
|
|
88
|
+
""")
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def isjs(text: str) -> bool:
|
|
92
|
+
"""\
|
|
93
|
+
>>> isjs('.reduce((vector1, vector2) =>')
|
|
94
|
+
True
|
|
95
|
+
>>> isjs('}')
|
|
96
|
+
True
|
|
97
|
+
>>> isjs('var tfidf:')
|
|
98
|
+
True
|
|
99
|
+
>>> isjs('val tfidf=230')
|
|
100
|
+
True
|
|
101
|
+
"""
|
|
102
|
+
if JAVASCRIPT_KEYWORDS.search(text):
|
|
103
|
+
return True
|
|
104
|
+
if JAVASCRIPT_METHODS.search(text):
|
|
105
|
+
return True
|
|
106
|
+
if JAVASCRIPT_START.search(text):
|
|
107
|
+
return True
|
|
108
|
+
if JAVASCRIPT_ASSIGNMENT.match(text):
|
|
109
|
+
return True
|
|
110
|
+
return False
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
BASH_KEYWORDS = utilo.splititems("""for do done in while screen quit ssh
|
|
114
|
+
#/bin/bash bin bash .sh csp scp
|
|
115
|
+
""")
|
|
116
|
+
BASH_KEYWORDS = prepare(BASH_KEYWORDS, escape=True)
|
|
117
|
+
BASH_ASSIGNMENT = utilo.compiles(r"""
|
|
118
|
+
^
|
|
119
|
+
[\w|\_]{1,30}
|
|
120
|
+
\=
|
|
121
|
+
["'‘]
|
|
122
|
+
""")
|
|
123
|
+
BASH_COMMENT = utilo.compiles(r"""
|
|
124
|
+
^
|
|
125
|
+
\#{1,4}[ ]
|
|
126
|
+
""")
|
|
127
|
+
BASH_VAR = utilo.compiles(r"""
|
|
128
|
+
[$]
|
|
129
|
+
(
|
|
130
|
+
\d|
|
|
131
|
+
\w{1,10}
|
|
132
|
+
)
|
|
133
|
+
""")
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def isbash(text: str) -> bool:
|
|
137
|
+
"""\
|
|
138
|
+
>>> isbash('#/bin/bash')
|
|
139
|
+
True
|
|
140
|
+
"""
|
|
141
|
+
if BASH_KEYWORDS.search(text):
|
|
142
|
+
return True
|
|
143
|
+
if BASH_ASSIGNMENT.search(text):
|
|
144
|
+
return True
|
|
145
|
+
if BASH_COMMENT.search(text):
|
|
146
|
+
return True
|
|
147
|
+
if BASH_VAR.search(text):
|
|
148
|
+
return True
|
|
149
|
+
return False
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
OBJECTC_START = utilo.splititems("""// /** /* * ) } )} ...""")
|
|
153
|
+
OBJECTC_START = prepare(OBJECTC_START, escape=True)
|
|
154
|
+
OBJECTC_KEYWORDS = utilo.splititems("""target << |= [[""")
|
|
155
|
+
OBJECTC_KEYWORDS = prepare(OBJECTC_KEYWORDS, escape=True)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def isobjectc(text: str) -> bool:
|
|
159
|
+
"""\
|
|
160
|
+
>>> isobjectc('t.target_addr |= [[ target objectForKey:@"main"] intValue] << 11; ')
|
|
161
|
+
True
|
|
162
|
+
"""
|
|
163
|
+
if OBJECTC_START.search(text):
|
|
164
|
+
return True
|
|
165
|
+
if OBJECTC_KEYWORDS.search(text):
|
|
166
|
+
return True
|
|
167
|
+
return False
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2021-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
codero/strategy/lines.py
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2021-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
"""Code Between Lines Detector
|
|
10
|
+
===========================
|
|
11
|
+
|
|
12
|
+
1. Strategy: Code and listings is detected inside 3 horizonals
|
|
13
|
+
2. Backup: Code is detected inside 2 horizonals and caption is detected below
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import elementae
|
|
17
|
+
import iamraw
|
|
18
|
+
import texmex
|
|
19
|
+
import utilo
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def parse(ptn: texmex.PTCN) -> iamraw.PageContent:
|
|
23
|
+
content = all_inside_textual_horizontals(ptn)
|
|
24
|
+
if not content:
|
|
25
|
+
content = caption_below_code(ptn)
|
|
26
|
+
result = iamraw.PageContent(content=content, page=ptn.page)
|
|
27
|
+
return result
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def all_inside_textual_horizontals(ptn):
|
|
31
|
+
"""\
|
|
32
|
+
Example
|
|
33
|
+
|
|
34
|
+
---------------------------------------------------------------------------
|
|
35
|
+
Listing 2.1 Eine Beschwerde aus dem NHTSA-Datensatz.
|
|
36
|
+
---------------------------------------------------------------------------
|
|
37
|
+
WHEN REAR ENDED WITH FOOT ON BRAKE, DRIVERS SHOULDER BELT DIDN’T RESTRAIN
|
|
38
|
+
FROM MAKING CONTACT, RESULTING IN AN INJURY. ESTIMATED SPEED OF
|
|
39
|
+
IMPACT 30 MPH.
|
|
40
|
+
---------------------------------------------------------------------------
|
|
41
|
+
"""
|
|
42
|
+
code = []
|
|
43
|
+
collector = DetectorAllInside()
|
|
44
|
+
for index, line in enumerate(ptn):
|
|
45
|
+
done = collector.run(line, index)
|
|
46
|
+
if not done:
|
|
47
|
+
continue
|
|
48
|
+
if len(utilo.unique(done)) != 3:
|
|
49
|
+
# false posititve, a lot of lines with any content. We require
|
|
50
|
+
# content between detected lines to have valid code detection.
|
|
51
|
+
collector.reset()
|
|
52
|
+
continue
|
|
53
|
+
# detected
|
|
54
|
+
code.append(done)
|
|
55
|
+
collector.reset()
|
|
56
|
+
converted = [
|
|
57
|
+
iamraw.PeaceOfCode(
|
|
58
|
+
caption=utilo.rtuple(done[0] + 1, done[1]),
|
|
59
|
+
tokens=utilo.rtuple(done[1] + 1, done[2]),
|
|
60
|
+
) for done in code
|
|
61
|
+
]
|
|
62
|
+
content = remove_invalids(converted, ptn)
|
|
63
|
+
return content
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def caption_below_code(ptn):
|
|
67
|
+
code = []
|
|
68
|
+
collector = DetectorBelow()
|
|
69
|
+
for index, line in enumerate(ptn):
|
|
70
|
+
done = collector.run(line, index)
|
|
71
|
+
if not done:
|
|
72
|
+
continue
|
|
73
|
+
# detected
|
|
74
|
+
code.append(done)
|
|
75
|
+
collector.reset()
|
|
76
|
+
content = [
|
|
77
|
+
iamraw.PeaceOfCode(
|
|
78
|
+
caption=utilo.rtuple(done[1] + 1, done[2] + 1),
|
|
79
|
+
tokens=utilo.rtuple(done[0] + 1, done[1]),
|
|
80
|
+
) for done in code
|
|
81
|
+
]
|
|
82
|
+
content = remove_invalids(content, ptn)
|
|
83
|
+
return content
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def remove_invalids(content, navigator: texmex.PTCN):
|
|
87
|
+
result = []
|
|
88
|
+
for item in content:
|
|
89
|
+
if not item.tokens:
|
|
90
|
+
# skip three horizontals in a row
|
|
91
|
+
continue
|
|
92
|
+
if not item.caption:
|
|
93
|
+
# skip three horizontals in a row
|
|
94
|
+
continue
|
|
95
|
+
firstindex = item.caption[0]
|
|
96
|
+
if not elementae.iscaption_code(navigator[firstindex].text):
|
|
97
|
+
continue
|
|
98
|
+
result.append(item)
|
|
99
|
+
return result
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class DetectorAllInside:
|
|
103
|
+
"""\
|
|
104
|
+
---------------------------------------------------------------------------
|
|
105
|
+
Listing 2.1 Eine Beschwerde aus dem NHTSA-Datensatz.
|
|
106
|
+
---------------------------------------------------------------------------
|
|
107
|
+
WHEN REAR ENDED WITH FOOT ON BRAKE, DRIVERS SHOULDER BELT DIDN’T RESTRAIN
|
|
108
|
+
FROM MAKING CONTACT, RESULTING IN AN INJURY. ESTIMATED SPEED OF
|
|
109
|
+
IMPACT 30 MPH.
|
|
110
|
+
---------------------------------------------------------------------------
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
def __init__(self):
|
|
114
|
+
self.start: int = None
|
|
115
|
+
self.middle: int = None
|
|
116
|
+
self.end: int = None
|
|
117
|
+
|
|
118
|
+
def run(self, line, index):
|
|
119
|
+
text = line.text
|
|
120
|
+
if self.start is None:
|
|
121
|
+
if text == texmex.HORIZONTAL:
|
|
122
|
+
self.start = index
|
|
123
|
+
return None
|
|
124
|
+
if self.middle is None:
|
|
125
|
+
if text == texmex.HORIZONTAL:
|
|
126
|
+
self.middle = index
|
|
127
|
+
return None
|
|
128
|
+
if text != texmex.HORIZONTAL:
|
|
129
|
+
return None
|
|
130
|
+
self.end = index
|
|
131
|
+
return self.start, self.middle, self.end
|
|
132
|
+
|
|
133
|
+
def reset(self):
|
|
134
|
+
self.start, self.middle, self.end = None, None, None
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class DetectorBelow:
|
|
138
|
+
"""\
|
|
139
|
+
---------------------------------------------------------------------------
|
|
140
|
+
WHEN REAR ENDED WITH FOOT ON BRAKE, DRIVERS SHOULDER BELT DIDN’T RESTRAIN
|
|
141
|
+
FROM MAKING CONTACT, RESULTING IN AN INJURY. ESTIMATED SPEED OF
|
|
142
|
+
IMPACT 30 MPH.
|
|
143
|
+
---------------------------------------------------------------------------
|
|
144
|
+
Listing 2.1 Eine Beschwerde aus dem NHTSA-Datensatz.
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
def __init__(self):
|
|
148
|
+
self.start: int = None
|
|
149
|
+
self.middle: int = None
|
|
150
|
+
self.end: int = None
|
|
151
|
+
|
|
152
|
+
def run(self, line, index):
|
|
153
|
+
text = line.text
|
|
154
|
+
if self.start is None:
|
|
155
|
+
if text == texmex.HORIZONTAL:
|
|
156
|
+
self.start = index
|
|
157
|
+
return None
|
|
158
|
+
if self.middle is None:
|
|
159
|
+
if text == texmex.HORIZONTAL:
|
|
160
|
+
self.middle = index
|
|
161
|
+
return None
|
|
162
|
+
if not elementae.iscaption_code(text):
|
|
163
|
+
# invalid parsing, reset Detector
|
|
164
|
+
self.reset()
|
|
165
|
+
return None
|
|
166
|
+
self.end = index
|
|
167
|
+
return self.start, self.middle, self.end
|
|
168
|
+
|
|
169
|
+
def reset(self):
|
|
170
|
+
self.start, self.middle, self.end = None, None, None
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2021-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
"""Code Inside Text Detector
|
|
10
|
+
=========================
|
|
11
|
+
|
|
12
|
+
Detect code as a normal part of written text. There are no special
|
|
13
|
+
elementae which help detecting these lines of code.
|
|
14
|
+
|
|
15
|
+
1. Strategy: Lines number and caption below
|
|
16
|
+
2. Strategy: Specialized R-Code with headline detector
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import re
|
|
20
|
+
|
|
21
|
+
import configos
|
|
22
|
+
import elementae
|
|
23
|
+
import iamraw
|
|
24
|
+
import texmex
|
|
25
|
+
import utilo
|
|
26
|
+
|
|
27
|
+
import codero.loc
|
|
28
|
+
import codero.strategy.text.numbers
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def parse(ptn: texmex.PTCN) -> iamraw.PageContent:
|
|
32
|
+
pagenumber = ptn.page
|
|
33
|
+
collected = []
|
|
34
|
+
if content := codero.strategy.text.numbers.linenumbers_and_caption(ptn):
|
|
35
|
+
collected.extend(content)
|
|
36
|
+
ptn = hide_result(ptn, collected)
|
|
37
|
+
if content := codero.strategy.text.numbers.code_without_caption(ptn):
|
|
38
|
+
collected.extend(content)
|
|
39
|
+
ptn = hide_result(ptn, collected)
|
|
40
|
+
if not collected:
|
|
41
|
+
collected = raw_code(ptn)
|
|
42
|
+
pagecontent = iamraw.PageContent(
|
|
43
|
+
content=collected,
|
|
44
|
+
page=pagenumber,
|
|
45
|
+
)
|
|
46
|
+
return pagecontent
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def hide_result(ptn, codes):
|
|
50
|
+
done = set()
|
|
51
|
+
for item in codes:
|
|
52
|
+
done |= item.caption
|
|
53
|
+
done |= item.tokens
|
|
54
|
+
ptn = ptn[:]
|
|
55
|
+
for item in done:
|
|
56
|
+
ptn[item] = texmex.TextInfo(text='')
|
|
57
|
+
return ptn
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
NOHEADLINE = '<<<NOHEADLINE>>>'
|
|
61
|
+
|
|
62
|
+
RAWCODE_LENGTH_MIN = configos.HV_INT_PLUS(default=5)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def raw_code(ptn):
|
|
66
|
+
code = []
|
|
67
|
+
collector = DetectorWithHeadline()
|
|
68
|
+
for index, line in enumerate(ptn):
|
|
69
|
+
done = collector.run(line.text, index)
|
|
70
|
+
if not done:
|
|
71
|
+
continue
|
|
72
|
+
# detected
|
|
73
|
+
code.append(done)
|
|
74
|
+
collector.reset()
|
|
75
|
+
if any((collector.start, collector.middle, collector.end)):
|
|
76
|
+
# raw code till page end
|
|
77
|
+
code.append((collector.start, collector.middle, len(ptn)))
|
|
78
|
+
content = [
|
|
79
|
+
iamraw.PeaceOfCode(tokens=set(utilo.rtuple(done[1], done[2])))
|
|
80
|
+
if done[0] == NOHEADLINE else iamraw.PeaceOfCode(
|
|
81
|
+
caption=set(utilo.rtuple(done[0], done[1])),
|
|
82
|
+
tokens=set(utilo.rtuple(done[1], done[2])),
|
|
83
|
+
) for done in code
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
def is_valid_raw(item):
|
|
87
|
+
if not item.caption:
|
|
88
|
+
if len(item.tokens) < RAWCODE_LENGTH_MIN:
|
|
89
|
+
# Too short code without any caption
|
|
90
|
+
return False
|
|
91
|
+
return True
|
|
92
|
+
|
|
93
|
+
content = [item for item in content if is_valid_raw(item)]
|
|
94
|
+
return content
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
RCODE = re.compile(r'^R-Code:')
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class DetectorWithHeadline:
|
|
101
|
+
"""\
|
|
102
|
+
R-Code:
|
|
103
|
+
|
|
104
|
+
> PROB_VOLLST <- NA
|
|
105
|
+
> PROB_VOLLST[PROB_VOLLST_s1 == 1 & PROB_VOLLST_s2 == 1] <- 1
|
|
106
|
+
> PROB_VOLLST[PROB_VOLLST_s1 != 1 | PROB_VOLLST_s2 != 1] <- 0
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
def __init__(self):
|
|
110
|
+
self.start: int = None
|
|
111
|
+
self.middle: int = None
|
|
112
|
+
self.end: int = None
|
|
113
|
+
|
|
114
|
+
def run(self, line: str, index: int):
|
|
115
|
+
text = line.strip()
|
|
116
|
+
if self.start is None:
|
|
117
|
+
if RCODE.search(text):
|
|
118
|
+
self.start = index
|
|
119
|
+
return None
|
|
120
|
+
if text and text[0] in '#>+':
|
|
121
|
+
# TODO: MAKE THIS MORE GENERAL
|
|
122
|
+
# R-Code start without headline
|
|
123
|
+
self.start = NOHEADLINE
|
|
124
|
+
self.middle = index
|
|
125
|
+
return None
|
|
126
|
+
if text and text[0] in '#>+':
|
|
127
|
+
if self.middle is None:
|
|
128
|
+
self.middle = index
|
|
129
|
+
else:
|
|
130
|
+
self.end = index + 1
|
|
131
|
+
return None
|
|
132
|
+
if self.middle is not None:
|
|
133
|
+
result = self.start, self.middle, index
|
|
134
|
+
self.reset()
|
|
135
|
+
return result
|
|
136
|
+
self.reset()
|
|
137
|
+
return None
|
|
138
|
+
|
|
139
|
+
def reset(self):
|
|
140
|
+
self.start, self.middle, self.end = None, None, None
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2022-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
import re
|
|
11
|
+
|
|
12
|
+
import configos
|
|
13
|
+
import elementae
|
|
14
|
+
import iamraw
|
|
15
|
+
import utilo
|
|
16
|
+
|
|
17
|
+
import codero.loc
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def linenumbers_and_caption(ptn):
|
|
21
|
+
code = []
|
|
22
|
+
collector = DetectorLineNumbers()
|
|
23
|
+
for index, line in enumerate(ptn):
|
|
24
|
+
done = collector.run(line.text, index)
|
|
25
|
+
if not done:
|
|
26
|
+
continue
|
|
27
|
+
# detected
|
|
28
|
+
code.append(done)
|
|
29
|
+
collector.reset()
|
|
30
|
+
content = [
|
|
31
|
+
iamraw.PeaceOfCode(
|
|
32
|
+
caption=set(utilo.rtuple(done[1], done[2])),
|
|
33
|
+
tokens=set(utilo.rtuple(done[0], done[1])),
|
|
34
|
+
) for done in code
|
|
35
|
+
]
|
|
36
|
+
return content
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def code_without_caption(ptn):
|
|
40
|
+
code = []
|
|
41
|
+
collector = CodeWithoutCaption()
|
|
42
|
+
for index, line in enumerate(ptn):
|
|
43
|
+
done = collector.run(line.text, index)
|
|
44
|
+
if not done:
|
|
45
|
+
continue
|
|
46
|
+
# detected
|
|
47
|
+
code.append(done)
|
|
48
|
+
final = collector.final()
|
|
49
|
+
if final[0] is not None and final[1] is not None:
|
|
50
|
+
code.append(final)
|
|
51
|
+
content = [
|
|
52
|
+
iamraw.PeaceOfCode(
|
|
53
|
+
caption=set(),
|
|
54
|
+
tokens=set(utilo.rtuple(done[0], done[1])),
|
|
55
|
+
) for done in code
|
|
56
|
+
]
|
|
57
|
+
return content
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class DetectorLineNumbers:
|
|
61
|
+
"""\
|
|
62
|
+
1 $ ./spark-shell
|
|
63
|
+
2 [...]
|
|
64
|
+
3 / __/__ ___ _____/ /__
|
|
65
|
+
|
|
66
|
+
Listing 2.1: Word Count in der Spark Konsole
|
|
67
|
+
|
|
68
|
+
>>> dtn = DetectorLineNumbers()
|
|
69
|
+
>>> dtn.run('1 import collections', 10)
|
|
70
|
+
>>> dtn.run('2 Abc = collections.namedtuple("Abc a b c")', 11)
|
|
71
|
+
>>> dtn.run('Listing 3: Simple python example', 12)
|
|
72
|
+
(10, 12, 13)
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
def __init__(self):
|
|
76
|
+
self.start: int = None
|
|
77
|
+
self.middle: int = None
|
|
78
|
+
self.end: int = None
|
|
79
|
+
|
|
80
|
+
def run(self, line: str, index: int):
|
|
81
|
+
text = line.strip()
|
|
82
|
+
if self.start is None:
|
|
83
|
+
if self.loc(text):
|
|
84
|
+
self.start = index
|
|
85
|
+
return None
|
|
86
|
+
if self.loc(text):
|
|
87
|
+
self.middle = index + 1
|
|
88
|
+
return None
|
|
89
|
+
if self.valid(text):
|
|
90
|
+
self.middle = index
|
|
91
|
+
self.end = index + 1
|
|
92
|
+
else:
|
|
93
|
+
self.reset()
|
|
94
|
+
return None
|
|
95
|
+
return self.final()
|
|
96
|
+
|
|
97
|
+
def loc(self, text: str) -> bool: # pylint:disable=R0201
|
|
98
|
+
"""Determine if text can be a line of code."""
|
|
99
|
+
return CODE_NUMBER.search(text)
|
|
100
|
+
|
|
101
|
+
def valid(self, text: str) -> bool: # pylint:disable=R0201
|
|
102
|
+
return elementae.iscaption_code(text)
|
|
103
|
+
|
|
104
|
+
def final(self):
|
|
105
|
+
result = self.start, self.middle, self.end
|
|
106
|
+
self.reset()
|
|
107
|
+
return result
|
|
108
|
+
|
|
109
|
+
def reset(self):
|
|
110
|
+
self.start, self.middle, self.end = None, None, None
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
CWC_CODE_LENGTH_MIN = configos.HV_INT_PLUS(default=2)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class CodeWithoutCaption(DetectorLineNumbers):
|
|
117
|
+
"""\
|
|
118
|
+
Code inside text
|
|
119
|
+
>>> cwc = CodeWithoutCaption()
|
|
120
|
+
>>> cwc.run('Text text text.', 9)
|
|
121
|
+
>>> cwc.run('1 import collections', 10)
|
|
122
|
+
>>> cwc.run('2 Abc = collections.namedtuple("Abc a b c")', 11)
|
|
123
|
+
>>> cwc.run('3 print("hello")', 12)
|
|
124
|
+
>>> cwc.run('Ich bin kein Quellcode.', 13)
|
|
125
|
+
(10, 13)
|
|
126
|
+
|
|
127
|
+
Normal List
|
|
128
|
+
>>> cwc = CodeWithoutCaption()
|
|
129
|
+
>>> cwc.run('1. Ich bin ein Listenpunkt', 3)
|
|
130
|
+
>>> cwc.run('2. Haus', 4)
|
|
131
|
+
>>> cwc.run('3. Hund', 5)
|
|
132
|
+
>>> cwc.run('Ich bin kein Quellcode.', 6)
|
|
133
|
+
|
|
134
|
+
TODO: ADD OPTION TO HAVE SOME LINES FALSE DETECTION
|
|
135
|
+
"""
|
|
136
|
+
|
|
137
|
+
def __init__(self):
|
|
138
|
+
super().__init__()
|
|
139
|
+
self.empty_line_count = 0
|
|
140
|
+
|
|
141
|
+
def loc(self, text: str) -> bool:
|
|
142
|
+
"""\
|
|
143
|
+
Bash Code
|
|
144
|
+
>>> cwc = CodeWithoutCaption()
|
|
145
|
+
>>> cwc.loc('1 #/bin/bash')
|
|
146
|
+
True
|
|
147
|
+
"""
|
|
148
|
+
if not CODE_NUMBER.search(text):
|
|
149
|
+
return False
|
|
150
|
+
without_number = CODE_NUMBER.sub('', text).strip()
|
|
151
|
+
if not without_number:
|
|
152
|
+
self.empty_line_count += 1
|
|
153
|
+
return True
|
|
154
|
+
if not codero.loc.determine(without_number):
|
|
155
|
+
return False
|
|
156
|
+
return True
|
|
157
|
+
|
|
158
|
+
def valid(self, text: str) -> bool:
|
|
159
|
+
if elementae.iscaption_code(text):
|
|
160
|
+
# see DetectorLineNumbers
|
|
161
|
+
self.reset()
|
|
162
|
+
return False
|
|
163
|
+
if self.middle is None:
|
|
164
|
+
self.reset()
|
|
165
|
+
return False
|
|
166
|
+
length = self.middle - self.start
|
|
167
|
+
if length < CWC_CODE_LENGTH_MIN:
|
|
168
|
+
self.reset()
|
|
169
|
+
return False
|
|
170
|
+
empty_rate = self.empty_line_count / length
|
|
171
|
+
if empty_rate > 0.34: # TODO: HOLY VALUE
|
|
172
|
+
# skip too many empty lines which are false positive dectections
|
|
173
|
+
self.reset()
|
|
174
|
+
return False
|
|
175
|
+
return True
|
|
176
|
+
|
|
177
|
+
def reset(self):
|
|
178
|
+
super().reset()
|
|
179
|
+
self.empty_line_count = 0
|
|
180
|
+
|
|
181
|
+
def final(self):
|
|
182
|
+
result = self.start, self.middle
|
|
183
|
+
self.reset()
|
|
184
|
+
return result
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
CODE_NUMBER = re.compile(r'^\d{1,3}([ ]|(?!\.))')
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: codero
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Author-email: Helmut Konrad Schewe <helmutus@outlook.com>
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/anaticulae/codero
|
|
7
|
+
Project-URL: Repository, https://github.com/anaticulae/codero
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
11
|
+
Requires-Python: >=3.12
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: utilo<3.0.0,>=2.109.1
|
|
15
|
+
Requires-Dist: iamraw<5.0.0,>=4.93.0
|
|
16
|
+
Requires-Dist: elementae<2.0.0,>=1.0.1
|
|
17
|
+
Requires-Dist: configos<2.0.0,>=1.0.4
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: gennex<2.0.0,>=1.1.0; extra == "dev"
|
|
20
|
+
Requires-Dist: groupmes<2.0.0,>=1.1.0; extra == "dev"
|
|
21
|
+
Requires-Dist: headnote<2.0.0,>=1.0.3; extra == "dev"
|
|
22
|
+
Requires-Dist: hoverpower<2.0.0,>=1.5.2; extra == "dev"
|
|
23
|
+
Requires-Dist: ibidem<2.0.0,>=1.0.2; extra == "dev"
|
|
24
|
+
Requires-Dist: mundare<2.0.0,>=1.0.2; extra == "dev"
|
|
25
|
+
Requires-Dist: pagenumber<2.0.0,>=1.0.0; extra == "dev"
|
|
26
|
+
Requires-Dist: utilotest<2.0.0,>=1.0.5; extra == "dev"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# codero
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
codero/__init__.py,sha256=s_KoCWB3r1hcvs8_1rEwwErxaTbilHdZUYqB7kXVpkU,676
|
|
2
|
+
codero/cli.py,sha256=aSryeT2ecsJgcmbj4JQwd2ctV27yG0sowi0HudmZAYQ,1815
|
|
3
|
+
codero/decider.py,sha256=1HkO7o3nXrKDXQaAy3VAnig3OjKbIlCIPCDv3jW_Py0,1169
|
|
4
|
+
codero/finalize.py,sha256=2FYwkXFA5Z7gGbX9y-Iovupqn41y4yt1327apvWIlmE,1812
|
|
5
|
+
codero/loc.py,sha256=K6NAsKhIb4DrK9oG6dqel7ameEZ6Ap3n2UUa2OOJteE,4519
|
|
6
|
+
codero/features/__init__.py,sha256=ZnAmZoM8YS7O_aZREOZiaHHCsO1ctWvQVu__JGFNWCc,552
|
|
7
|
+
codero/features/horizontal.py,sha256=DWup-mikKt2GXLE6uwWxj-g4W3xXwdfR1-jVtJM0uLs,1462
|
|
8
|
+
codero/features/result.py,sha256=msRKBiTKk_A8BEXxGGjo0mEC17FVE97ZM1OWqfCmGOw,969
|
|
9
|
+
codero/features/text.py,sha256=k42-W10xwS4iv2XInR6EuD6OwJbkpT5RG30q8mbbXfc,1460
|
|
10
|
+
codero/strategy/__init__.py,sha256=ZnAmZoM8YS7O_aZREOZiaHHCsO1ctWvQVu__JGFNWCc,552
|
|
11
|
+
codero/strategy/lines.py,sha256=cB9BKQC8nnS80T9u9LZcqLfZonOWiqqNxryKgyBdUJE,5684
|
|
12
|
+
codero/strategy/text/__init__.py,sha256=17Q_RqcE3_33nNX11jk70bhDZwZ1CrekX6oJZUpB30c,4136
|
|
13
|
+
codero/strategy/text/numbers.py,sha256=dJWrqrxhtnFGVMiZwJGsMiHJOAoOcKPHdhe4eDs6qMk,5253
|
|
14
|
+
codero-1.0.0.dist-info/licenses/LICENSE,sha256=9jV_XivjSpyzpEYIFKZGcjDzX8invw3EHEJsGXmGJbA,1077
|
|
15
|
+
codero-1.0.0.dist-info/METADATA,sha256=mcP_rBFL7E-siYy6st8cQjCL1DI0XUbkw_WomsyNV2Q,1128
|
|
16
|
+
codero-1.0.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
17
|
+
codero-1.0.0.dist-info/entry_points.txt,sha256=EflcpnvitNuwY78jFrrd4SHQmNUeLR5X6rUUkee7-xk,43
|
|
18
|
+
codero-1.0.0.dist-info/top_level.txt,sha256=mSUG4msWnOzBsNhN_ABrRJ5BDfD749-YKOIwA2yJcoc,7
|
|
19
|
+
codero-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Helmut Konrad Schewe
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
codero
|