tesorotools-python 0.1.5__tar.gz → 0.1.6__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.
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/PKG-INFO +1 -1
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/_common.py +16 -8
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/note/builder.py +86 -19
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/note/lint.py +221 -31
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/note/markdown.py +93 -21
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/note/skill/SKILL.md +22 -9
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/.gitignore +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/pyproject.toml +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/__init__.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/_build_context.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/_registry.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/__init__.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/bar_line.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/barh_plot.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/box_plot.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/compact.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/intraday_plot.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/line_plot.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/matrix.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/plotly_backend.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/sankey.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/scatter.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/sharing.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/shock_plot.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/stacked.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/tikz_backend.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/type_curve.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/vector_plot.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/artists/waterfall.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/assets/README.md +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/assets/fonts/CabinetGrotesk-Black.otf +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/assets/fonts/CabinetGrotesk-Bold.otf +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/assets/fonts/CabinetGrotesk-Extrabold.otf +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/assets/fonts/CabinetGrotesk-Extralight.otf +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/assets/fonts/CabinetGrotesk-Light.otf +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/assets/fonts/CabinetGrotesk-Medium.otf +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/assets/fonts/CabinetGrotesk-Regular.otf +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/assets/fonts/CabinetGrotesk-Thin.otf +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/assets/fonts/README.md +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/assets/nota_template.dotx +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/assets/plots.yaml +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/assets/template.docx +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/assets/tesoro.mplstyle +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/data_sources/__init__.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/data_sources/debug.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/database/__init__.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/database/local.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/database/push.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/database/shared.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/dependencies/__init__.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/dependencies/node.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/dependencies/resolution.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/driver.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/__init__.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/cli.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/scaffold.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/article/main.tex.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/article/sections/01-introduccion.tex +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/article/sections/02-analisis.tex +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/article/sections/03-conclusiones.tex +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/beamer/main.tex.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/beamer/slides/01-contexto.tex +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/beamer/slides/02-analisis.tex +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/beamer/slides/03-conclusiones.tex +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/beamer/style/beamerthemeTesoro.sty +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/book/appendices/a-fuentes.tex +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/book/chapters/01-introduccion.tex +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/book/chapters/02-analisis.tex +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/book/frontmatter/resumen.tex +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/book/main.tex.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/common/README.md.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/common/dot-gitignore +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/common/dot-vscode/settings.json +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/common/figures/dot-gitkeep +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/common/fonts/README.md +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/common/latexmkrc +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/common/refs.bib +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/common/style/tesoro.sty +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/common/style/tesorobrand.sty.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/latex/templates/common/style/tesorolocal.sty.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/manifest.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/note/__init__.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/note/charts.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/note/cli.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/note/inline.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/note/issues.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/note/pdf.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/note/skeleton.md +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/note/skill/reglas.md +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/note/template.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/offsets/__init__.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/offsets/offsets.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/offsets/outliers.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/orchestration.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/palette.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/pipeline/__init__.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/pipeline/diagnose.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/pipeline/engine.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/pipeline/rules.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/providers/__init__.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/providers/base.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/providers/bde.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/providers/ecb.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/providers/fred.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/providers/imf_irfcl.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/providers/lseg.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/py.typed +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/render/__init__.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/render/content/__init__.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/render/content/content.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/render/content/images.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/render/content/section.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/render/content/subtitle.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/render/content/table.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/render/content/text.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/render/content/title.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/render/document.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/render/report.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/scaffold.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/testing/__init__.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/testing/compare.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/utils/__init__.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/utils/config.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/utils/format.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/utils/globals.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/utils/matplotlib.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/utils/series.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/utils/shortcuts.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/utils/template.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/__init__.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/app.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/brand.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/cli.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/components.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/formatting.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/launcher.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/palette.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/plotting.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/scaffold.py +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/templates/Dockerfile.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/templates/README.md.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/templates/dot-dockerignore.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/templates/dot-gitignore.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/templates/dot-streamlit/config.toml.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/templates/pyproject.toml.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/templates/src/$package/__init__.py.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/templates/src/$package/cli.py.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/templates/src/$package/main.py.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/templates/src/$package/sections.py.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/templates/tests/__init__.py.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/templates/tests/test_app.py.tmpl +0 -0
- {tesorotools_python-0.1.5 → tesorotools_python-0.1.6}/src/tesorotools/web/theme.py +0 -0
|
@@ -24,6 +24,7 @@ overrides only need to update ``plots.yaml``.
|
|
|
24
24
|
from __future__ import annotations
|
|
25
25
|
|
|
26
26
|
import math
|
|
27
|
+
import warnings
|
|
27
28
|
from collections.abc import Sequence
|
|
28
29
|
from pathlib import Path
|
|
29
30
|
from typing import Any, Literal, Protocol, Self, cast, runtime_checkable
|
|
@@ -698,14 +699,21 @@ def date_span_ticks(
|
|
|
698
699
|
lo: float = float(cast(Any, date2num(data_min)))
|
|
699
700
|
hi: float = float(cast(Any, date2num(data_max)))
|
|
700
701
|
locator = AutoDateLocator(minticks=2, maxticks=maxticks)
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
702
|
+
# With few ticks over a long span the locator finds no interval in its
|
|
703
|
+
# table, warns and falls back to a sensible default: the fallback is
|
|
704
|
+
# the wanted result, the warning only noise for whoever draws a chart.
|
|
705
|
+
with warnings.catch_warnings():
|
|
706
|
+
warnings.filterwarnings(
|
|
707
|
+
"ignore", "AutoDateLocator was unable", UserWarning
|
|
708
|
+
)
|
|
709
|
+
candidates: list[float] = cast(
|
|
710
|
+
"list[float]", locator.tick_values(data_min, data_max)
|
|
711
|
+
)
|
|
712
|
+
if not pin_start:
|
|
713
|
+
return [t for t in candidates if lo <= t <= hi] or [lo, hi]
|
|
714
|
+
chosen: Any = locator.get_locator( # type: ignore[reportUnknownMemberType]
|
|
715
|
+
data_min, data_max
|
|
716
|
+
)
|
|
709
717
|
if isinstance(chosen, YearLocator):
|
|
710
718
|
step = int(cast(Any, chosen.base).step)
|
|
711
719
|
if step > 1:
|
|
@@ -55,6 +55,7 @@ from docx.oxml import OxmlElement, parse_xml # type: ignore[reportUnknownVariab
|
|
|
55
55
|
from docx.oxml.ns import qn
|
|
56
56
|
from docx.shared import Cm, Emu, Pt, Twips
|
|
57
57
|
from docx.table import Table as DocxTable
|
|
58
|
+
from docx.text.run import Run
|
|
58
59
|
from docx.table import _Cell # pyright: ignore[reportPrivateUsage]
|
|
59
60
|
from docx.text.paragraph import Paragraph
|
|
60
61
|
|
|
@@ -99,6 +100,8 @@ _MIN_PAIR_SCALE = 0.9
|
|
|
99
100
|
|
|
100
101
|
#: Space after a chart or table block: that of the ``Nota`` style.
|
|
101
102
|
_BLOCK_AFTER = 160
|
|
103
|
+
#: Left indent (twips) of the text of a list item («Bullet Nivel 1»).
|
|
104
|
+
_ITEM_INDENT = 714
|
|
102
105
|
|
|
103
106
|
_CHART = "Gráfico"
|
|
104
107
|
_TABLE = "Tabla"
|
|
@@ -261,7 +264,26 @@ def format_number(
|
|
|
261
264
|
|
|
262
265
|
|
|
263
266
|
#: Cells that do not make a numeric column textual.
|
|
264
|
-
_PLACEHOLDERS = {
|
|
267
|
+
_PLACEHOLDERS = {
|
|
268
|
+
"",
|
|
269
|
+
"-",
|
|
270
|
+
"\u2013",
|
|
271
|
+
"\u2014",
|
|
272
|
+
"\u2212",
|
|
273
|
+
"\u2026",
|
|
274
|
+
"..",
|
|
275
|
+
"...",
|
|
276
|
+
"n.d.",
|
|
277
|
+
"n.d",
|
|
278
|
+
"nd",
|
|
279
|
+
"n/d",
|
|
280
|
+
"s.d.",
|
|
281
|
+
"s.d",
|
|
282
|
+
"sd",
|
|
283
|
+
"n.a.",
|
|
284
|
+
"n.a",
|
|
285
|
+
"na",
|
|
286
|
+
}
|
|
265
287
|
|
|
266
288
|
|
|
267
289
|
def _is_numeric(text: str) -> bool:
|
|
@@ -282,8 +304,13 @@ def _year_column(values: Sequence[object]) -> bool:
|
|
|
282
304
|
)
|
|
283
305
|
|
|
284
306
|
|
|
307
|
+
def _placeholder(cell: str) -> str:
|
|
308
|
+
"""*cell* lowered and without spaces («n. d.» -> «n.d.»)."""
|
|
309
|
+
return "".join(cell.split()).lower()
|
|
310
|
+
|
|
311
|
+
|
|
285
312
|
def _numeric_column(cells: Sequence[str]) -> bool:
|
|
286
|
-
values = [c for c in cells if c
|
|
313
|
+
values = [c for c in cells if _placeholder(c) not in _PLACEHOLDERS]
|
|
287
314
|
return bool(values) and all(_is_numeric(c) for c in values)
|
|
288
315
|
|
|
289
316
|
|
|
@@ -467,6 +494,18 @@ def _footnotes_root(document: Document) -> tuple[Any, Any]:
|
|
|
467
494
|
return part, _parse(part.blob)
|
|
468
495
|
|
|
469
496
|
|
|
497
|
+
def _es(value: float, spec: str = "g") -> str:
|
|
498
|
+
"""*value* with a decimal comma, for the messages («7,2 cm»)."""
|
|
499
|
+
return format(value, spec).replace(".", ",")
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
def _end_block(table: DocxTable) -> None:
|
|
503
|
+
"""The last row of *table* does not keep with what follows it."""
|
|
504
|
+
for cell in table.rows[-1].cells:
|
|
505
|
+
for paragraph in cell.paragraphs:
|
|
506
|
+
paragraph.paragraph_format.keep_with_next = False
|
|
507
|
+
|
|
508
|
+
|
|
470
509
|
def _cm(emu: float) -> float:
|
|
471
510
|
return emu / 360000
|
|
472
511
|
|
|
@@ -644,8 +683,17 @@ class Note:
|
|
|
644
683
|
self._block()
|
|
645
684
|
if level == 1:
|
|
646
685
|
self._appendix = is_appendix(text)
|
|
647
|
-
self._references = _REFERENCES.
|
|
686
|
+
self._references = _REFERENCES.search(text) is not None
|
|
648
687
|
paragraph = self._add(f"Heading{level}")
|
|
688
|
+
if self._appendix and level < 3:
|
|
689
|
+
# Annexes, references and bibliography are not numbered
|
|
690
|
+
# sections («3. Anexo I» reads as a section of the body): the
|
|
691
|
+
# numbering of the style is switched off (numId 0) and so is
|
|
692
|
+
# the hanging indent left for the number.
|
|
693
|
+
pPr = _xml(paragraph)._p.get_or_add_pPr()
|
|
694
|
+
pPr.get_or_add_numPr().get_or_add_numId().val = 0
|
|
695
|
+
paragraph.paragraph_format.left_indent = Twips(0)
|
|
696
|
+
paragraph.paragraph_format.first_line_indent = Twips(0)
|
|
649
697
|
self._write(paragraph, spans)
|
|
650
698
|
return paragraph
|
|
651
699
|
|
|
@@ -661,12 +709,20 @@ class Note:
|
|
|
661
709
|
if self._references or long_link:
|
|
662
710
|
paragraph.alignment = WD_ALIGN_PARAGRAPH.LEFT
|
|
663
711
|
|
|
664
|
-
def paragraph(self, text: str) -> Paragraph:
|
|
665
|
-
"""Body paragraph; start it with its ``**lead sentence.**``.
|
|
712
|
+
def paragraph(self, text: str, *, continuation: bool = False) -> Paragraph:
|
|
713
|
+
"""Body paragraph; start it with its ``**lead sentence.**``.
|
|
714
|
+
|
|
715
|
+
``continuation`` is a further paragraph of a list item: indented
|
|
716
|
+
like the item's text, and the list goes on after it (the next
|
|
717
|
+
item keeps its number).
|
|
718
|
+
"""
|
|
666
719
|
spans = parse_inline(text)
|
|
667
|
-
|
|
720
|
+
if not continuation:
|
|
721
|
+
self._block()
|
|
668
722
|
style = self._appendix_style() if self._appendix else "Normal"
|
|
669
723
|
paragraph = self._add(style)
|
|
724
|
+
if continuation:
|
|
725
|
+
paragraph.paragraph_format.left_indent = Twips(_ITEM_INDENT)
|
|
670
726
|
self._align(paragraph, spans)
|
|
671
727
|
self._write(paragraph, spans)
|
|
672
728
|
return paragraph
|
|
@@ -778,8 +834,9 @@ class Note:
|
|
|
778
834
|
def _shrink(self, paragraph: Paragraph) -> None:
|
|
779
835
|
"""Annex bullets and numbered items: the annex font size."""
|
|
780
836
|
if self._appendix:
|
|
781
|
-
|
|
782
|
-
|
|
837
|
+
# every run, also those inside hyperlinks (not in .runs)
|
|
838
|
+
for r in _xml(paragraph)._p.iter(qn("w:r")):
|
|
839
|
+
Run(r, paragraph).font.size = Pt(_APPENDIX_PT)
|
|
783
840
|
paragraph.paragraph_format.space_after = Pt(2)
|
|
784
841
|
|
|
785
842
|
# -- captions, sources and notes ---------------------------------------
|
|
@@ -846,13 +903,20 @@ class Note:
|
|
|
846
903
|
The block ends with the spacing of the ``Nota`` style even when
|
|
847
904
|
there is no note, so the next paragraph does not stick to it
|
|
848
905
|
(*last* is ``None`` after a table, whose end already separates).
|
|
906
|
+
Its last paragraph does not keep with the next one: the ``Fuente``
|
|
907
|
+
style (and the image) keep with the next paragraph so that the
|
|
908
|
+
block holds together, and on the last paragraph that would chain
|
|
909
|
+
the block to the following chart or heading, which would then jump
|
|
910
|
+
to the next page together and leave half a page blank.
|
|
849
911
|
"""
|
|
850
912
|
if source:
|
|
851
913
|
last = self._attribution("Fuente", source)
|
|
852
914
|
if note:
|
|
853
|
-
self._attribution("Nota", note)
|
|
915
|
+
last = self._attribution("Nota", note)
|
|
854
916
|
elif last is not None:
|
|
855
917
|
last.paragraph_format.space_after = Twips(_BLOCK_AFTER)
|
|
918
|
+
if last is not None:
|
|
919
|
+
last.paragraph_format.keep_with_next = False
|
|
856
920
|
|
|
857
921
|
# -- charts -------------------------------------------------------------
|
|
858
922
|
|
|
@@ -875,8 +939,8 @@ class Note:
|
|
|
875
939
|
width = float(Cm(chart.width_cm))
|
|
876
940
|
if chart.width_cm > TEXT_WIDTH_CM:
|
|
877
941
|
self.warnings.append(
|
|
878
|
-
f"«{chart.title}»: ancho de {chart.width_cm
|
|
879
|
-
f" el texto; se reduce a {TEXT_WIDTH_CM
|
|
942
|
+
f"«{chart.title}»: ancho de {_es(chart.width_cm)} cm, más que"
|
|
943
|
+
f" el texto; se reduce a {_es(TEXT_WIDTH_CM)} cm"
|
|
880
944
|
)
|
|
881
945
|
width = min(width, float(Cm(TEXT_WIDTH_CM)))
|
|
882
946
|
height = width * native_h / native_w
|
|
@@ -885,7 +949,7 @@ class Note:
|
|
|
885
949
|
width, height = width * scale, height * scale
|
|
886
950
|
self.warnings.append(
|
|
887
951
|
f"«{chart.title}»: la imagen no cabe en una página; se reduce"
|
|
888
|
-
f" a {_cm(width)
|
|
952
|
+
f" a {_es(_cm(width), '.1f')} x {_es(_cm(height), '.1f')} cm"
|
|
889
953
|
)
|
|
890
954
|
return round(width), round(height)
|
|
891
955
|
|
|
@@ -904,8 +968,8 @@ class Note:
|
|
|
904
968
|
and _cm(width) < _SMALL_CHART_CM
|
|
905
969
|
):
|
|
906
970
|
self.warnings.append(
|
|
907
|
-
f"«{chart.title}» mide {_cm(width)
|
|
908
|
-
f" de {TEXT_WIDTH_CM
|
|
971
|
+
f"«{chart.title}» mide {_es(_cm(width), '.1f')} cm de ancho en un texto"
|
|
972
|
+
f" de {_es(TEXT_WIDTH_CM)}: genéralo con chart_size() o ponlo en"
|
|
909
973
|
" un bloque graficos con otro"
|
|
910
974
|
)
|
|
911
975
|
self._block()
|
|
@@ -949,7 +1013,7 @@ class Note:
|
|
|
949
1013
|
if chart.width_cm > PAIR_WIDTH_CM:
|
|
950
1014
|
self.warnings.append(
|
|
951
1015
|
f"«{chart.title}»: en una pareja el ancho máximo es"
|
|
952
|
-
f" {PAIR_WIDTH_CM
|
|
1016
|
+
f" {_es(PAIR_WIDTH_CM)} cm"
|
|
953
1017
|
)
|
|
954
1018
|
cap = min(cap, chart.width_cm)
|
|
955
1019
|
caps.append(cap)
|
|
@@ -960,7 +1024,7 @@ class Note:
|
|
|
960
1024
|
if scale < _MIN_PAIR_SCALE:
|
|
961
1025
|
self.warnings.append(
|
|
962
1026
|
f"«{chart.title}»: en la pareja se reduce al"
|
|
963
|
-
f" {scale * 100
|
|
1027
|
+
f" {_es(scale * 100, '.0f')} % de su tamaño (la letra queda por debajo"
|
|
964
1028
|
" de 7 puntos); genera las imágenes con"
|
|
965
1029
|
" chart_size(pair=True) y la misma proporción"
|
|
966
1030
|
)
|
|
@@ -1006,6 +1070,7 @@ class Note:
|
|
|
1006
1070
|
# image itself it would lift this chart above the other one
|
|
1007
1071
|
if not (one_note and col) and (last is not image or rows == 2):
|
|
1008
1072
|
last.paragraph_format.space_after = Twips(_BLOCK_AFTER)
|
|
1073
|
+
_end_block(table)
|
|
1009
1074
|
|
|
1010
1075
|
def _separate_tables(self) -> None:
|
|
1011
1076
|
"""Keep a new table from merging with one that ends the body.
|
|
@@ -1152,6 +1217,8 @@ class Note:
|
|
|
1152
1217
|
_element("w:noWrap")
|
|
1153
1218
|
)
|
|
1154
1219
|
self._fit_table(grid, table, rows, size or _TABLE_PT)
|
|
1220
|
+
if not (table.source or table.note):
|
|
1221
|
+
_end_block(grid)
|
|
1155
1222
|
self._close(None, table.source, table.note)
|
|
1156
1223
|
|
|
1157
1224
|
def _fit_table(
|
|
@@ -1166,8 +1233,8 @@ class Note:
|
|
|
1166
1233
|
total = sum(table.widths)
|
|
1167
1234
|
if total > TEXT_WIDTH_CM + 0.01:
|
|
1168
1235
|
self.warnings.append(
|
|
1169
|
-
f"la tabla «{table.title}» mide {total
|
|
1170
|
-
f" el texto, {TEXT_WIDTH_CM
|
|
1236
|
+
f"la tabla «{table.title}» mide {_es(total)} cm de ancho;"
|
|
1237
|
+
f" el texto, {_es(TEXT_WIDTH_CM)} cm"
|
|
1171
1238
|
)
|
|
1172
1239
|
props = _xml(grid)._tbl.tblPr
|
|
1173
1240
|
props.find(qn("w:tblLook")).addprevious(
|
|
@@ -1185,7 +1252,7 @@ class Note:
|
|
|
1185
1252
|
if needed > TEXT_WIDTH_CM:
|
|
1186
1253
|
self.warnings.append(
|
|
1187
1254
|
f"la tabla «{table.title}» parece no caber en el ancho de la"
|
|
1188
|
-
f" página (unos {needed
|
|
1255
|
+
f" página (unos {_es(needed, '.0f')} cm de {_es(TEXT_WIDTH_CM)}):"
|
|
1189
1256
|
" abrevia las cabeceras, quita columnas o fija «anchos»"
|
|
1190
1257
|
)
|
|
1191
1258
|
|