cvlac-json 0.1.0__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.
- cvlac_json-0.1.0/.gitignore +19 -0
- cvlac_json-0.1.0/CHANGELOG.md +14 -0
- cvlac_json-0.1.0/LICENSE +21 -0
- cvlac_json-0.1.0/PKG-INFO +114 -0
- cvlac_json-0.1.0/README.md +79 -0
- cvlac_json-0.1.0/docs/cvlac_json_esquema.html +203 -0
- cvlac_json-0.1.0/docs/cvlac_json_esquema.md +336 -0
- cvlac_json-0.1.0/pyproject.toml +81 -0
- cvlac_json-0.1.0/src/cvlac_json/__init__.py +17 -0
- cvlac_json-0.1.0/src/cvlac_json/__main__.py +3 -0
- cvlac_json-0.1.0/src/cvlac_json/cli.py +79 -0
- cvlac_json-0.1.0/src/cvlac_json/parser.py +775 -0
- cvlac_json-0.1.0/src/cvlac_json/py.typed +0 -0
- cvlac_json-0.1.0/src/cvlac_json/ror.py +231 -0
- cvlac_json-0.1.0/src/cvlac_json/scienti.py +633 -0
- cvlac_json-0.1.0/tests/conftest.py +27 -0
- cvlac_json-0.1.0/tests/fixtures/cvlac_sintetico.html +170 -0
- cvlac_json-0.1.0/tests/test_cli.py +33 -0
- cvlac_json-0.1.0/tests/test_parser.py +126 -0
- cvlac_json-0.1.0/tests/test_ror.py +85 -0
- cvlac_json-0.1.0/tests/test_scienti.py +64 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*.egg-info/
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
.venv/
|
|
7
|
+
venv/
|
|
8
|
+
.pytest_cache/
|
|
9
|
+
.ruff_cache/
|
|
10
|
+
.coverage
|
|
11
|
+
coverage.xml
|
|
12
|
+
htmlcov/
|
|
13
|
+
# Generated CvLAC outputs and saved pages: they hold personal data, keep them out of the repository
|
|
14
|
+
cvlac_[0-9]*.json
|
|
15
|
+
cvlac_[0-9]*.html
|
|
16
|
+
# Never commit credentials
|
|
17
|
+
.env
|
|
18
|
+
.pypirc
|
|
19
|
+
*apikey*
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Cambios
|
|
2
|
+
|
|
3
|
+
El formato sigue [Keep a Changelog](https://keepachangelog.com/es-ES/1.1.0/) y las versiones, [versionado semántico](https://semver.org/lang/es/).
|
|
4
|
+
|
|
5
|
+
## [Sin publicar]
|
|
6
|
+
|
|
7
|
+
## [0.1.0] - 2026-10-28
|
|
8
|
+
|
|
9
|
+
### Agregado
|
|
10
|
+
- Comando `cvlac-json` y función `cvlac_json.extract()`, para Python 3.10 o superior, sin dependencias.
|
|
11
|
+
- Perfil, identificadores, formación, experiencia (con años y ROR), áreas, idiomas, líneas, reconocimientos, proyectos, eventos y todas las demás secciones.
|
|
12
|
+
- Producción bibliográfica en el esquema de obras de ImpactU, con las afiliaciones del dueño del CV según el año.
|
|
13
|
+
- Tesis dirigidas con título, director, codirectores, estudiantes, institución con ROR, estado y programa.
|
|
14
|
+
- Identificadores Scienti por DOI o título (`--scienti auto|full|off`, `--apikey`).
|
cvlac_json-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Diego Restrepo
|
|
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,114 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: cvlac-json
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Turn a researcher's public CvLAC page (Minciencias, Colombia) into one JSON document, with Scienti and ROR identifiers.
|
|
5
|
+
Project-URL: Homepage, https://github.com/restrepo/cvlac-json
|
|
6
|
+
Project-URL: Repository, https://github.com/restrepo/cvlac-json
|
|
7
|
+
Project-URL: Issues, https://github.com/restrepo/cvlac-json/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/restrepo/cvlac-json/blob/main/CHANGELOG.md
|
|
9
|
+
Author-email: Diego Restrepo <restrepo@udea.edu.co>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: bibliometrics,colombia,cris,cvlac,impactu,minciencias,ror,scienti
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: Natural Language :: Spanish
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
25
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
26
|
+
Classifier: Typing :: Typed
|
|
27
|
+
Requires-Python: >=3.10
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest-cov>=5; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
32
|
+
Requires-Dist: ruff==0.17.3; extra == 'dev'
|
|
33
|
+
Requires-Dist: twine>=5; extra == 'dev'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# cvlac-json
|
|
37
|
+
|
|
38
|
+
[](https://github.com/restrepo/cvlac-json/actions/workflows/ci.yml)
|
|
39
|
+
[](https://pypi.org/project/cvlac-json/)
|
|
40
|
+
[](https://pypi.org/project/cvlac-json/)
|
|
41
|
+
|
|
42
|
+
Convierte la página pública del **CvLAC** de un investigador (Minciencias, Colombia) en un único documento JSON: perfil, formación, experiencia, producción bibliográfica en el esquema de obras de [ImpactU](https://impactu.colav.co), proyectos, eventos, tesis dirigidas y todas las demás secciones.
|
|
43
|
+
|
|
44
|
+
- Sin dependencias: solo la biblioteca estándar de Python (3.10 o superior).
|
|
45
|
+
- Agrega los **identificadores ROR** de las instituciones de la experiencia y de las tesis.
|
|
46
|
+
- Con una clave de [apis.colav.co](https://apis.colav.co), agrega los **identificadores Scienti** (`COD_RH-COD_PRODUCTO`, `-COD_PROYECTO`, `-COD_EVENTO`) de las entradas que coinciden.
|
|
47
|
+
|
|
48
|
+
## Instalación
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install cvlac-json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Uso en la terminal
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
cvlac-json 0000026549 # escribe cvlac_0000026549.json
|
|
58
|
+
cvlac-json 26549 -o zapata.json # los ceros a la izquierda se agregan solos
|
|
59
|
+
cvlac-json 0000026549 --save-html cv.html # guarda también la página descargada
|
|
60
|
+
cvlac-json 0000026549 --html cv.html # analiza una página guardada, sin descargar
|
|
61
|
+
cvlac-json 0000026549 -o - # JSON por la salida estándar
|
|
62
|
+
cvlac-json 0000026549 --scienti off --ror off # solo la página pública, sin otras APIs
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
| Opción | Efecto |
|
|
66
|
+
| --- | --- |
|
|
67
|
+
| `--scienti auto` (por defecto) | Si hay clave de apis.colav.co, agrega los ids Scienti de las entradas que coinciden. |
|
|
68
|
+
| `--scienti full` | Además agrega los registros de Scienti que no están en la página (`origin: "scienti"`). |
|
|
69
|
+
| `--scienti off` | No consulta Scienti. |
|
|
70
|
+
| `--institution`, `--model-year` | Volcado de Scienti (`udea`, `univalle`, `uec`, `unaula`) y año del modelo. |
|
|
71
|
+
| `--apikey CLAVE` | Clave de apis.colav.co para esta ejecución. |
|
|
72
|
+
| `--ror auto` / `off` | Consulta o no el registro ROR. |
|
|
73
|
+
|
|
74
|
+
La clave de apis.colav.co se toma, en este orden, de `--apikey`, de la variable de entorno `COLAV_APIKEY` o del archivo `~/.config/colav/apikey`. Nunca se imprime. Para no dejarla en el historial de la terminal, use `--apikey "$(cat archivo)"`.
|
|
75
|
+
|
|
76
|
+
## Uso como biblioteca
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from cvlac_json import extract
|
|
80
|
+
|
|
81
|
+
data = extract("0000026549", scienti="off") # descarga y analiza la página
|
|
82
|
+
print(data["profile"]["Nombre"], len(data["works"]))
|
|
83
|
+
|
|
84
|
+
html = open("cv.html", encoding="latin-1").read()
|
|
85
|
+
data = extract("0000026549", html=html, ror=False) # página guardada
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Esquema del JSON
|
|
89
|
+
|
|
90
|
+
El esquema completo, campo por campo, está en [docs/cvlac_json_esquema.md](docs/cvlac_json_esquema.md) y en versión navegable en [docs/cvlac_json_esquema.html](docs/cvlac_json_esquema.html).
|
|
91
|
+
|
|
92
|
+
## Desarrollo
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
git clone https://github.com/restrepo/cvlac-json.git
|
|
96
|
+
cd cvlac-json
|
|
97
|
+
python -m pip install -e ".[dev]"
|
|
98
|
+
python -m pytest
|
|
99
|
+
ruff check . && ruff format --check .
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Las pruebas no usan la red: corren sobre una página sintética (`tests/fixtures/cvlac_sintetico.html`) con una persona ficticia y la misma estructura HTML del CvLAC.
|
|
103
|
+
|
|
104
|
+
Cómo publicar una versión nueva en PyPI: [PUBLISHING.md](PUBLISHING.md).
|
|
105
|
+
|
|
106
|
+
## Avisos
|
|
107
|
+
|
|
108
|
+
- La página del CvLAC es pública, pero contiene datos personales (nombre, nacionalidad, sexo). Úselos de acuerdo con la normativa de protección de datos que aplique.
|
|
109
|
+
- Sea moderado con el servidor de Minciencias: haga una pausa de uno o dos segundos entre CV cuando procese muchos.
|
|
110
|
+
- Las afiliaciones de las obras son **inferidas** de la experiencia (dónde trabajaba la persona ese año); el CvLAC no las declara.
|
|
111
|
+
|
|
112
|
+
## Licencia
|
|
113
|
+
|
|
114
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# cvlac-json
|
|
2
|
+
|
|
3
|
+
[](https://github.com/restrepo/cvlac-json/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/cvlac-json/)
|
|
5
|
+
[](https://pypi.org/project/cvlac-json/)
|
|
6
|
+
|
|
7
|
+
Convierte la página pública del **CvLAC** de un investigador (Minciencias, Colombia) en un único documento JSON: perfil, formación, experiencia, producción bibliográfica en el esquema de obras de [ImpactU](https://impactu.colav.co), proyectos, eventos, tesis dirigidas y todas las demás secciones.
|
|
8
|
+
|
|
9
|
+
- Sin dependencias: solo la biblioteca estándar de Python (3.10 o superior).
|
|
10
|
+
- Agrega los **identificadores ROR** de las instituciones de la experiencia y de las tesis.
|
|
11
|
+
- Con una clave de [apis.colav.co](https://apis.colav.co), agrega los **identificadores Scienti** (`COD_RH-COD_PRODUCTO`, `-COD_PROYECTO`, `-COD_EVENTO`) de las entradas que coinciden.
|
|
12
|
+
|
|
13
|
+
## Instalación
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install cvlac-json
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Uso en la terminal
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cvlac-json 0000026549 # escribe cvlac_0000026549.json
|
|
23
|
+
cvlac-json 26549 -o zapata.json # los ceros a la izquierda se agregan solos
|
|
24
|
+
cvlac-json 0000026549 --save-html cv.html # guarda también la página descargada
|
|
25
|
+
cvlac-json 0000026549 --html cv.html # analiza una página guardada, sin descargar
|
|
26
|
+
cvlac-json 0000026549 -o - # JSON por la salida estándar
|
|
27
|
+
cvlac-json 0000026549 --scienti off --ror off # solo la página pública, sin otras APIs
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
| Opción | Efecto |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| `--scienti auto` (por defecto) | Si hay clave de apis.colav.co, agrega los ids Scienti de las entradas que coinciden. |
|
|
33
|
+
| `--scienti full` | Además agrega los registros de Scienti que no están en la página (`origin: "scienti"`). |
|
|
34
|
+
| `--scienti off` | No consulta Scienti. |
|
|
35
|
+
| `--institution`, `--model-year` | Volcado de Scienti (`udea`, `univalle`, `uec`, `unaula`) y año del modelo. |
|
|
36
|
+
| `--apikey CLAVE` | Clave de apis.colav.co para esta ejecución. |
|
|
37
|
+
| `--ror auto` / `off` | Consulta o no el registro ROR. |
|
|
38
|
+
|
|
39
|
+
La clave de apis.colav.co se toma, en este orden, de `--apikey`, de la variable de entorno `COLAV_APIKEY` o del archivo `~/.config/colav/apikey`. Nunca se imprime. Para no dejarla en el historial de la terminal, use `--apikey "$(cat archivo)"`.
|
|
40
|
+
|
|
41
|
+
## Uso como biblioteca
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from cvlac_json import extract
|
|
45
|
+
|
|
46
|
+
data = extract("0000026549", scienti="off") # descarga y analiza la página
|
|
47
|
+
print(data["profile"]["Nombre"], len(data["works"]))
|
|
48
|
+
|
|
49
|
+
html = open("cv.html", encoding="latin-1").read()
|
|
50
|
+
data = extract("0000026549", html=html, ror=False) # página guardada
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Esquema del JSON
|
|
54
|
+
|
|
55
|
+
El esquema completo, campo por campo, está en [docs/cvlac_json_esquema.md](docs/cvlac_json_esquema.md) y en versión navegable en [docs/cvlac_json_esquema.html](docs/cvlac_json_esquema.html).
|
|
56
|
+
|
|
57
|
+
## Desarrollo
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
git clone https://github.com/restrepo/cvlac-json.git
|
|
61
|
+
cd cvlac-json
|
|
62
|
+
python -m pip install -e ".[dev]"
|
|
63
|
+
python -m pytest
|
|
64
|
+
ruff check . && ruff format --check .
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Las pruebas no usan la red: corren sobre una página sintética (`tests/fixtures/cvlac_sintetico.html`) con una persona ficticia y la misma estructura HTML del CvLAC.
|
|
68
|
+
|
|
69
|
+
Cómo publicar una versión nueva en PyPI: [PUBLISHING.md](PUBLISHING.md).
|
|
70
|
+
|
|
71
|
+
## Avisos
|
|
72
|
+
|
|
73
|
+
- La página del CvLAC es pública, pero contiene datos personales (nombre, nacionalidad, sexo). Úselos de acuerdo con la normativa de protección de datos que aplique.
|
|
74
|
+
- Sea moderado con el servidor de Minciencias: haga una pausa de uno o dos segundos entre CV cuando procese muchos.
|
|
75
|
+
- Las afiliaciones de las obras son **inferidas** de la experiencia (dónde trabajaba la persona ese año); el CvLAC no las declara.
|
|
76
|
+
|
|
77
|
+
## Licencia
|
|
78
|
+
|
|
79
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="es">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Esquema JSON CvLAC</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root{--bg:#fbfbfa;--panel:#ffffff;--fg:#1d2127;--muted:#5f6672;--line:#e1e3e8;--accent:#0b5cad;--code-bg:#f1f3f6;--code-fg:#9a1656;--th:#f4f6f9;--mark:#ffe58a;--mark-fg:#1d2127;
|
|
9
|
+
--sans:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;--mono:ui-monospace,"SFMono-Regular",Menlo,Consolas,"Liberation Mono",monospace}
|
|
10
|
+
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--bg:#15171b;--panel:#1c1f24;--fg:#e3e5e9;--muted:#9aa1ad;--line:#2f343c;--accent:#6aaeff;--code-bg:#262a31;--code-fg:#f39ac9;--th:#22262c;--mark:#7a6512;--mark-fg:#fff6d6;color-scheme:dark}}
|
|
11
|
+
:root[data-theme="dark"]{--bg:#15171b;--panel:#1c1f24;--fg:#e3e5e9;--muted:#9aa1ad;--line:#2f343c;--accent:#6aaeff;--code-bg:#262a31;--code-fg:#f39ac9;--th:#22262c;--mark:#7a6512;--mark-fg:#fff6d6;color-scheme:dark}
|
|
12
|
+
*{box-sizing:border-box}
|
|
13
|
+
html{scroll-padding-top:16px}
|
|
14
|
+
body{margin:0;background:var(--bg);color:var(--fg);font:15px/1.55 var(--sans)}
|
|
15
|
+
a{color:var(--accent)}
|
|
16
|
+
.layout{display:grid;grid-template-columns:270px minmax(0,1fr);min-height:100vh}
|
|
17
|
+
aside{position:sticky;top:0;height:100vh;overflow:auto;border-right:1px solid var(--line);background:var(--panel);padding:18px 14px}
|
|
18
|
+
aside .t{font-weight:650;font-size:14px;margin:0 6px 10px}
|
|
19
|
+
aside nav a{display:block;padding:4px 8px;border-radius:5px;color:var(--fg);text-decoration:none;font-size:13.5px}
|
|
20
|
+
aside nav a:hover{background:var(--th)}
|
|
21
|
+
aside nav a.on{background:var(--th);color:var(--accent);font-weight:600}
|
|
22
|
+
.search{margin:0 4px 12px}
|
|
23
|
+
.search input{width:100%;padding:7px 9px;border:1px solid var(--line);border-radius:6px;background:var(--bg);color:var(--fg);font:inherit;font-size:13.5px}
|
|
24
|
+
.search .n{font-size:12px;color:var(--muted);margin-top:4px;min-height:16px}
|
|
25
|
+
.theme{margin:14px 4px 0;font-size:12.5px;color:var(--muted)}
|
|
26
|
+
.theme button{font:inherit;font-size:12.5px;border:1px solid var(--line);background:var(--bg);color:var(--fg);border-radius:5px;padding:2px 8px;cursor:pointer}
|
|
27
|
+
main{padding:28px 40px 80px;max-width:1180px;min-width:0}
|
|
28
|
+
h1{font-size:28px;margin:0 0 6px;line-height:1.2}
|
|
29
|
+
.sub{color:var(--muted);margin:0 0 22px}
|
|
30
|
+
h2{font-size:20px;margin:36px 0 10px;padding-top:6px;border-top:1px solid var(--line)}
|
|
31
|
+
h2 .anchor{color:inherit;text-decoration:none}
|
|
32
|
+
p,ul{max-width:82ch}
|
|
33
|
+
li{margin:3px 0}
|
|
34
|
+
code{font-family:var(--mono);font-size:.86em;background:var(--code-bg);color:var(--code-fg);padding:1px 5px;border-radius:4px;overflow-wrap:anywhere}
|
|
35
|
+
pre{background:var(--code-bg);padding:12px 14px;border-radius:7px;overflow:auto;max-width:100%}
|
|
36
|
+
pre code{background:none;padding:0;color:var(--fg);font-size:13px}
|
|
37
|
+
.tw{overflow-x:auto;margin:12px 0 18px;border:1px solid var(--line);border-radius:8px;background:var(--panel)}
|
|
38
|
+
table{border-collapse:collapse;width:100%;font-size:14px}
|
|
39
|
+
th,td{text-align:left;vertical-align:top;padding:7px 11px;border-bottom:1px solid var(--line)}
|
|
40
|
+
th{background:var(--th);font-weight:600;font-size:13px;position:sticky;top:0}
|
|
41
|
+
tbody tr:last-child td{border-bottom:0}
|
|
42
|
+
td:first-child code{white-space:nowrap}
|
|
43
|
+
mark{background:var(--mark);color:var(--mark-fg);border-radius:2px}
|
|
44
|
+
tr.hide,.sec.hide{display:none}
|
|
45
|
+
.foot{margin-top:48px;color:var(--muted);font-size:13px}
|
|
46
|
+
@media (max-width:860px){.layout{grid-template-columns:minmax(0,1fr)}aside{position:static;height:auto;border-right:0;border-bottom:1px solid var(--line)}aside nav{display:none}main{padding:20px 16px 60px}td:first-child code{white-space:normal}}
|
|
47
|
+
@media print{aside{display:none}.layout{display:block}main{max-width:none;padding:0}th{position:static}}
|
|
48
|
+
</style>
|
|
49
|
+
</head>
|
|
50
|
+
<body>
|
|
51
|
+
<div class="layout">
|
|
52
|
+
<aside>
|
|
53
|
+
<div class="t">Esquema JSON del CvLAC</div>
|
|
54
|
+
<div class="search"><input id="q" type="search" placeholder="Buscar campo o texto…" autocomplete="off" aria-label="Buscar en el esquema"><div class="n" id="n"></div></div>
|
|
55
|
+
<nav id="toc"><a href="#1-cómo-se-genera">1. Cómo se genera</a>
|
|
56
|
+
<a href="#2-convenciones-generales">2. Convenciones generales</a>
|
|
57
|
+
<a href="#3-identificadores">3. Identificadores</a>
|
|
58
|
+
<a href="#4-nivel-superior">4. Nivel superior</a>
|
|
59
|
+
<a href="#5-profile">5. <code>profile</code></a>
|
|
60
|
+
<a href="#6-identifiers-y-academic_networks">6. <code>identifiers</code> y <code>academic_networks</code></a>
|
|
61
|
+
<a href="#7-educationacademic-y-educationcomplementary">7. <code>education.academic[]</code> y <code>education.complementary[]</code></a>
|
|
62
|
+
<a href="#8-experience">8. <code>experience[]</code></a>
|
|
63
|
+
<a href="#9-languages-research_lines-awards">9. <code>languages[]</code>, <code>research_lines[]</code>, <code>awards[]</code></a>
|
|
64
|
+
<a href="#10-works-producción-bibliográfica-esquema-de-obras-de-impactu">10. <code>works[]</code>: producción bibliográfica (esquema de obras de ImpactU)</a>
|
|
65
|
+
<a href="#11-projects">11. <code>projects[]</code></a>
|
|
66
|
+
<a href="#12-events">12. <code>events[]</code></a>
|
|
67
|
+
<a href="#13-sections-demás-secciones">13. <code>sections</code>: demás secciones</a>
|
|
68
|
+
<a href="#14-tesis-dirigidas-sectionstrabajos-dirigidostutorías">14. Tesis dirigidas: <code>sections["Trabajos dirigidos/tutorías"][]</code></a>
|
|
69
|
+
<a href="#15-counts">15. <code>counts</code></a>
|
|
70
|
+
<a href="#16-afiliaciones-y-affiliations_from_experience">16. Afiliaciones y <code>affiliations_from_experience</code></a>
|
|
71
|
+
<a href="#17-coincidencias-con-scienti-y-objeto-scienti">17. Coincidencias con Scienti y objeto <code>scienti</code></a>
|
|
72
|
+
<a href="#18-diferencias-con---scienti-full">18. Diferencias con <code>--scienti full</code></a>
|
|
73
|
+
<a href="#19-valores-observados-cinco-cv-de-la-udea-2026-10-28">19. Valores observados (cinco CV de la UdeA, 2026-10-28)</a></nav>
|
|
74
|
+
<div class="theme">Tema: <button type="button" id="tb">automático</button></div>
|
|
75
|
+
</aside>
|
|
76
|
+
<main>
|
|
77
|
+
<h1>Esquema del JSON extraído del CvLAC</h1>
|
|
78
|
+
<p class="sub">Paquete <code>cvlac-json</code> · verificado contra cinco CV de la UdeA, 2026-10-28 · documento autocontenido</p>
|
|
79
|
+
<div id="doc"><section class="sec" id="intro">
|
|
80
|
+
<p>Este documento describe el JSON que produce el paquete <strong>cvlac-json</strong> (comando <code>cvlac-json</code> o función <code>cvlac_json.extract()</code>) a partir de la página pública del CvLAC de un investigador:</p>
|
|
81
|
+
<pre><code>https://scienti.minciencias.gov.co/cvlac/visualizador/generarCurriculoCv.do?cod_rh=COD_RH</code></pre>
|
|
82
|
+
<p>El esquema se verificó contra cinco CV reales de profesores de la UdeA (2026-10-28). Los ejemplos de este documento usan una persona ficticia (Ana María Pérez Gómez, COD_RH <code>0000000001</code>); los valores de los ejemplos imitan los reales.</p>
|
|
83
|
+
</section><section class="sec" id="1-cómo-se-genera"><h2><a class="anchor" href="#1-cómo-se-genera">1. Cómo se genera</a></h2>
|
|
84
|
+
<pre><code>cvlac-json COD_RH [-o salida.json] [--html pagina_guardada.html] [--save-html pagina.html]
|
|
85
|
+
[--scienti auto|full|off] [--institution udea] [--model-year 2024]
|
|
86
|
+
[--apikey CLAVE] [--ror auto|off]</code></pre>
|
|
87
|
+
<p>El JSON combina tres fuentes:</p>
|
|
88
|
+
<div class="tw"><table><thead><tr><th>Fuente</th><th>Qué aporta</th><th>Opción</th></tr></thead><tbody><tr><td>Página pública del CvLAC</td><td><strong>Todos los registros</strong> (perfil, formación, experiencia, productos, proyectos, eventos…)</td><td>Siempre</td></tr><tr><td>Scienti (apis.colav.co, con clave)</td><td>Solo los <strong>identificadores Scienti</strong> de las entradas que coinciden (<code>COD_RH-COD_PRODUCTO</code>, etc.) y la evidencia de la coincidencia</td><td><code>--scienti auto</code> (por defecto)</td></tr><tr><td>Scienti, registros completos</td><td>Además, los registros de Scienti que <strong>no</strong> están en la página, marcados <code>origin: "scienti"</code></td><td><code>--scienti full</code></td></tr><tr><td>ROR (api.ror.org)</td><td>Identificador ROR de las instituciones de la experiencia y de las tesis</td><td><code>--ror auto</code> (por defecto)</td></tr></tbody></table></div>
|
|
89
|
+
<p>Con la configuración por defecto, <strong>todo registro proviene de la página pública</strong>; de Scienti solo llegan ids y la evidencia de la coincidencia, y los registros que solo están en Scienti se cuentan en <code>scienti.not_on_page</code>, sin incluirlos.</p>
|
|
90
|
+
</section><section class="sec" id="2-convenciones-generales"><h2><a class="anchor" href="#2-convenciones-generales">2. Convenciones generales</a></h2>
|
|
91
|
+
<ul><li><strong>Los mismos campos en todos los registros de una colección.</strong> En <code>works</code>, <code>projects</code>, <code>events</code>, <code>experience</code>, cada lista de <code>education</code> y cada lista de <code>sections</code>, si un campo tiene valor en algún registro, aparece en todos: vale <code>[]</code> (listas) o <code>null</code> (lo demás) donde no hay dato. Lo mismo dentro de los objetos anidados (<code>source</code>, <code>cvlac</code>, <code>authors[]</code>, <code>affiliations[]</code>…).</li><li><strong>Campos vacíos en toda la colección se eliminan</strong> de esa colección. Por eso las claves pueden variar de un CV a otro (por ejemplo, un CV sin palabras clave no tiene <code>keywords</code> en sus <code>works</code>).</li><li><strong>Campos que el CvLAC nunca publica no existen</strong>: no hay <code>abstracts</code>, <code>citations_count</code>, <code>groups</code>, <code>ranking</code>, <code>language</code> ni <code>date_published</code>.</li><li><strong>Fechas</strong>: año y mes como enteros (<code>{"year": 2014, "month": 7}</code>), o cadenas ISO <code>AAAA-MM-DD</code> en eventos. No hay fechas en segundos (a diferencia de ImpactU).</li><li><strong>Textos</strong>: se conservan como aparecen en la página (mayúsculas, errores de digitación como "Coturor/asesor" o "blibliográfica").</li><li>**<code>provenance</code> / <code>source</code>** siguen la convención de ImpactU: <code>cvlac</code> (página), <code>scienti</code> (apis.colav.co), <code>ror</code> (registro ROR).</li><li><strong>Datos personales</strong>: el JSON guarda lo que muestra la página pública (nombre, nacionalidad, sexo). No incluye números de identificación. De Scienti solo se copian nombres, nunca los campos personales de sus registros de autor.</li></ul>
|
|
92
|
+
</section><section class="sec" id="3-identificadores"><h2><a class="anchor" href="#3-identificadores">3. Identificadores</a></h2>
|
|
93
|
+
<div class="tw"><table><thead><tr><th>Identificador</th><th>Formato</th><th>Ejemplo</th><th>Dónde aparece</th></tr></thead><tbody><tr><td>COD_RH (Scienti/CvLAC)</td><td>10 dígitos</td><td><code>0000000001</code></td><td><code>cod_rh</code>; <code>authors[].id</code> del dueño del CV</td></tr><tr><td>Obra del CvLAC</td><td><code>cvlac:COD_RH:n</code> (n = orden en la página)</td><td><code>cvlac:0000000001:1</code></td><td><code>works[].id</code></td></tr><tr><td>Obra solo en Scienti (<code>--scienti full</code>)</td><td><code>scienti:COD_RH-COD_PRODUCTO</code></td><td><code>scienti:0000000001-10</code></td><td><code>works[].id</code></td></tr><tr><td>Producto Scienti</td><td><code>COD_RH-COD_PRODUCTO</code></td><td><code>0000000001-20912</code></td><td><code>works[].external_ids</code>, <code>works[].cvlac.scienti.id</code>, <code>sections.*[].scienti.id</code></td></tr><tr><td>Proyecto Scienti</td><td><code>COD_RH-COD_PROYECTO</code></td><td><code>0000000001-1</code></td><td><code>projects[].scienti.id</code></td></tr><tr><td>Evento Scienti</td><td><code>COD_RH-COD_EVENTO</code></td><td><code>0000000001-4</code></td><td><code>events[].scienti.id</code></td></tr><tr><td>Red Scienti</td><td><code>COD_RH-COD_RED</code></td><td></td><td><code>sections["Redes de conocimiento especializado"][].scienti.id</code></td></tr><tr><td>ROR</td><td>id corto (9 caracteres) y URL</td><td><code>03bp5hc83</code>, <code>https://ror.org/03bp5hc83</code></td><td><code>affiliations[].id</code>, <code>affiliations[].external_ids</code>, <code>experience[].ror.id</code>, <code>institution.id</code></td></tr><tr><td>DOI</td><td>sin prefijo en <code>external_ids</code>, como URL en <code>doi</code></td><td><code>10.9999/synthetic.2017.003</code></td><td><code>works[]</code></td></tr></tbody></table></div>
|
|
94
|
+
</section><section class="sec" id="4-nivel-superior"><h2><a class="anchor" href="#4-nivel-superior">4. Nivel superior</a></h2>
|
|
95
|
+
<div class="tw"><table><thead><tr><th>Campo</th><th>Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td><code>cod_rh</code></td><td>string</td><td>COD_RH del investigador (10 dígitos).</td></tr><tr><td><code>url</code></td><td>string</td><td>URL de la página del CvLAC leída.</td></tr><tr><td><code>retrieved</code></td><td>string</td><td>Fecha y hora de la extracción (ISO 8601, UTC).</td></tr><tr><td><code>profile</code></td><td>object</td><td>Datos de la hoja de vida (§5).</td></tr><tr><td><code>identifiers</code></td><td>array</td><td>Identificadores de autor: ORCID, Scopus… (§6).</td></tr><tr><td><code>academic_networks</code></td><td>array</td><td>Perfiles en redes académicas y sociales: Google Scholar, ResearchGate, LinkedIn… (§6).</td></tr><tr><td><code>education</code></td><td>object</td><td><code>academic</code> (formación académica) y <code>complementary</code> (formación complementaria) (§7).</td></tr><tr><td><code>experience</code></td><td>array</td><td>Experiencia profesional, con años y ROR (§8).</td></tr><tr><td><code>areas</code></td><td>array de string</td><td>Áreas de actuación, "Gran área -- Área -- Disciplina".</td></tr><tr><td><code>languages</code></td><td>array</td><td>Idiomas (§9).</td></tr><tr><td><code>research_lines</code></td><td>array</td><td>Líneas de investigación (§9).</td></tr><tr><td><code>awards</code></td><td>array</td><td>Reconocimientos (§9).</td></tr><tr><td><code>works</code></td><td>array</td><td><strong>Producción bibliográfica</strong> en el esquema de obras de ImpactU (§10).</td></tr><tr><td><code>projects</code></td><td>array</td><td>Proyectos (§11).</td></tr><tr><td><code>events</code></td><td>array</td><td>Eventos científicos (§12).</td></tr><tr><td><code>sections</code></td><td>object</td><td>Las demás secciones del CV, por título (§13); las tesis dirigidas tienen campos estructurados (§14).</td></tr><tr><td><code>counts</code></td><td>object</td><td>Conteos (§15).</td></tr><tr><td><code>affiliations_from_experience</code></td><td>object</td><td>Resumen de la búsqueda ROR y las afiliaciones asignadas (§16).</td></tr><tr><td><code>scienti</code></td><td>object</td><td>Resumen del cruce con Scienti; solo con clave de apis.colav.co (§17).</td></tr></tbody></table></div>
|
|
96
|
+
</section><section class="sec" id="5-profile"><h2><a class="anchor" href="#5-profile">5. <code>profile</code></a></h2>
|
|
97
|
+
<p>Objeto con las filas de la tabla "Hoja de vida" de la página; las claves son las etiquetas tal como aparecen.</p>
|
|
98
|
+
<div class="tw"><table><thead><tr><th>Clave</th><th>Tipo</th><th>Ejemplo</th></tr></thead><tbody><tr><td><code>Categoría</code></td><td>string</td><td>"Investigador Asociado (I) con vigencia hasta la publicación de los resultados de la siguiente convocatoria"</td></tr><tr><td><code>Nombre</code></td><td>string</td><td>"Ana María Pérez Gómez"</td></tr><tr><td><code>Nombre en citaciones</code></td><td>string</td><td>"PÉREZ GÓMEZ, ANA MARÍA"</td></tr><tr><td><code>Nacionalidad</code></td><td>string</td><td>"Colombiana"</td></tr><tr><td><code>Sexo</code></td><td>string</td><td>"Femenino"</td></tr><tr><td><code>notes</code></td><td>array de string</td><td>Notas sueltas de la hoja de vida, p. ej. "Par evaluador reconocido por Minciencias"</td></tr></tbody></table></div>
|
|
99
|
+
<p>El nombre y el nombre en citaciones se usan para reconocer al dueño del CV entre los autores.</p>
|
|
100
|
+
</section><section class="sec" id="6-identifiers-y-academic_networks"><h2><a class="anchor" href="#6-identifiers-y-academic_networks">6. <code>identifiers</code> y <code>academic_networks</code></a></h2>
|
|
101
|
+
<div class="tw"><table><thead><tr><th>Campo</th><th>Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td><code>name</code></td><td>string</td><td>Nombre del enlace en la página, p. ej. "Autor ID (Scopus)", "Google Scholar".</td></tr><tr><td><code>url</code></td><td>string</td><td>Enlace.</td></tr><tr><td><code>source</code></td><td>string o null</td><td>Fuente normalizada: <code>orcid</code>, <code>scopus</code>, <code>scholar</code>; <code>null</code> en las demás (ResearchGate, LinkedIn).</td></tr><tr><td><code>id</code></td><td>string o null</td><td>Identificador extraído del enlace, p. ej. <code>57000000000</code> (Scopus), <code>AbCdEfGhIjKl</code> (Scholar).</td></tr></tbody></table></div>
|
|
102
|
+
</section><section class="sec" id="7-educationacademic-y-educationcomplementary"><h2><a class="anchor" href="#7-educationacademic-y-educationcomplementary">7. <code>education.academic[]</code> y <code>education.complementary[]</code></a></h2>
|
|
103
|
+
<div class="tw"><table><thead><tr><th>Campo</th><th>Tipo</th><th>Descripción</th><th>Ejemplo</th></tr></thead><tbody><tr><td><code>level</code></td><td>string</td><td>Nivel</td><td>"Doctorado", "Cursos de corta duración"</td></tr><tr><td><code>institution</code></td><td>string</td><td>Institución, como en la página</td><td>"UNIVERSIDAD DE ANTIOQUIA"</td></tr><tr><td><code>program</code></td><td>string</td><td>Programa</td><td>"Doctorado en Ingeniería"</td></tr><tr><td><code>start</code>, <code>end</code></td><td>object</td><td><code>{year, month}</code>; <code>month</code> puede ser <code>null</code></td><td><code>{"year": 2002, "month": 1}</code></td></tr><tr><td><code>dates_text</code></td><td>string</td><td>Texto original de las fechas</td><td>"Enerode2010 - Diciembrede 2014"</td></tr><tr><td><code>thesis</code></td><td>string o null</td><td>Título de la tesis (solo formación académica)</td><td></td></tr></tbody></table></div>
|
|
104
|
+
</section><section class="sec" id="8-experience"><h2><a class="anchor" href="#8-experience">8. <code>experience[]</code></a></h2>
|
|
105
|
+
<div class="tw"><table><thead><tr><th>Campo</th><th>Tipo</th><th>Descripción</th><th>Ejemplo</th></tr></thead><tbody><tr><td><code>institution</code></td><td>string</td><td>Institución o unidad, como en la página</td><td>"UNIVERSIDAD DE ANTIOQUIA", "FACULTAD DE QUIMICA FARMACEUTICA"</td></tr><tr><td><code>dedication</code></td><td>string</td><td>Dedicación</td><td>"40 horas Semanales"</td></tr><tr><td><code>period</code></td><td>string</td><td>Periodo original</td><td>"Febrero de 1995 de", "Marzo de 2006 de Actual"</td></tr><tr><td><code>start_year</code>, <code>end_year</code></td><td>integer</td><td>Años del periodo</td><td>1995, 2026</td></tr><tr><td><code>open_end</code></td><td>boolean</td><td><code>true</code> si el periodo no tiene fin: <code>end_year</code> es entonces el año actual</td><td><code>true</code></td></tr><tr><td><code>ror</code></td><td>object o null</td><td><code>{id, name, match}</code> del registro ROR aceptado; <code>null</code> si no hay</td><td><code>{"id": "03bp5hc83", "name": "Universidad de Antioquia", "match": "name"}</code></td></tr><tr><td><code>activities</code></td><td>array</td><td><code>{type, items[]}</code>: actividades de docencia, investigación, administración…</td><td></td></tr></tbody></table></div>
|
|
106
|
+
<p><strong>Regla ROR</strong>: se acepta un registro solo si uno de sus nombres, alias, etiquetas o siglas coincide con el nombre del CvLAC (sin tildes ni mayúsculas) → <code>match: "name"</code>; o si uno es prefijo del otro por palabras, con puntaje ≥ 0.9 → <code>match: "prefix"</code> (p. ej. "UNIVERSIDAD NACIONAL DE COLOMBIA SEDE MANIZALES" → Universidad Nacional de Colombia). Las facultades y departamentos casi nunca tienen ROR.</p>
|
|
107
|
+
</section><section class="sec" id="9-languages-research_lines-awards"><h2><a class="anchor" href="#9-languages-research_lines-awards">9. <code>languages[]</code>, <code>research_lines[]</code>, <code>awards[]</code></a></h2>
|
|
108
|
+
<div class="tw"><table><thead><tr><th>Objeto</th><th>Campos</th></tr></thead><tbody><tr><td><code>languages[]</code></td><td><code>language</code>, <code>speaks</code>, <code>writes</code>, <code>reads</code>, <code>understands</code> (valores como "Bueno", "Aceptable")</td></tr><tr><td><code>research_lines[]</code></td><td><code>name</code>, <code>active</code> (boolean)</td></tr><tr><td><code>awards[]</code></td><td><code>name</code>, <code>institution</code>, <code>date</code> (<code>{year, month}</code>), <code>text</code> (texto original)</td></tr></tbody></table></div>
|
|
109
|
+
</section><section class="sec" id="10-works-producción-bibliográfica-esquema-de-obras-de-impactu"><h2><a class="anchor" href="#10-works-producción-bibliográfica-esquema-de-obras-de-impactu">10. <code>works[]</code>: producción bibliográfica (esquema de obras de ImpactU)</a></h2>
|
|
110
|
+
<p>Incluye las secciones Artículos, Libros, Capítulos de libro, Textos en publicaciones no científicas, Otra producción bibliográfica, Documentos de trabajo, Libros de formación o divulgación, Manuales y guías especializadas, Traducciones, Notas científicas y Trabajos en eventos.</p>
|
|
111
|
+
<div class="tw"><table><thead><tr><th>Campo</th><th>Tipo</th><th>Descripción</th><th>Ejemplo</th></tr></thead><tbody><tr><td><code>id</code></td><td>string</td><td><code>cvlac:COD_RH:n</code></td><td><code>cvlac:0000000001:1</code></td></tr><tr><td><code>title</code></td><td>string</td><td>Título</td><td>"A synthetic benchmark for testing CvLAC parsers"</td></tr><tr><td><code>titles[]</code></td><td>array</td><td><code>{title, source: "cvlac", provenance: "cvlac"}</code></td><td></td></tr><tr><td><code>types[]</code></td><td>array</td><td>Jerarquía del tipo de producto: <code>{type, level, source, provenance}</code>; nivel 0 "Producción bibliográfica", nivel 1 la clase (Artículo, Libro, Capítulo de libro…), nivel 2 el subtipo. Son los mismos nombres que ImpactU guarda con <code>source: "scienti"</code>.</td><td></td></tr><tr><td><code>product_types[]</code></td><td>array</td><td><code>{name, source}</code> con el tipo más específico</td><td>"Publicado en revista especializada"</td></tr><tr><td><code>authors[]</code></td><td>array</td><td>Autores en el orden de la página (ver abajo)</td><td></td></tr><tr><td><code>authors_count</code></td><td>integer</td><td>Número de autores listados. El CvLAC a menudo lista solo al dueño, así que puede ser menor que el real.</td><td>1</td></tr><tr><td><code>year_published</code></td><td>integer o null</td><td>Año de publicación</td><td>2017</td></tr><tr><td><code>doi</code></td><td>string o null</td><td>DOI como URL. Se toma tal como lo reporta el CvLAC: hay DOI truncados (p. ej. <code>10.1111/1750-3841</code>, que es solo el prefijo de una revista).</td><td><code>https://doi.org/10.9999/synthetic.2017.003</code></td></tr><tr><td><code>external_ids[]</code></td><td>array</td><td><code>{provenance, source, id}</code>: <code>doi</code>, <code>isbn</code> y, si hubo coincidencia, <code>scienti</code> (<code>COD_RH-COD_PRODUCTO</code>)</td><td><code>{"provenance": "scienti", "source": "scienti", "id": "0000000001-20912"}</code></td></tr><tr><td><code>external_urls[]</code></td><td>array</td><td><code>{provenance, source, url}</code>: enlaces del ítem y el "Medio de verificación". No aparece en los cinco CV de prueba (ninguna obra tenía enlaces).</td><td></td></tr><tr><td><code>source</code></td><td>object</td><td>Revista o libro: <code>name</code>, <code>external_ids[]</code> (<code>issn</code> o <code>isbn</code>), <code>publisher</code> (<code>name</code>, <code>country</code>). En artículos, la revista con ISSN; en capítulos, el libro con ISBN; en libros no hay <code>name</code>.</td><td><code>{"name": "REVISTA DE PRUEBAS SINTETICAS", "external_ids": [{"source": "issn", "id": "1234-5679"}], …}</code></td></tr><tr><td><code>bibliographic_info</code></td><td>object o null</td><td><code>volume</code>, <code>issue</code>, <code>start_page</code>, <code>end_page</code>, <code>pages</code> (número de páginas de un libro)</td><td><code>{"volume": "12", "issue": "3", "start_page": "101", "end_page": "115"}</code></td></tr><tr><td><code>keywords[]</code></td><td>array de string</td><td>"Palabras" del ítem</td><td>"parsing"</td></tr><tr><td><code>subjects[]</code></td><td>array</td><td><code>{source: "cvlac", subjects: [{name, level}]}</code> desde las "Areas" (gran área, área, disciplina)</td><td></td></tr><tr><td><code>cvlac</code></td><td>object</td><td>Datos propios del CvLAC (ver abajo)</td><td></td></tr><tr><td><code>origin</code></td><td>string</td><td>Solo con <code>--scienti full</code>: <code>"cvlac"</code> o <code>"scienti"</code></td><td></td></tr></tbody></table></div>
|
|
112
|
+
<p>**<code>works[].authors[]</code>**</p>
|
|
113
|
+
<div class="tw"><table><thead><tr><th>Campo</th><th>Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td><code>full_name</code></td><td>string</td><td>Nombre como aparece en la cita.</td></tr><tr><td><code>id</code></td><td>string o null</td><td>COD_RH del dueño del CV; <code>null</code> para los demás autores.</td></tr><tr><td><code>external_ids[]</code></td><td>array</td><td><code>{provenance: "cvlac", source: "scienti", id: COD_RH}</code> para el dueño.</td></tr><tr><td><code>affiliations[]</code></td><td>array</td><td>Solo el dueño: instituciones de su experiencia cuyo periodo contiene <code>year_published</code> (§16). Los coautores no tienen afiliación (la página no la da).</td></tr></tbody></table></div>
|
|
114
|
+
<p>**<code>works[].cvlac</code>**</p>
|
|
115
|
+
<div class="tw"><table><thead><tr><th>Campo</th><th>Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td><code>section</code></td><td>string</td><td>Sección del CvLAC: "Artículos", "Capitulos de libro", "Libros"…</td></tr><tr><td><code>endorsed</code></td><td>boolean</td><td>Marca de verificación de la página: producto avalado y validado en la última convocatoria de medición. Su ausencia no significa que el producto no sea válido.</td></tr><tr><td><code>country</code></td><td>string o null</td><td>País de "En:" (de la revista o editorial, no de los autores).</td></tr><tr><td><code>authors_inferred</code></td><td>boolean</td><td><code>true</code> en formatos sin autores (libros de formación, manuales): se asume que el autor es el dueño del CV.</td></tr><tr><td><code>sectors[]</code>, <code>areas[]</code></td><td>array de string</td><td>Sectores y áreas del ítem, como en la página.</td></tr><tr><td><code>fields</code></td><td>object</td><td>Pares etiqueta → valor del ítem (ISSN, ed, v, fasc, DOI…).</td></tr><tr><td><code>text</code></td><td>string</td><td>Cita completa, como aparece en la página.</td></tr><tr><td><code>scienti</code></td><td>object o null</td><td>Coincidencia con Scienti (§17).</td></tr></tbody></table></div>
|
|
116
|
+
</section><section class="sec" id="11-projects"><h2><a class="anchor" href="#11-projects">11. <code>projects[]</code></a></h2>
|
|
117
|
+
<div class="tw"><table><thead><tr><th>Campo</th><th>Tipo</th><th>Descripción</th><th>Ejemplo</th></tr></thead><tbody><tr><td><code>type</code></td><td>string</td><td>Tipo de proyecto</td><td>"Investigación y desarrollo"</td></tr><tr><td><code>title</code></td><td>string</td><td>Título</td><td>"Plataforma sintética para pruebas"</td></tr><tr><td><code>start</code></td><td>object</td><td><code>{year, month}</code></td><td><code>{"year": 1998, "month": 1}</code></td></tr><tr><td><code>end</code></td><td>object o null</td><td><code>{year, month}</code> de finalización</td><td></td></tr><tr><td><code>projected_end</code></td><td>object o null</td><td><code>{year, month}</code> de finalización proyectada</td><td></td></tr><tr><td><code>duration_months</code></td><td>integer o null</td><td>Duración en meses</td><td></td></tr><tr><td><code>summary</code></td><td>string o null</td><td>Resumen</td><td></td></tr><tr><td><code>scienti</code></td><td>object o null</td><td>Coincidencia con un proyecto Scienti (§17)</td><td><code>{"id": "0000000001-1", …}</code></td></tr></tbody></table></div>
|
|
118
|
+
<p>El CvLAC no enlaza proyectos con productos: no presente un proyecto como fuente de una obra sin otra evidencia (OpenAlex <code>awards</code>, compromisos de SIIU).</p>
|
|
119
|
+
</section><section class="sec" id="12-events"><h2><a class="anchor" href="#12-events">12. <code>events[]</code></a></h2>
|
|
120
|
+
<div class="tw"><table><thead><tr><th>Campo</th><th>Tipo</th><th>Descripción</th><th>Ejemplo</th></tr></thead><tbody><tr><td><code>name</code></td><td>string</td><td>Nombre del evento</td><td>"Simposio internacional de ejemplo"</td></tr><tr><td><code>type</code></td><td>string</td><td>Tipo</td><td>"Simposio"</td></tr><tr><td><code>scope</code></td><td>string o null</td><td>Ámbito</td><td>"Internacional"</td></tr><tr><td><code>endorsed</code></td><td>boolean</td><td>Marca de verificación</td><td></td></tr><tr><td><code>start</code>, <code>end</code></td><td>string (<code>AAAA-MM-DD</code>) o null</td><td>Fechas</td><td>"2014-10-20"</td></tr><tr><td><code>place</code></td><td>string o null</td><td>Lugar</td><td>"Medellín - Universidad de Antioquia"</td></tr><tr><td><code>products[]</code></td><td>array</td><td>Productos asociados: <code>{name, type}</code> (único vínculo explícito producto–actividad del CvLAC)</td><td></td></tr><tr><td><code>institutions[]</code></td><td>array</td><td><code>{name, link}</code>; <code>link</code> es el tipo de vínculo ("Patrocinadora", "Gestionadora")</td><td></td></tr><tr><td><code>participants[]</code></td><td>array</td><td><code>{name, role}</code></td><td><code>{"name": "ANA MARIA PEREZ GOMEZ", "role": "Ponente"}</code></td></tr><tr><td><code>scienti</code></td><td>object o null</td><td>Coincidencia con un evento Scienti (§17)</td><td></td></tr></tbody></table></div>
|
|
121
|
+
</section><section class="sec" id="13-sections-demás-secciones"><h2><a class="anchor" href="#13-sections-demás-secciones">13. <code>sections</code>: demás secciones</a></h2>
|
|
122
|
+
<p>Objeto cuyas claves son los títulos de sección del CvLAC y cuyos valores son listas de ítems genéricos. Secciones vistas en los cinco CV: Trabajos dirigidos/tutorías, Jurado en comités de evaluación, Participación en comités de evaluación, Par evaluador, Cursos de corta duración, Consultorías, Informes de investigación, Informes técnicos, Demás trabajos, Fortalecimiento o solución de asuntos de interés social, Redes de conocimiento especializado, Estancias posdoctorales, Patentes, Secretos empresariales, Prototipos, Planta piloto, Softwares, Signos distintivos, Nuevos registros científicos, Innovación de proceso o procedimiento.</p>
|
|
123
|
+
<div class="tw"><table><thead><tr><th>Campo</th><th>Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td><code>type</code></td><td>string</td><td>Tipo de producto del CvLAC, niveles separados por " - " (p. ej. "Producción técnica - Cursos de corta duración dictados - Extensión extracurricular"). Falta si toda la sección lo tiene vacío.</td></tr><tr><td><code>endorsed</code></td><td>boolean</td><td>Marca de verificación.</td></tr><tr><td><code>text</code></td><td>string</td><td>Texto completo del ítem.</td></tr><tr><td><code>fields</code></td><td>object o null</td><td>Pares etiqueta → valor (<code>Finalidad</code>, <code>Institución</code>, <code>Nombre comercial</code>, <code>contrato/registro</code>…).</td></tr><tr><td><code>keywords[]</code>, <code>areas[]</code>, <code>sectors[]</code></td><td>array de string</td><td>Palabras, áreas y sectores del ítem.</td></tr><tr><td><code>links[]</code></td><td>array</td><td>Enlaces del ítem; no aparece en los cinco CV de prueba.</td></tr><tr><td><code>year</code></td><td>integer o null</td><td>Año detectado en el texto.</td></tr><tr><td><code>scienti</code></td><td>object o null</td><td>Coincidencia con un producto o red Scienti (§17). Los pares evaluadores no son productos Scienti y no tienen id.</td></tr><tr><td><code>origin</code></td><td>string</td><td>Solo con <code>--scienti full</code>.</td></tr></tbody></table></div>
|
|
124
|
+
</section><section class="sec" id="14-tesis-dirigidas-sectionstrabajos-dirigidostutorías"><h2><a class="anchor" href="#14-tesis-dirigidas-sectionstrabajos-dirigidostutorías">14. Tesis dirigidas: <code>sections["Trabajos dirigidos/tutorías"][]</code></a></h2>
|
|
125
|
+
<p>Además de los campos genéricos, cada ítem tiene campos estructurados, leídos de la estructura de la página (el CvLAC separa con <code>&nbsp;</code> "DUEÑO, Título" / institución / "Estado: …" / programa / "AÑO. Dirigió como: ROL" / estudiantes / "N meses" / "Tutor(es)/Cotutor(es): …").</p>
|
|
126
|
+
<p>Texto de origen:</p>
|
|
127
|
+
<pre><code>ANA MARIA PEREZ GOMEZ, Análisis de datos sintéticos para la evaluación de algoritmos
|
|
128
|
+
UNIVERSIDAD DE ANTIOQUIA Estado: Tesis en curso Doctorado en Ingeniería Electrónica, 2017.
|
|
129
|
+
Dirigió como: Tutor principal, Persona(s) orientada(s): Carlos Andrés Ruiz Mejía Tutor(es)/Cotutor(es): ANA MARIA PEREZ GOMEZ,</code></pre>
|
|
130
|
+
<div class="tw"><table><thead><tr><th>Campo</th><th>Tipo</th><th>Descripción</th><th>Ejemplo</th></tr></thead><tbody><tr><td><code>title</code></td><td>string</td><td>Texto entre el nombre del dueño y la institución, sin el punto final</td><td>"Análisis de datos sintéticos para la evaluación de algoritmos"</td></tr><tr><td><code>titles[]</code></td><td>array</td><td><code>{title, source: "cvlac", provenance: "cvlac"}</code></td><td></td></tr><tr><td><code>authors[]</code></td><td>array</td><td>Personas de la tesis (ver abajo)</td><td></td></tr><tr><td><code>institution</code></td><td>object</td><td><code>{name, id, ror_name, ror_match}</code>: institución tras el título, con su ROR</td><td><code>{"name": "UNIVERSIDAD DE ANTIOQUIA", "id": "03bp5hc83", "ror_name": "Universidad de Antioquia", "ror_match": "name"}</code></td></tr><tr><td><code>status</code></td><td>string</td><td><code>completed</code> ("Tesis concluida") u <code>ongoing</code> ("Tesis en curso"); otro valor se deja como está</td><td><code>ongoing</code></td></tr><tr><td><code>status_text</code></td><td>string</td><td>Texto original del estado</td><td>"Tesis en curso"</td></tr><tr><td><code>program</code></td><td>string o null</td><td>Programa, tras el estado; <code>null</code> si la página no lo da</td><td>"Doctorado en Ingeniería Electrónica"</td></tr><tr><td><code>role</code></td><td>string o null</td><td>"Dirigió como"</td><td>"Tutor principal", "Coturor/asesor"</td></tr><tr><td><code>duration_months</code></td><td>integer o null</td><td>"N meses", si aparece</td><td></td></tr><tr><td><code>year</code></td><td>integer</td><td>Año de la tesis</td><td>2017</td></tr></tbody></table></div>
|
|
131
|
+
<p>**<code>authors[]</code> de una tesis**</p>
|
|
132
|
+
<div class="tw"><table><thead><tr><th>Campo</th><th>Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td><code>full_name</code></td><td>string</td><td>Nombre como en la página.</td></tr><tr><td><code>type</code></td><td>string</td><td><code>advisor</code>: el dueño, si "Dirigió como" es "Tutor principal" (o falta). <code>co-advisor</code>: el dueño, si es "Cotutor/asesor", y las demás personas de "Tutor(es)/Cotutor(es)" distintas del dueño y de los estudiantes. <code>student</code>: las "Persona(s) orientada(s)". Cuando el dueño es solo cotutor, la página no dice quién fue el tutor principal y todos los demás tutores quedan como <code>co-advisor</code>.</td></tr><tr><td><code>id</code></td><td>string o null</td><td>COD_RH del dueño; <code>null</code> para los demás.</td></tr><tr><td><code>external_ids[]</code></td><td>array</td><td>El COD_RH del dueño.</td></tr><tr><td><code>affiliations[]</code></td><td>array</td><td>Para <code>advisor</code> y <code>student</code>: la institución de la tesis con su ROR, <code>years: [año]</code> y <code>cvlac.provenance: "cvlac thesis"</code>. Los cotutores no tienen afiliación.</td></tr></tbody></table></div>
|
|
133
|
+
</section><section class="sec" id="15-counts"><h2><a class="anchor" href="#15-counts">15. <code>counts</code></a></h2>
|
|
134
|
+
<p>Objeto de conteos (enteros):</p>
|
|
135
|
+
<div class="tw"><table><thead><tr><th>Clave</th><th>Significado</th></tr></thead><tbody><tr><td><code>works</code>, <code>projects</code>, <code>events</code>, <code>education</code></td><td>Registros de cada parte.</td></tr><tr><td><code>works:<sección></code></td><td>Obras por sección, p. ej. <code>works:Artículos</code>.</td></tr><tr><td><code><título de sección></code></td><td>Ítems de cada sección de <code>sections</code>.</td></tr><tr><td><code>endorsed_works</code></td><td>Obras con la marca de verificación.</td></tr><tr><td><code>works_with_affiliation</code></td><td>Obras con al menos una afiliación del dueño.</td></tr><tr><td><code>works_only_in_scienti</code>, <code>section_items_only_in_scienti</code>, …</td><td>Solo con <code>--scienti full</code>.</td></tr></tbody></table></div>
|
|
136
|
+
</section><section class="sec" id="16-afiliaciones-y-affiliations_from_experience"><h2><a class="anchor" href="#16-afiliaciones-y-affiliations_from_experience">16. Afiliaciones y <code>affiliations_from_experience</code></a></h2>
|
|
137
|
+
<p>Las afiliaciones siguen la forma de ImpactU:</p>
|
|
138
|
+
<div class="tw"><table><thead><tr><th>Campo</th><th>Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td><code>id</code></td><td>string</td><td>ROR corto; <code>""</code> o <code>null</code> si no se encontró ROR.</td></tr><tr><td><code>name</code></td><td>string</td><td>Nombre ROR (o el del CvLAC si no hay ROR).</td></tr><tr><td><code>types[]</code></td><td>array</td><td><code>{source: "ror", type}</code>: tipos ROR, p. ej. <code>education</code>, <code>funder</code> (los únicos vistos en los cinco CV), <code>company</code>, <code>government</code>.</td></tr><tr><td><code>external_ids[]</code></td><td>array</td><td><code>{provenance: "ror", source, id}</code>: <code>ror</code> (URL), <code>grid</code>, <code>isni</code>, <code>wikidata</code>, <code>fundref</code>.</td></tr><tr><td><code>addresses[]</code></td><td>array</td><td><code>{city, country, country_code}</code> del registro ROR.</td></tr><tr><td><code>years[]</code></td><td>array de integer</td><td>En obras: todos los años de los periodos de experiencia. En tesis: el año de la tesis.</td></tr><tr><td><code>cvlac</code></td><td>object</td><td><code>provenance</code> ("cvlac experience" o "cvlac thesis"), <code>names[]</code> (nombres del CvLAC), <code>periods[]</code> (<code>{period, dedication}</code>, solo experiencia), <code>ror_match</code>.</td></tr></tbody></table></div>
|
|
139
|
+
<p>En las obras, la afiliación es <strong>inferida</strong>: significa "el dueño trabajaba allí ese año", no que el CvLAC declare dónde se hizo la obra. Con dos empleos simultáneos aparecen ambos; varias entradas de la misma institución se fusionan en una.</p>
|
|
140
|
+
<p><code>affiliations_from_experience</code> resume el proceso: <code>ror_api</code>, <code>experience</code> (entradas de experiencia), <code>experience_with_ror</code>, <code>works_with_affiliation</code>, <code>theses_with_affiliation</code>, <code>lookup_errors</code>.</p>
|
|
141
|
+
</section><section class="sec" id="17-coincidencias-con-scienti-y-objeto-scienti"><h2><a class="anchor" href="#17-coincidencias-con-scienti-y-objeto-scienti">17. Coincidencias con Scienti y objeto <code>scienti</code></a></h2>
|
|
142
|
+
<p><strong>Objeto de coincidencia</strong> (<code>works[].cvlac.scienti</code>, <code>projects[].scienti</code>, <code>events[].scienti</code>, <code>sections.*[].scienti</code>):</p>
|
|
143
|
+
<div class="tw"><table><thead><tr><th>Campo</th><th>Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td><code>id</code></td><td>string</td><td>Id Scienti (<code>COD_RH-COD_…</code>).</td></tr><tr><td><code>by</code></td><td>string</td><td>Regla: <code>doi</code>, <code>title</code>, <code>title prefix</code> (Scienti trunca títulos largos) o, con <code>--scienti full</code>, <code>not on the CvLAC page</code>.</td></tr><tr><td><code>evidence[]</code></td><td>array de string</td><td>Evidencia adicional: <code>year</code>, <code>issn</code>, <code>isbn</code>, <code>venue</code>, <code>patent number</code>.</td></tr><tr><td><code>shared</code></td><td>boolean</td><td><code>true</code> si el registro Scienti ya se había asignado a otra entrada (duplicados en el CvLAC).</td></tr><tr><td><code>scienti_title</code>, <code>scienti_year</code></td><td>string, integer</td><td>Título y año del registro Scienti.</td></tr></tbody></table></div>
|
|
144
|
+
<p><strong>Reglas de coincidencia</strong>: (1) mismo DOI normalizado; (2) mismo título normalizado (≥ 25 caracteres y 4 palabras) más una evidencia: año, ISSN, ISBN, revista/libro/evento o número de patente; en ítems genéricos, el título Scienti debe aparecer completo en el texto; (3) un título prefijo del otro (ambos ≥ 40 caracteres) con el mismo año; (4) proyectos, eventos y redes: mismo nombre normalizado y mismo año.</p>
|
|
145
|
+
<p>**Objeto <code>scienti</code> del nivel superior**:</p>
|
|
146
|
+
<div class="tw"><table><thead><tr><th>Campo</th><th>Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td><code>institution</code>, <code>model_year</code></td><td>string</td><td>Volcado de Scienti usado (p. ej. <code>udea</code>, <code>2024</code>). Sin <code>--institution</code>, se prueba udea, univalle, uec y unaula, en ese orden.</td></tr><tr><td><code>source</code></td><td>string</td><td><code>apis.colav.co</code></td></tr><tr><td><code>products</code>, <code>products_matched</code></td><td>integer</td><td>Productos Scienti del COD_RH y cuántos coincidieron.</td></tr><tr><td><code>matched</code></td><td>object</td><td>Coincidencias por parte: <code>works</code>, <code>section_items</code>, <code>projects</code>, <code>events</code>, <code>networks</code>.</td></tr><tr><td><code>records</code></td><td>object</td><td>Registros Scienti recibidos: <code>projects</code>, <code>events</code>, <code>networks</code>, <code>patents</code>.</td></tr><tr><td><code>rules</code></td><td>string</td><td>Descripción de las reglas aplicadas.</td></tr><tr><td><code>not_on_page</code></td><td>object</td><td>Registros Scienti sin coincidencia, por la sección a la que pertenecerían: <code>works</code>, <code>sections</code> (por título), <code>projects</code>, <code>events</code>, <code>networks</code>. Con <code>--scienti full</code> se llama <code>added_from_scienti</code> y esos registros se agregan al JSON.</td></tr><tr><td><code>not_on_page_note</code></td><td>string</td><td>Explicación del campo anterior.</td></tr><tr><td><code>note</code></td><td>string</td><td>Solo si el COD_RH no está en ningún volcado.</td></tr></tbody></table></div>
|
|
147
|
+
</section><section class="sec" id="18-diferencias-con---scienti-full"><h2><a class="anchor" href="#18-diferencias-con---scienti-full">18. Diferencias con <code>--scienti full</code></a></h2>
|
|
148
|
+
<ul><li>Se agregan a <code>works</code> las obras bibliográficas que solo están en Scienti, con <code>id</code> <code>scienti:COD_RH-COD_PRODUCTO</code>, <code>types[]</code> con <code>source: "scienti"</code> y el <code>code</code> del tipo, autores en orden (<code>re_author_others</code>), revista/libro/evento, volumen y páginas, palabras clave, y <code>cvlac: {section, scienti}</code>.</li><li>Se agregan a <code>sections</code> los demás productos (a la sección cuyos ítems comparten al menos dos niveles del tipo), a <code>projects</code> y <code>events</code> los proyectos y eventos de Scienti sin coincidencia.</li><li>Todos los registros llevan <code>origin</code> (<code>"cvlac"</code> o <code>"scienti"</code>), y <code>counts</code> incluye <code>*_only_in_scienti</code>.</li><li>Muchos de esos registros repiten una entrada de la página que no pasó la regla exacta (sobre todo jurados y comités): revíselos antes de contarlos como producción adicional.</li></ul>
|
|
149
|
+
</section><section class="sec" id="19-valores-observados-cinco-cv-de-la-udea-2026-10-28"><h2><a class="anchor" href="#19-valores-observados-cinco-cv-de-la-udea-2026-10-28">19. Valores observados (cinco CV de la UdeA, 2026-10-28)</a></h2>
|
|
150
|
+
<div class="tw"><table><thead><tr><th></th><th>Mínimo</th><th>Máximo</th></tr></thead><tbody><tr><td>Obras</td><td>36</td><td>182</td></tr><tr><td>Proyectos</td><td>5</td><td>43</td></tr><tr><td>Eventos</td><td>16</td><td>53</td></tr><tr><td>Tesis dirigidas</td><td>8</td><td>72</td></tr><tr><td>Obras con id Scienti</td><td>32 de 36</td><td>182 de 182</td></tr></tbody></table></div></section>
|
|
151
|
+
</div>
|
|
152
|
+
<p class="foot">Generado desde <code>docs/cvlac_json_esquema.md</code>. </p>
|
|
153
|
+
</main>
|
|
154
|
+
</div>
|
|
155
|
+
<script>
|
|
156
|
+
(() => {
|
|
157
|
+
const q = document.getElementById("q"), n = document.getElementById("n");
|
|
158
|
+
const secs = [...document.querySelectorAll("#doc .sec")];
|
|
159
|
+
const orig = new Map();
|
|
160
|
+
secs.forEach(s => orig.set(s, s.innerHTML));
|
|
161
|
+
const esc = s => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
162
|
+
function mark(el, re) {
|
|
163
|
+
const w = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);
|
|
164
|
+
const nodes = []; while (w.nextNode()) nodes.push(w.currentNode);
|
|
165
|
+
nodes.forEach(t => {
|
|
166
|
+
if (!re.test(t.nodeValue)) return; re.lastIndex = 0;
|
|
167
|
+
const span = document.createElement("span");
|
|
168
|
+
span.innerHTML = t.nodeValue.replace(/[&<>]/g, c => ({"&":"&","<":"<",">":">"}[c])).replace(re, m => "<mark>" + m + "</mark>");
|
|
169
|
+
t.replaceWith(span); re.lastIndex = 0;
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
let h;
|
|
173
|
+
q.addEventListener("input", () => { clearTimeout(h); h = setTimeout(run, 120); });
|
|
174
|
+
function run() {
|
|
175
|
+
const v = q.value.trim();
|
|
176
|
+
secs.forEach(s => { s.innerHTML = orig.get(s); s.classList.remove("hide"); });
|
|
177
|
+
if (!v) { n.textContent = ""; return; }
|
|
178
|
+
const re = new RegExp(esc(v), "gi"); let rows = 0, hitSecs = 0;
|
|
179
|
+
secs.forEach(s => {
|
|
180
|
+
let any = false;
|
|
181
|
+
s.querySelectorAll("tbody tr").forEach(tr => {
|
|
182
|
+
const ok = re.test(tr.textContent); re.lastIndex = 0;
|
|
183
|
+
tr.classList.toggle("hide", !ok); if (ok) { rows++; any = true; }
|
|
184
|
+
});
|
|
185
|
+
const textHit = [...s.querySelectorAll("p,li,pre,h2")].some(e => { const ok = re.test(e.textContent); re.lastIndex = 0; return ok; });
|
|
186
|
+
if (!any && !textHit) s.classList.add("hide"); else { hitSecs++; mark(s, re); }
|
|
187
|
+
});
|
|
188
|
+
n.textContent = rows + " filas en " + hitSecs + " secciones";
|
|
189
|
+
}
|
|
190
|
+
const links = [...document.querySelectorAll("#toc a")];
|
|
191
|
+
const io = new IntersectionObserver(es => es.forEach(e => {
|
|
192
|
+
if (e.isIntersecting) links.forEach(a => a.classList.toggle("on", a.getAttribute("href") === "#" + e.target.id));
|
|
193
|
+
}), { rootMargin: "0px 0px -70% 0px" });
|
|
194
|
+
secs.forEach(s => s.id && io.observe(s));
|
|
195
|
+
const tb = document.getElementById("tb"), modes = ["automático", "claro", "oscuro"], val = {"claro":"light","oscuro":"dark"};
|
|
196
|
+
let m = 0; try { m = Math.max(0, modes.indexOf(localStorage.getItem("cvlac-schema-theme") || "automático")); } catch (e) {}
|
|
197
|
+
const apply = () => { tb.textContent = modes[m]; if (val[modes[m]]) document.documentElement.dataset.theme = val[modes[m]]; else delete document.documentElement.dataset.theme; };
|
|
198
|
+
apply();
|
|
199
|
+
tb.addEventListener("click", () => { m = (m + 1) % 3; apply(); try { localStorage.setItem("cvlac-schema-theme", modes[m]); } catch (e) {} });
|
|
200
|
+
})();
|
|
201
|
+
</script>
|
|
202
|
+
</body>
|
|
203
|
+
</html>
|