mergeron 2024.739123.8__tar.gz → 2024.739125.2__tar.gz

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.

Potentially problematic release.


This version of mergeron might be problematic. Click here for more details.

Files changed (33) hide show
  1. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/PKG-INFO +1 -1
  2. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/pyproject.toml +1 -1
  3. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/__init__.py +1 -1
  4. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/core/ftc_merger_investigations_data.py +2 -2
  5. mergeron-2024.739125.2/src/mergeron/data/jinja2_LaTeX_templates/ftcinvdata_summarypaired_table_template_tabularray.tex.jinja2 +81 -0
  6. mergeron-2024.739125.2/src/mergeron/data/jinja2_LaTeX_templates/setup_tikz_tables.sty +129 -0
  7. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/gen/enforcement_stats.py +99 -60
  8. mergeron-2024.739123.8/src/mergeron/data/jinja2_LaTeX_templates/setup_tikz_tables.tex +0 -96
  9. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/README.rst +0 -0
  10. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/License.txt +0 -0
  11. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/core/__init__.py +0 -0
  12. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/core/damodaran_margin_data.py +0 -0
  13. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/core/guidelines_boundaries.py +0 -0
  14. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/core/guidelines_boundary_functions.py +0 -0
  15. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/core/guidelines_boundary_functions_extra.py +0 -0
  16. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/core/pseudorandom_numbers.py +0 -0
  17. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/data/__init__.py +0 -0
  18. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/data/damodaran_margin_data.xls +0 -0
  19. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/data/damodaran_margin_data_dict.msgpack +0 -0
  20. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/data/ftc_invdata.msgpack +0 -0
  21. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/data/jinja2_LaTeX_templates/clrrate_cis_summary_table_template.tex.jinja2 +0 -0
  22. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/data/jinja2_LaTeX_templates/ftcinvdata_byhhianddelta_table_template.tex.jinja2 +0 -0
  23. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/data/jinja2_LaTeX_templates/ftcinvdata_summary_table_template.tex.jinja2 +0 -0
  24. /mergeron-2024.739123.8/src/mergeron/data/jinja2_LaTeX_templates/ftcinvdata_summarypaired_table_template.tex.jinja2 → /mergeron-2024.739125.2/src/mergeron/data/jinja2_LaTeX_templates/ftcinvdata_summarypaired_table_template_tikz.tex.jinja2 +0 -0
  25. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/data/jinja2_LaTeX_templates/mergeron.cls +0 -0
  26. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/data/jinja2_LaTeX_templates/mergeron_table_collection_template.tex.jinja2 +0 -0
  27. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/demo/__init__.py +0 -0
  28. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/demo/visualize_empirical_margin_distribution.py +0 -0
  29. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/gen/__init__.py +0 -0
  30. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/gen/data_generation.py +0 -0
  31. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/gen/data_generation_functions.py +0 -0
  32. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/gen/upp_tests.py +0 -0
  33. {mergeron-2024.739123.8 → mergeron-2024.739125.2}/src/mergeron/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mergeron
3
- Version: 2024.739123.8
3
+ Version: 2024.739125.2
4
4
  Summary: Merger Policy Analysis using Python
5
5
  License: MIT
6
6
  Keywords: merger policy analysis,merger guidelines,merger screening,policy presumptions,concentration standards,upward pricing pressure,GUPPI
@@ -13,7 +13,7 @@ keywords = [
13
13
  "upward pricing pressure",
14
14
  "GUPPI",
15
15
  ]
16
- version = "2024.739123.8"
16
+ version = "2024.739125.2"
17
17
 
18
18
  # Classifiers list: https://pypi.org/classifiers/
19
19
  classifiers = [
@@ -9,7 +9,7 @@ from numpy.typing import NDArray
9
9
 
10
10
  _PKG_NAME: str = Path(__file__).parent.stem
11
11
 
12
- VERSION = "2024.739123.8"
12
+ VERSION = "2024.739125.2"
13
13
 
14
14
  __version__ = VERSION
15
15
 
@@ -95,7 +95,7 @@ class INVTableData(NamedTuple):
95
95
  data_array: ArrayBIGINT
96
96
 
97
97
 
98
- INVData: TypeAlias = Mapping[str, dict[str, dict[str, INVTableData]]]
98
+ INVData: TypeAlias = Mapping[str, Mapping[str, Mapping[str, INVTableData]]]
99
99
 
100
100
 
101
101
  def construct_data(
@@ -228,7 +228,7 @@ def _construct_no_evidence_data(_invdata: INVData, _data_period: str, /) -> None
228
228
  _invdata_sub_evid_cond_conc = _invdata[_data_period][_stats_grp]
229
229
 
230
230
  _dtn = _table_nos_map[_invdata_evid_cond]["ByHHIandDelta"]
231
- _stn0 = "Table 3.1" if _stats_grp == "ByHHIandDelta" else "Table 4.1"
231
+ _stn0 = "Table 4.1" if _stats_grp == "ByFirmCount" else "Table 3.1"
232
232
  _stn1, _stn2 = (_dtn.replace(".X", f".{_i}") for _i in ("1", "2"))
233
233
 
234
234
  _invdata_sub_evid_cond_conc[_dtn] = INVTableData(
@@ -0,0 +1,81 @@
1
+ \begin{table}[t]
2
+
3
+ ((* if tmpl_data.obs_merger_class_0 == 'All Markets' *))
4
+ ((* set obs_merger_class_0 = "All Markets" *))
5
+ ((* else *))
6
+ ((* set obs_merger_class_0 = "Markets with, ``" + tmpl_data.obs_merger_class_0 + "''" *))
7
+ ((* endif *))
8
+
9
+ ((* set obs_merger_class_1 = "Markets with, ``" + tmpl_data.obs_merger_class_1 + "''" *))
10
+
11
+ \centering
12
+ \caption{FTC Merger Investigations Data}\label{tbl:FTCInvData_\JINVAR{- tmpl_data.obs_summary_type }_alt}
13
+ {\footnotesize
14
+ \JINVAR{ tmpl_data.obs_summary_type_title } \\
15
+ Grouped by Entry Conditions and Reporting Period \\[0.5\baselineskip]
16
+ }
17
+
18
+ \sffamily\scriptsize\addfontfeatures{Numbers={Monospaced,Lining}}
19
+ \SetTblrInner{stretch=0, rowsep=3pt, colsep=3pt, hspan=even}
20
+ \begin{tikzpicture}[auto, font = \sffamily]
21
+ \begin{tblr}{
22
+ baseline=T,
23
+ width=\textwidth,
24
+ colspec = {%
25
+ Q[c,m,wd=\JINVAR{ tmpl_data.hdrcol_width }]%
26
+ Q[r,m]%
27
+ Q[r,m]%
28
+ Q[r,m]%
29
+ Q[r,m]%
30
+ Q[r,m]%
31
+ Q[r,m]%
32
+ Q[r,m]%
33
+ Q[r,m]%
34
+ },
35
+ row{odd[6]} = {bg=table_bar_green},
36
+ row{1-5} = {fg=white, bg=OBSHDRFill},
37
+ column{1} = {fg=white, bg=OBSHDRFill},
38
+ cell{1}{1} = {r=5, c=1}{c, f},
39
+ cell{1}{2} = {r=1, c=8}{c},
40
+ cell{2}{2,6} = {r=1, c=4}{c},
41
+ cell{3,4}{2,4,6,8} = {r=1, c=2}{c},
42
+ cell{5}{2-9} = {r, m, cmd=\rothead},
43
+ vline{4,8} = {3-5}{1pt, white},
44
+ vline{6} = {2-5}{1pt, white},
45
+ vline{4,6,8} = {6-Z}{1pt, OBSHDRFill},
46
+ hline{Y} = {1-Z}{1pt, OBSHDRFill},
47
+ }
48
+ { \JINVAR{- tmpl_data.hdrcol_desc_text } } &
49
+ Observed Data & & & & & & & \\
50
+ sp0 &
51
+ \JINVAR{ obs_merger_class_0 } & sp0 & sp0 & sp0 &
52
+ \JINVAR{ obs_merger_class_1 } & sp0 & sp0 & sp0 \\
53
+ sp0 &
54
+ \JINVAR{ tmpl_data.obs_periods_str|replace(" & ", " & sp0 & ") } & sp0 &
55
+ \JINVAR{ tmpl_data.obs_periods_str|replace(" & ", " & sp0 & ") } & sp0 \\
56
+ sp0 &
57
+ \JINVAR{ tmpl_data.mkt_counts_str_class_0|replace(" & ", " & sp0 & ") } & sp0 &
58
+ \JINVAR{ tmpl_data.mkt_counts_str_class_0|replace(" & ", " & sp0 & ") } & sp0 \\
59
+ sp0 &
60
+ {Relative \\ Frequency} &
61
+ {Proportion \\ Enforced} &
62
+ {Relative \\ Frequency} &
63
+ {Proportion \\ Enforced} &
64
+ {Relative\\ Frequency} &
65
+ {Proportion \\ Enforced} &
66
+ {Relative \\ Frequency} &
67
+ {Proportion \\ Enforced} \\
68
+ %
69
+ \JINVAR{ tmpl_data.invdata_datstr -}
70
+ \end{tblr}
71
+ \end{tikzpicture}
72
+
73
+ \setlist{nosep}
74
+ \vspace{\baselineskip}
75
+ {\raggedright\sffamily\tiny
76
+ \JINVAR{ tmpl_data.invdata_notestr }
77
+ \vspace{\baselineskip}
78
+ \JINVAR{ tmpl_data.invdata_sourcestr }
79
+ }
80
+ \vspace{\baselineskip}
81
+ \end{table}
@@ -0,0 +1,129 @@
1
+ % Tables in tikz, but first we need to define some colors for nonwhite text backgrounds
2
+ \definecolor{OBSHDRFill}{HTML}{0a6c97}
3
+ \definecolor{SIMHDRFill}{HTML}{646464}
4
+ \definecolor{DataFill}{HTML}{dfeadf}
5
+ % The below are definition's from Paul Tol's website, https://personal.sron.nl/~pault/
6
+ \definecolor{VibrBlue}{HTML}{0077bb}
7
+ \definecolor{BrightGreen}{HTML}{228833}
8
+ \definecolor{HiCoYellow}{HTML}{ddaa33}
9
+ \definecolor{VibrRed}{HTML}{cc3311}
10
+
11
+ %% Rotating text in a tabularray cell
12
+ %% https://tex.stackexchange.com/questions/101686/rotating-text-in-a-cell
13
+ %%https://tex.stackexchange.com/questions/464170/how-to-rotate-text-in-table
14
+ \usepackage{rotating}
15
+ \usepackage{makecell}
16
+
17
+ %% https://github.com/lvjr/tabularray/discussions/85#discussioncomment-3397197
18
+ \setlength\rotheadsize{1.5cm}
19
+ \renewcommand\theadfont{}
20
+
21
+
22
+
23
+ \newcount\tnr
24
+ \newcount\tnc
25
+ % \makeatletter
26
+ % \tikzset{record matrix dimensions/.style={execute at end matrix={
27
+ % \global\tnc=\pgf@matrix@numberofcolumns
28
+ % \global\tnr=\pgfmatrixcurrentrow
29
+ % }}}
30
+ % \makeatother
31
+
32
+ % Some useful documents from grokking various options used below
33
+ % https://courses.helsinki.fi/sites/default/files/course-material/4611024/LaTeXandFriendsCourseInHelsinki_9_v2.pdf
34
+ % https://tug.org/TUGboat/tb39-1/tb121duck-tikz.pdf
35
+ % https://tug.org/TUGboat/tb41-1/tb127duck-matrix.pdf
36
+ % https://tex.stackexchange.com/questions/22286/coloring-every-other-row-of-a-table-with-vertical-lines
37
+ % https://tex.stackexchange.com/questions/354043/swot-matrix-with-multicolumn-and-multirow
38
+ % https://tex.stackexchange.com/questions/20599/horizontal-row-separation-line-in-tikz-matrix-like-hline-in-tabular
39
+ % https://tex.stackexchange.com/questions/63560/how-to-use-x-coordinate-of-a-point-and-y-coordinate-of-other-point
40
+ % https://tex.stackexchange.com/questions/167944/auto-word-wrapping-in-a-node-in-tikz
41
+ % https://tex.stackexchange.com/questions/132741/typewriter-in-tikz-node
42
+ \tikzset{
43
+ green_bar_filler/.code={
44
+ \pgfmathtruncatemacro{\itest}{ifthenelse(%
45
+ \pgfmatrixcurrentcolumn==1,0,%
46
+ ifthenelse(iseven(\pgfmatrixcurrentrow),1,3))}
47
+ %\typeout{\the\pgfmatrixcurrentcolumn,\pgfmatrixcurrentrow->\itest}
48
+ \ifcase\itest
49
+ \tikzset{fill=none}%
50
+ \or
51
+ \tikzset{fill=DataFill}%
52
+ \else
53
+ \tikzset{fill=white}%
54
+ \fi
55
+ },
56
+ get_matrix_dims/.code={
57
+ \global\tnc=\pgf@matrix@numberofcolumns
58
+ \global\tnr=\pgfmatrixcurrentrow
59
+ },
60
+ record matrix dimensions/.style={
61
+ execute at end matrix={get_matrix_dims},
62
+ % execute at end matrix={
63
+ % \global\tnc=\pgf@matrix@numberofcolumns
64
+ % \global\tnr=\pgfmatrixcurrentrow
65
+ % }
66
+ },
67
+ % If you only have numbers, text depth = 0ex; if text, text depth = 0.25ex, (may need tweaking for alignment across cells)
68
+ anytext/.style = {
69
+ font = \sffamily\scriptsize\addfontfeatures{Numbers={Monospaced,Lining}},
70
+ align = center,
71
+ inner sep = 3pt,
72
+ text depth = 0pt,
73
+ },
74
+ hdrtext/.style = {
75
+ anytext,
76
+ text = white,
77
+ fill = OBSHDRFill,
78
+ },
79
+ notetext/.style = {
80
+ anytext,
81
+ font = \sffamily\tiny,
82
+ align = left,
83
+ },
84
+ anytable/.style = {
85
+ matrix of nodes,
86
+ nodes in empty cells,
87
+ column sep = -1.0\pgflinewidth,
88
+ row sep = -1.0\pgflinewidth,
89
+ inner sep = -0.25\pgflinewidth,
90
+ outer sep = -0.25\pgflinewidth,
91
+ nodes = {anchor = center, minimum height = 12.5pt,}
92
+ },
93
+ datatable/.style = {
94
+ anytable,
95
+ nodes = {
96
+ anytext,
97
+ align = right,
98
+ draw = none,
99
+ fill = none,
100
+ green_bar_filler,
101
+ },
102
+ % execute at end matrix={
103
+ % \global\tnc=\pgf@matrix@numberofcolumns
104
+ % \global\tnr=\pgfmatrixcurrentrow
105
+ % },
106
+ },
107
+ hdrtable/.style = {
108
+ anytable,
109
+ nodes = {
110
+ hdrtext,
111
+ draw = none,
112
+ fill = OBSHDRFill,
113
+ },
114
+ },
115
+ hrow/.style = {
116
+ hdrtable,
117
+ nodes = {text width = 40pt,},
118
+ },
119
+ hcol/.style = {
120
+ hdrtable,
121
+ nodes = {text width = 60pt,},
122
+ },
123
+ }
124
+ % Define layers for later reference
125
+ % https://tex.stackexchange.com/questions/40840/put-a-node-behind-another-in-a-tikz-diagram
126
+ \pgfdeclarelayer{background}
127
+ \pgfsetlayers{background,main}
128
+
129
+
@@ -6,7 +6,7 @@ Methods to format and print summary statistics on merger enforcement patterns.
6
6
  import enum
7
7
  import shutil
8
8
  import subprocess
9
- from collections.abc import Mapping, Sequence
9
+ from collections.abc import Mapping
10
10
  from importlib import resources
11
11
  from pathlib import Path
12
12
  from types import SimpleNamespace
@@ -94,36 +94,53 @@ moe_tmpl = Template(R"""
94
94
  """)
95
95
 
96
96
  # Define the LaTeX jinja environment
97
- _tmpl_resource = resources.files(f"{_PKG_NAME}.data.jinja2_LaTeX_templates")
98
- _tmpl_folder = DATA_DIR.joinpath(_tmpl_resource.name)
97
+ _template_resource = resources.files(f"{_PKG_NAME}.data.jinja2_LaTeX_templates")
98
+ _template_folder = DATA_DIR.joinpath(_template_resource.name)
99
99
  with resources.as_file(
100
100
  resources.files(f"{_PKG_NAME}.data.jinja2_LaTeX_templates")
101
101
  ) as _tmpl_src:
102
- if not _tmpl_folder.is_dir():
103
- shutil.copytree(_tmpl_src, _tmpl_folder)
104
-
105
- LaTeX_jinja_env = Environment(
106
- block_start_string=R"((*",
107
- block_end_string="*))",
108
- variable_start_string=R"\JINVAR{",
109
- variable_end_string="}",
110
- comment_start_string=R"((#", # r'#{',
111
- comment_end_string=R"#))", # '}',
112
- line_statement_prefix="##",
113
- line_comment_prefix="%#",
114
- trim_blocks=True,
115
- lstrip_blocks=True,
116
- autoescape=select_autoescape(disabled_extensions=("tex.jinja2",)),
117
- loader=FileSystemLoader(_tmpl_folder),
118
- )
102
+ if not _template_folder.is_dir():
103
+ shutil.copytree(_tmpl_src, _template_folder)
119
104
 
120
105
  # Place files related to rendering LaTeX in output data directory
121
106
  if not (_out_path := DATA_DIR.joinpath(f"{_PKG_NAME}.cls")).is_file():
122
- shutil.move(_tmpl_folder / _out_path.name, _out_path)
107
+ shutil.move(_template_folder / _out_path.name, _out_path)
123
108
 
124
109
  # Write to LaTeX table settings file
125
- if not (_DOTTEX := DATA_DIR / Rf"{_PKG_NAME}_TikZTableSettings.tex").is_file():
126
- shutil.move(_tmpl_folder.joinpath("setup_tikz_tables.tex"), _DOTTEX)
110
+ if not (_DOTTEX := DATA_DIR / Rf"{_PKG_NAME}_TikZTableSettings.sty").is_file():
111
+ shutil.move(_template_folder / "setup_tikz_tables.sty", _DOTTEX)
112
+
113
+
114
+ def create_jinja_env(_tmpl_folder: Path = _template_folder, /) -> Environment:
115
+ """Create jinja2 environment
116
+
117
+ Loader is the FileSystemLoader initialized with the given path as
118
+ template folder
119
+
120
+ Parameters
121
+ ----------
122
+ _tmpl_folder : Path
123
+ Path to template folder
124
+
125
+ Returns
126
+ -------
127
+ Environment
128
+ jinja2 environment
129
+ """
130
+ return Environment(
131
+ block_start_string=R"((*",
132
+ block_end_string="*))",
133
+ variable_start_string=R"\JINVAR{",
134
+ variable_end_string="}",
135
+ comment_start_string=R"((#", # r'#{',
136
+ comment_end_string=R"#))", # '}',
137
+ line_statement_prefix="##",
138
+ line_comment_prefix="%#",
139
+ trim_blocks=True,
140
+ lstrip_blocks=True,
141
+ autoescape=select_autoescape(disabled_extensions=("tex.jinja2",)),
142
+ loader=FileSystemLoader(_tmpl_folder),
143
+ )
127
144
 
128
145
 
129
146
  LTX_ARRAY_LINEEND = "\\\\\n"
@@ -207,13 +224,20 @@ ZONE_DETAIL_STRINGS_DELTA = {
207
224
  4: Rf"ΔHHI ⩾ {HHI_DELTA_KNOTS[2]} pts.",
208
225
  }
209
226
 
210
- ZONE_STRINGS_LATEX = {
227
+ ZONE_STRINGS_LATEX_TIKZ = {
211
228
  0: R"\node[align = left, fill=BrightGreen] {Green Zone (Safeharbor)};",
212
229
  1: R"\node[align = left, fill=HiCoYellow] {Yellow Zone};",
213
230
  2: R"\node[align = left, fill=VibrRed] {Red Zone (SLC Presumption)};",
214
231
  fid.TTL_KEY: R"\node[align = left, fill=OBSHDRFill] {TOTAL};",
215
232
  }
216
233
 
234
+ ZONE_STRINGS_LATEX_TBLR = {
235
+ 0: R"\SetCell{l, bg=BrightGreen} {Green Zone (Safeharbor)}",
236
+ 1: R"\SetCell{l, bg=HiCoYellow} {Yellow Zone}",
237
+ 2: R"\SetCell{l, bg=VibrRed} {Red Zone (SLC Presumption)}",
238
+ fid.TTL_KEY: R"\SetCell{l, bg=OBSHDRFill} {TOTAL}",
239
+ }
240
+
217
241
  ZONE_DETAIL_STRINGS_HHI_LATEX = {
218
242
  0: Rf"HHI_{{post}} < \text{{{HHI_POST_ZONE_KNOTS[1]} pts.}}",
219
243
  1: R"HHI_{{post}} \in \text{{[{}, {}) pts. and }} ".format(
@@ -231,7 +255,7 @@ ZONE_DETAIL_STRINGS_DELTA_LATEX = {
231
255
  }
232
256
 
233
257
 
234
- def enf_stats_output(
258
+ def enf_stats_obs(
235
259
  _data_array_dict: fid.INVData,
236
260
  _data_period: str = "1996-2003",
237
261
  _table_ind_group: IndustryGroup = IndustryGroup.ALL,
@@ -242,6 +266,7 @@ def enf_stats_output(
242
266
  *,
243
267
  return_type_sel: StatsReturnSelector = StatsReturnSelector.RPT,
244
268
  sort_order: SortSelector = SortSelector.UCH,
269
+ print_format: Literal["text", "LaTeX", "LaTeX+TikZ"] = "LaTeX",
245
270
  print_to_screen: bool = True,
246
271
  ) -> tuple[list[str], list[list[str]]]:
247
272
  if _data_period not in _data_array_dict:
@@ -262,7 +287,7 @@ def enf_stats_output(
262
287
  'Statistics formatted, "{_stats_group}" not available here.'
263
288
  )
264
289
 
265
- _enf_stats_cnts = enf_stats_listing_by_group(
290
+ _enf_stats_cnts = enf_cnts_obs_by_group(
266
291
  _data_array_dict,
267
292
  _data_period,
268
293
  _table_ind_group,
@@ -271,13 +296,12 @@ def enf_stats_output(
271
296
  _enf_spec,
272
297
  )
273
298
 
274
- _print_format: Literal["text", "LaTeX"] = "text" if print_to_screen else "LaTeX"
275
299
  _enf_stats_hdr_list, _enf_stats_dat_list = _enf_stats_table_func(
276
300
  _enf_stats_cnts,
277
301
  None,
278
302
  return_type_sel=return_type_sel,
279
303
  sort_order=sort_order,
280
- print_format=_print_format,
304
+ print_format=print_format,
281
305
  )
282
306
 
283
307
  if print_to_screen:
@@ -289,13 +313,13 @@ def enf_stats_output(
289
313
  _table_evid_cond,
290
314
  )
291
315
  stats_print_rows(
292
- _enf_stats_hdr_list, _enf_stats_dat_list, print_format=_print_format
316
+ _enf_stats_hdr_list, _enf_stats_dat_list, print_format=print_format
293
317
  )
294
318
 
295
319
  return _enf_stats_hdr_list, _enf_stats_dat_list
296
320
 
297
321
 
298
- def enf_stats_listing_by_group(
322
+ def enf_cnts_obs_by_group(
299
323
  _invdata_array_dict: Mapping[str, Mapping[str, Mapping[str, fid.INVTableData]]],
300
324
  _study_period: str,
301
325
  _table_ind_grp: IndustryGroup,
@@ -312,13 +336,13 @@ def enf_stats_listing_by_group(
312
336
  match _stats_group:
313
337
  case StatsGrpSelector.FC:
314
338
  _cnts_func = enf_cnts_byfirmcount
315
- _cnts_listing_func = enf_cnts_listing_byfirmcount
339
+ _cnts_listing_func = enf_cnts_obs_byfirmcount
316
340
  case StatsGrpSelector.DL:
317
341
  _cnts_func = enf_cnts_bydelta
318
- _cnts_listing_func = enf_cnts_listing_byhhianddelta
342
+ _cnts_listing_func = enf_cnts_obs_byhhianddelta
319
343
  case StatsGrpSelector.ZN:
320
344
  _cnts_func = enf_cnts_byconczone
321
- _cnts_listing_func = enf_cnts_listing_byhhianddelta
345
+ _cnts_listing_func = enf_cnts_obs_byhhianddelta
322
346
 
323
347
  return _cnts_func(
324
348
  _cnts_listing_func(
@@ -331,7 +355,7 @@ def enf_stats_listing_by_group(
331
355
  )
332
356
 
333
357
 
334
- def enf_cnts_listing_byfirmcount(
358
+ def enf_cnts_obs_byfirmcount(
335
359
  _data_array_dict: Mapping[str, Mapping[str, Mapping[str, fid.INVTableData]]],
336
360
  _data_period: str = "1996-2003",
337
361
  _table_ind_group: IndustryGroup = IndustryGroup.ALL,
@@ -367,7 +391,7 @@ def enf_cnts_listing_byfirmcount(
367
391
  ])
368
392
 
369
393
 
370
- def enf_cnts_listing_byhhianddelta(
394
+ def enf_cnts_obs_byhhianddelta(
371
395
  _data_array_dict: Mapping[str, Mapping[str, Mapping[str, fid.INVTableData]]],
372
396
  _data_period: str = "1996-2003",
373
397
  _table_ind_group: IndustryGroup = IndustryGroup.ALL,
@@ -529,7 +553,7 @@ def enf_stats_table_onedim(
529
553
  *,
530
554
  return_type_sel: StatsReturnSelector = StatsReturnSelector.CNT,
531
555
  sort_order: SortSelector = SortSelector.UCH,
532
- print_format: Literal["text", "LaTeX"] = "LaTeX",
556
+ print_format: Literal["text", "LaTeX", "LaTeX+TikZ"] = "LaTeX",
533
557
  ) -> tuple[list[str], list[list[str]]]:
534
558
  _ndim_in: int = 1
535
559
  _dim_hdr_dict = {_v: _k for _k, _v in fid.CNT_FCOUNT_DICT.items()} | {
@@ -562,7 +586,9 @@ def enf_stats_table_onedim(
562
586
  for _stats_row in _inparr:
563
587
  _stats_hdr_str = _dim_hdr_dict[_stats_row[0]]
564
588
  _stats_hdr_list += [
565
- f"{{{_stats_hdr_str}}}" if print_format == "LaTeX" else _stats_hdr_str
589
+ f"{{{_stats_hdr_str}}}"
590
+ if print_format in ("LaTeX", "LaTeX+TikZ")
591
+ else _stats_hdr_str
566
592
  ]
567
593
 
568
594
  _stats_cnt = _stats_row[_ndim_in:]
@@ -582,11 +608,15 @@ def enf_stats_table_byzone(
582
608
  *,
583
609
  return_type_sel: StatsReturnSelector = StatsReturnSelector.CNT,
584
610
  sort_order: SortSelector = SortSelector.UCH,
585
- print_format: Literal["text", "LaTeX"] = "LaTeX",
611
+ print_format: Literal["text", "LaTeX", "LaTeX+TikZ"] = "LaTeX",
586
612
  ) -> tuple[list[str], list[list[str]]]:
587
613
  _ndim_in: int = ZONE_VALS.shape[1]
588
614
 
589
- _zone_str_dict = ZONE_STRINGS_LATEX if print_format == "LaTeX" else ZONE_STRINGS
615
+ _zone_str_dict = (
616
+ ZONE_STRINGS_LATEX_TIKZ
617
+ if print_format == "LaTeX+TikZ"
618
+ else (ZONE_STRINGS_LATEX_TBLR if print_format == "LaTeX" else ZONE_STRINGS)
619
+ )
590
620
  _zone_str_keys = list(_zone_str_dict)
591
621
 
592
622
  if sort_order == SortSelector.REV:
@@ -620,17 +650,20 @@ def enf_stats_table_byzone(
620
650
  for _stats_byzone_detail in _stats_byzone_it:
621
651
  # Only two sets of subtotals detail, so
622
652
  # a conditional expression will do here
623
- if print_format == "LaTeX":
653
+ if print_format in ("LaTeX", "LaTeX+TikZ"):
624
654
  _stats_text_color = "HiCoYellow" if _conc_zone == 1 else "BrightGreen"
625
655
  _stats_hdr_list += [
626
- R"{} {{\null\hfill \({}{}\) }};".format(
627
- rf"\node[text = {_stats_text_color}, fill = white, align = right]",
656
+ R"{} {{\null\hfill \({}{}\) }}{}".format(
657
+ rf"\node[text = {_stats_text_color}, fill = white, align = right]"
658
+ if print_format == "LaTeX+TikZ"
659
+ else rf"\SetCell{{r, fg={_stats_text_color}, bg=white}}",
628
660
  ZONE_DETAIL_STRINGS_HHI_LATEX[_stats_byzone_detail[1]],
629
661
  (
630
662
  ""
631
663
  if _stats_byzone_detail[2] == 0
632
664
  else Rf"{ZONE_DETAIL_STRINGS_DELTA_LATEX[_stats_byzone_detail[2]]}"
633
665
  ),
666
+ ";" if print_format == "LaTeX+TikZ" else "",
634
667
  )
635
668
  ]
636
669
  else:
@@ -703,14 +736,14 @@ def stats_print_rows(
703
736
  _enf_stats_dat_list: list[list[str]],
704
737
  /,
705
738
  *,
706
- print_format: Literal["text", "LaTeX"] = "text",
739
+ print_format: Literal["text", "LaTeX", "LaTeX+TikZ"] = "text",
707
740
  ) -> None:
708
741
  for _idx, _hdr in enumerate(_enf_stats_hdr_list):
709
- if print_format == "LaTeX":
742
+ if print_format in ("LaTeX", "LaTeX+TikZ"):
710
743
  _hdr_str = (
711
744
  _hdr
712
745
  if _hdr == "TOTAL"
713
- else re.fullmatch(r".*?\{(.*)\};?", _hdr)[1].strip()
746
+ else re.fullmatch(r".*\{.*\}\{(.*)\};?", _hdr)[1].strip()
714
747
  )
715
748
  print(
716
749
  _hdr_str,
@@ -829,25 +862,33 @@ def propn_ci(
829
862
 
830
863
 
831
864
  def render_table_pdf(
832
- _table_dottex_pathlist: Sequence[str], _table_coll_path: str, /
865
+ _table_collection_design: Template,
866
+ _table_collection_content: StatsContainer,
867
+ _output_tex_path: Path,
868
+ /,
833
869
  ) -> None:
834
- _table_collection_design = LaTeX_jinja_env.get_template(
835
- "mergeron_table_collection_template.tex.jinja2"
836
- )
837
- _table_collection_content = StatsContainer()
870
+ """Render table collection to PDF
871
+
872
+ Parameters
873
+ ----------
874
+ _table_collection_design
875
+ A jinja2 template for generating the LaTeX file to render
876
+
877
+ _table_collection_content
878
+ Content for jinja2 template
838
879
 
839
- _table_collection_content.path_list = _table_dottex_pathlist
880
+ _output_tex_path
881
+ Path to LaTeX output file to render to PDF
882
+ """
840
883
 
841
- with Path(DATA_DIR / _table_coll_path).open(
842
- "w", encoding="utf8"
843
- ) as _table_coll_file:
844
- _table_coll_file.write(
884
+ with _output_tex_path.open("w", encoding="utf8") as _output_tex_file:
885
+ _output_tex_file.write(
845
886
  _table_collection_design.render(tmpl_data=_table_collection_content)
846
887
  )
847
- print("\n", file=_table_coll_file)
888
+ print("\n", file=_output_tex_file)
848
889
 
849
890
  _run_rc = subprocess.run( # noqa: S603
850
- f"latexmk -f -quiet -synctex=0 -interaction=nonstopmode -file-line-error -pdflua {_table_coll_path}".split(),
891
+ f"latexmk -f -quiet -synctex=0 -interaction=nonstopmode -file-line-error -pdflua {_output_tex_path}".split(),
851
892
  check=True,
852
893
  cwd=DATA_DIR,
853
894
  )
@@ -855,9 +896,7 @@ def render_table_pdf(
855
896
  subprocess.run("latexmk -quiet -c".split(), check=True, cwd=DATA_DIR) # noqa: S603
856
897
  del _run_rc
857
898
 
858
- print(
859
- f"Tables rendered to path, {f"{Path(DATA_DIR / _table_coll_path).with_suffix(".pdf")}"}"
860
- )
899
+ print(f"Tables rendered to path, {_output_tex_path.with_suffix(".pdf")}")
861
900
 
862
901
 
863
902
  if __name__ == "__main__":
@@ -1,96 +0,0 @@
1
- % Tables in tikz, but first we need to define some colors for nonwhite text backgrounds
2
- \definecolor{OBSHDRFill}{HTML}{0a6c97}
3
- \definecolor{SIMHDRFill}{HTML}{646464}
4
- \definecolor{DataFill}{HTML}{dfeadf}
5
- % The below are definition's from Paul Tol's website, https://personal.sron.nl/~pault/
6
- \definecolor{VibrBlue}{HTML}{0077bb}
7
- \definecolor{BrightGreen}{HTML}{228833}
8
- \definecolor{HiCoYellow}{HTML}{ddaa33}
9
- \definecolor{VibrRed}{HTML}{cc3311}
10
- % Some useful documents from grokking various options used below
11
- % https://courses.helsinki.fi/sites/default/files/course-material/4611024/LaTeXandFriendsCourseInHelsinki_9_v2.pdf
12
- % https://tug.org/TUGboat/tb39-1/tb121duck-tikz.pdf
13
- % https://tug.org/TUGboat/tb41-1/tb127duck-matrix.pdf
14
- % https://tex.stackexchange.com/questions/22286/coloring-every-other-row-of-a-table-with-vertical-lines
15
- % https://tex.stackexchange.com/questions/354043/swot-matrix-with-multicolumn-and-multirow
16
- % https://tex.stackexchange.com/questions/20599/horizontal-row-separation-line-in-tikz-matrix-like-hline-in-tabular
17
- % https://tex.stackexchange.com/questions/63560/how-to-use-x-coordinate-of-a-point-and-y-coordinate-of-other-point
18
- % https://tex.stackexchange.com/questions/167944/auto-word-wrapping-in-a-node-in-tikz
19
- % https://tex.stackexchange.com/questions/132741/typewriter-in-tikz-node
20
- \tikzset{
21
- green_bar_filler/.code={%
22
- \pgfmathtruncatemacro{\itest}{ifthenelse(%
23
- \pgfmatrixcurrentcolumn==1,0,%
24
- ifthenelse(iseven(\pgfmatrixcurrentrow),1,3))}
25
- %\typeout{\the\pgfmatrixcurrentcolumn,\pgfmatrixcurrentrow->\itest}
26
- \ifcase\itest
27
- \tikzset{fill=none}%
28
- \or
29
- \tikzset{fill=DataFill}%
30
- \else
31
- \tikzset{fill=white}%
32
- \fi
33
- },
34
- get matrix dims/.code={
35
- \global\tnc=\pgf@matrix@numberofcolumns
36
- \global\tnr=\pgfmatrixcurrentrow
37
- },
38
- % If you only have numbers, text depth = 0ex; if text, text depth = 0.25ex, (may need tweaking for alignment across cells)
39
- anytext/.style = {
40
- font = \sffamily\scriptsize\addfontfeatures{Numbers={Monospaced,Lining}},
41
- align = center,
42
- inner sep = 3pt,
43
- text depth = 0pt,
44
- },
45
- hdrtext/.style = {
46
- anytext,
47
- text = white,
48
- fill = OBSHDRFill,
49
- },
50
- notetext/.style = {
51
- anytext,
52
- font = \sffamily\tiny,
53
- align = left,
54
- },
55
- anytable/.style = {
56
- matrix of nodes,
57
- nodes in empty cells,
58
- column sep = -1.0\pgflinewidth,
59
- row sep = -1.0\pgflinewidth,
60
- inner sep = -0.25\pgflinewidth,
61
- outer sep = -0.25\pgflinewidth,
62
- nodes = {anchor = center, minimum height = 12.5pt,}
63
- },
64
- datatable/.style = {
65
- anytable,
66
- nodes = {
67
- anytext,
68
- align = right,
69
- draw = none,
70
- fill = none,
71
- green_bar_filler,
72
- },
73
- },
74
- hdrtable/.style = {
75
- anytable,
76
- nodes = {
77
- hdrtext,
78
- draw = none,
79
- fill = OBSHDRFill,
80
- },
81
- },
82
- hrow/.style = {
83
- hdrtable,
84
- nodes = {text width = 40pt,},
85
- },
86
- hcol/.style = {
87
- hdrtable,
88
- nodes = {text width = 60pt,},
89
- },
90
- }
91
- % Define layers for later reference
92
- % https://tex.stackexchange.com/questions/40840/put-a-node-behind-another-in-a-tikz-diagram
93
- \pgfdeclarelayer{background}
94
- \pgfsetlayers{background,main}
95
-
96
-