pub-analyzer 0.3.0__tar.gz → 0.4.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.

Potentially problematic release.


This version of pub-analyzer might be problematic. Click here for more details.

Files changed (70) hide show
  1. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/PKG-INFO +5 -5
  2. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/css/main.tcss +19 -13
  3. pub_analyzer-0.4.0/pub_analyzer/internal/templates/author/author_summary.typ +112 -0
  4. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/internal/templates/author/report.typ +12 -0
  5. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/internal/templates/author/sources.typ +1 -1
  6. pub_analyzer-0.4.0/pub_analyzer/internal/templates/author/works.typ +152 -0
  7. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/internal/templates/author/works_extended.typ +1 -2
  8. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/main.py +5 -1
  9. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pyproject.toml +10 -10
  10. pub_analyzer-0.3.0/pub_analyzer/internal/templates/author/author_summary.typ +0 -97
  11. pub_analyzer-0.3.0/pub_analyzer/internal/templates/author/works.typ +0 -65
  12. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/LICENSE +0 -0
  13. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/README.md +0 -0
  14. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/__init__.py +0 -0
  15. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/css/body.tcss +0 -0
  16. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/css/buttons.tcss +0 -0
  17. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/css/checkbox.tcss +0 -0
  18. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/css/collapsible.tcss +0 -0
  19. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/css/datatable.tcss +0 -0
  20. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/css/report.tcss +0 -0
  21. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/css/search.tcss +0 -0
  22. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/css/summary.tcss +0 -0
  23. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/css/tabs.tcss +0 -0
  24. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/css/tree.tcss +0 -0
  25. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/internal/__init__.py +0 -0
  26. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/internal/identifier.py +0 -0
  27. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/internal/render.py +0 -0
  28. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/internal/report.py +0 -0
  29. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/models/__init__.py +0 -0
  30. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/models/author.py +0 -0
  31. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/models/concept.py +0 -0
  32. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/models/institution.py +0 -0
  33. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/models/report.py +0 -0
  34. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/models/source.py +0 -0
  35. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/models/topic.py +0 -0
  36. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/models/work.py +0 -0
  37. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/__init__.py +0 -0
  38. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/author/__init__.py +0 -0
  39. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/author/cards.py +0 -0
  40. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/author/core.py +0 -0
  41. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/author/tables.py +0 -0
  42. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/body.py +0 -0
  43. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/common/__init__.py +0 -0
  44. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/common/card.py +0 -0
  45. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/common/filesystem.py +0 -0
  46. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/common/filters.py +0 -0
  47. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/common/input.py +0 -0
  48. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/common/modal.py +0 -0
  49. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/common/selector.py +0 -0
  50. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/common/summary.py +0 -0
  51. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/institution/__init__.py +0 -0
  52. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/institution/cards.py +0 -0
  53. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/institution/core.py +0 -0
  54. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/institution/tables.py +0 -0
  55. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/report/__init__.py +0 -0
  56. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/report/author.py +0 -0
  57. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/report/cards.py +0 -0
  58. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/report/concept.py +0 -0
  59. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/report/core.py +0 -0
  60. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/report/export.py +0 -0
  61. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/report/grants.py +0 -0
  62. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/report/institution.py +0 -0
  63. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/report/locations.py +0 -0
  64. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/report/source.py +0 -0
  65. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/report/topic.py +0 -0
  66. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/report/work.py +0 -0
  67. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/search/__init__.py +0 -0
  68. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/search/core.py +0 -0
  69. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/search/results.py +0 -0
  70. {pub_analyzer-0.3.0 → pub_analyzer-0.4.0}/pub_analyzer/widgets/sidebar.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pub-analyzer
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: A text user interface, written in python, which automates the generation of scientific production reports using OpenAlex
5
5
  Home-page: https://github.com/alejandrgaspar/pub-analyzer
6
6
  License: MIT
@@ -23,10 +23,10 @@ Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
24
  Classifier: Typing :: Typed
25
25
  Requires-Dist: httpx (==0.27.0)
26
- Requires-Dist: jinja2 (==3.1.3)
27
- Requires-Dist: pydantic (==2.7.1)
28
- Requires-Dist: textual (==0.58.0)
29
- Requires-Dist: typst (==0.11.0)
26
+ Requires-Dist: jinja2 (==3.1.4)
27
+ Requires-Dist: pydantic (==2.7.4)
28
+ Requires-Dist: textual (==0.70.0)
29
+ Requires-Dist: typst (==0.11.1)
30
30
  Project-URL: Documentation, https://pub-analyzer.com/
31
31
  Project-URL: Repository, https://github.com/alejandrgaspar/pub-analyzer
32
32
  Description-Content-Type: text/markdown
@@ -19,20 +19,26 @@ Body {
19
19
  Footer {
20
20
  dock: bottom;
21
21
  background: $primary-color;
22
- }
23
-
24
- Footer > .footer--highlight {
25
- background: $primary-color-accent;
26
- }
27
-
28
- Footer > .footer--highlight-key {
29
- background: $primary-color-highlight;
30
- text-style: bold;
31
- }
32
22
 
33
- Footer > .footer--key {
34
- text-style: bold;
35
- background: $primary-color-accent
23
+ FooterKey {
24
+ background: $primary-color;
25
+ color: white;
26
+
27
+ .footer-key--key {
28
+ text-style: bold;
29
+ color: white;
30
+ background: $primary-color-accent;
31
+ }
32
+
33
+ &:hover {
34
+ background: $primary-color-highlight;
35
+ color: white;
36
+ text-style: bold;
37
+ .footer-key--key {
38
+ background: $primary-color-accent;
39
+ }
40
+ }
41
+ }
36
42
  }
37
43
 
38
44
  LoadingIndicator {
@@ -0,0 +1,112 @@
1
+ // Author Summary
2
+ = Author.
3
+
4
+ #let summary-card(title: "Title", body) = {
5
+ return block(
6
+ width: 100%,
7
+ height: 150pt,
8
+ fill: rgb("e5e7eb"),
9
+ stroke: 1pt,
10
+ radius: 2pt,
11
+ )[
12
+ #v(20pt)
13
+ #align(center)[#text(size: 12pt)[#title]]
14
+ #v(5pt)
15
+ #block(width: 100%, inset: (x: 20pt))[#body]
16
+ ]
17
+ }
18
+
19
+ // Cards
20
+ #grid(
21
+ columns: (1fr, 1fr, 1fr),
22
+ column-gutter: 15pt,
23
+ [
24
+ // Last institution.
25
+ #summary-card(title:"Last institution:")[
26
+ {% if report.author.last_known_institutions%}
27
+ {% set last_known_institution = report.author.last_known_institutions[0] %}
28
+ #grid(
29
+ rows: auto, row-gutter: 10pt,
30
+
31
+ [*Name:* {{ last_known_institution.display_name }}],
32
+ [*Country:* {{ last_known_institution.country_code }}],
33
+ [*Type:* {{ last_known_institution.type.value|capitalize }}],
34
+ )
35
+ {% endif %}
36
+ ]
37
+ ],
38
+ [
39
+ // Author identifiers.
40
+ #summary-card(title:"Identifiers:")[
41
+ #grid(
42
+ rows: auto, row-gutter: 10pt,
43
+ {% for key, value in report.author.ids.model_dump().items() %}
44
+ {% if value %}
45
+ [- #underline( [#link("{{ value }}")[{{ key }}]] )],
46
+ {% endif %}
47
+ {% endfor %}
48
+ )
49
+ ]
50
+ ],
51
+ [
52
+ // Citation metrics.
53
+ #summary-card(title: "Citation metrics:")[
54
+ #grid(
55
+ rows: auto, row-gutter: 10pt,
56
+
57
+ [*2-year mean:* {{ report.author.summary_stats.two_yr_mean_citedness|round(5) }}],
58
+ [*h-index:* {{ report.author.summary_stats.h_index }}],
59
+ [*i10 index:* {{ report.author.summary_stats.i10_index }}]
60
+ )
61
+ ]
62
+ ],
63
+ )
64
+
65
+ #v(10pt)
66
+ #align(center, text(11pt)[_Counts by year_])
67
+ #grid(
68
+ columns: (1fr, 1fr),
69
+ column-gutter: 15pt,
70
+ align: (auto, horizon),
71
+
72
+ [
73
+ #table(
74
+ columns: (1fr, 2fr, 2fr),
75
+ inset: 8pt,
76
+ align: horizon,
77
+ // Headers
78
+ [*Year*], [*Works count*], [*Cited by count*],
79
+
80
+ // Content
81
+ {% set max_year_count = 0 %}
82
+ {% for year_count in report.author.counts_by_year[:8] %}
83
+ [{{ year_count.year }}], [{{ year_count.works_count }}], [{{ year_count.cited_by_count }}],
84
+ {% set max_year_count = year_count %}
85
+ {% endfor %}
86
+ )
87
+ ],
88
+ grid.cell(
89
+ inset: (x: 10pt, bottom: 10pt, top: 2.5pt),
90
+ stroke: 1pt
91
+ )[
92
+ #align(center, text(10pt)[Cites by year])
93
+ #v(5pt)
94
+ #canvas(length: 100%, {
95
+ plot.plot(
96
+ size: (0.90, 0.48),
97
+ axis-style: "scientific-auto",
98
+ plot-style: (stroke: (1pt + BLUE),),
99
+ x-min: auto, x-max: auto,
100
+ x-tick-step: 1, y-tick-step: auto,
101
+ x-label: none, y-label: none,
102
+ {
103
+ plot.add((
104
+ {% for year_count in report.author.counts_by_year[:8] %}
105
+ ({{ year_count.year }}, {{ year_count.cited_by_count }}),
106
+ {% endfor %}
107
+ ))
108
+ })
109
+ })
110
+ ]
111
+ )
112
+ #pagebreak()
@@ -1,6 +1,18 @@
1
1
  // This document was generated using Pub Analyzer.
2
2
  // https://pub-analyzer.com
3
3
 
4
+ // Packages
5
+ #import "@preview/cetz:0.2.2": canvas, plot, chart, palette
6
+
7
+ // Colors
8
+ #let BLUE = rgb("#42a2f8")
9
+ #let GREEN = rgb("#82d452")
10
+ #let GRAY = rgb("#929292")
11
+ #let YELLOW = rgb("#f0bb40")
12
+ #let RED = rgb("#eb4025")
13
+ #let PURPLE = rgb("#c33375")
14
+
15
+ #let colors = (BLUE, GREEN, GRAY, YELLOW, RED, PURPLE)
4
16
 
5
17
  // Page Layoput
6
18
  #set page("us-letter")
@@ -10,7 +10,7 @@
10
10
 
11
11
  // Content
12
12
  {% for source in report.sources_summary.sources %}
13
- [#underline[3.{{ loop.index }}. #label("source_{{ source.id.path.rpartition("/")[2] }}")]],
13
+ [3.{{ loop.index }}. #label("source_{{ source.id.path.rpartition("/")[2] }}")],
14
14
  [#underline([#link("{{ source.homepage_url }}")[#"{{ source.display_name }}"]])],
15
15
  [{{ source.host_organization_name or "-" }}],
16
16
  [{{source.type }}],
@@ -0,0 +1,152 @@
1
+ // Works
2
+ = Works.
3
+
4
+ #let works_metrics_card(title: "Title", graph, body) = {
5
+ grid(
6
+ rows: (18pt, 175pt, 60pt),
7
+ columns: 100%,
8
+
9
+ [
10
+ #block(width: 100%, height: 100%)[
11
+ #align(center + horizon)[#text(style: "italic")[#title]]
12
+ ]
13
+ ],
14
+ [
15
+ #block(width: 100%, height: 100%)[
16
+ #align(center + horizon)[#graph]
17
+ ]
18
+ ],
19
+ [
20
+ #block(width: 100%, height: 100%, inset: (x: 5pt, y: 10pt))[#body]
21
+ ],
22
+ )
23
+ }
24
+
25
+ #grid(
26
+ columns: (1fr, 1fr, 1fr),
27
+ column-gutter: 15pt,
28
+ [
29
+ #let graph = {
30
+ canvas(length: 35%, {
31
+ chart.piechart(
32
+ (
33
+ {{ report.citation_summary.type_a_count }}, // Type A
34
+ {{ report.citation_summary.type_b_count }} // Type B
35
+ ),
36
+ radius: 1,
37
+ slice-style: (BLUE, GREEN),
38
+ outer-label: (content: "%", radius: 115%),
39
+ )
40
+ })
41
+ }
42
+
43
+ #works_metrics_card(title: "Citation metrics", graph)[
44
+ #grid(
45
+ rows: auto, row-gutter: 10pt,
46
+ columns: (1fr, 1fr),
47
+
48
+ grid.cell(colspan: 2)[
49
+ *Count:* {{ report.citation_summary.type_a_count + report.citation_summary.type_b_count }}
50
+ ],
51
+ [#box(height: 7pt, width: 7pt, fill: BLUE) *Type A:* {{ report.citation_summary.type_a_count }}],
52
+ [#box(height: 7pt, width: 7pt, fill: GREEN) *Type B:* {{ report.citation_summary.type_b_count }}],
53
+ )
54
+ ]
55
+ ],
56
+ [
57
+ #let graph = {
58
+ canvas(length: 35%, {
59
+ chart.columnchart(
60
+ size: (2.45, 2.0),
61
+ y-grid: false,
62
+ bar-style: palette.new(
63
+ base: (stroke: none, fill: none),
64
+ colors: colors
65
+ ),
66
+ (
67
+ {% for work_type in report.works_type_summary[:4] %}
68
+ ("{{ work_type.type_name[:2]|capitalize }}", {{ work_type.count }}),
69
+ {% endfor %}
70
+ )
71
+ )
72
+ })
73
+ }
74
+ #works_metrics_card(title: "Work Type", graph)[
75
+ #grid(
76
+ rows: auto, row-gutter: 10pt,
77
+ columns: (1fr, 1fr),
78
+ column-gutter: 5pt,
79
+
80
+ grid.cell(colspan: 2)[
81
+ *Count:* {{ report.open_access_summary.model_dump().items()|sum(attribute="1") }}
82
+ ],
83
+
84
+ {% for work_type in report.works_type_summary[:4] %}
85
+ [
86
+ #box(height: 7pt, width: 7pt, fill: colors.at({{ loop.index0 }})) *{{ work_type.type_name|capitalize }}:* {{ work_type.count }}
87
+ ],
88
+ {% endfor %}
89
+ )
90
+ ]
91
+ ],
92
+ [
93
+ #let graph = {
94
+ canvas(length: 35%, {
95
+ chart.piechart(
96
+ (
97
+ {{report.open_access_summary.gold}}, // Gold
98
+ {{report.open_access_summary.green}}, // Green
99
+ {{report.open_access_summary.hybrid}}, // Hybrid
100
+ {{report.open_access_summary.bronze}}, // Bronze
101
+ {{report.open_access_summary.closed}}, // Closed
102
+ ),
103
+ radius: 1,
104
+ inner-radius: .4,
105
+ slice-style: (YELLOW, GREEN, RED, BLUE, GRAY),
106
+ outer-label: (content: "%", radius: 115%),
107
+ )
108
+ })
109
+ }
110
+ #works_metrics_card(title: "Open Access", graph)[
111
+ #grid(
112
+ rows: auto, row-gutter: 10pt,
113
+ columns: (1fr, 1fr, 1fr),
114
+ column-gutter: 5pt,
115
+
116
+ grid.cell(colspan: 3)[
117
+ *Count:* {{ report.open_access_summary.model_dump().items()|sum(attribute="1") }}
118
+ ],
119
+
120
+ [#box(height: 7pt, width: 7pt, fill: YELLOW) *Gold:* {{report.open_access_summary.gold}}],
121
+ [#box(height: 7pt, width: 7pt, fill: GREEN) *Green:* {{report.open_access_summary.green}}],
122
+ [#box(height: 7pt, width: 7pt, fill: BLUE) *Bronze:* {{report.open_access_summary.bronze}}],
123
+
124
+ [#box(height: 7pt, width: 7pt, fill: GRAY) *Closed:* {{report.open_access_summary.closed}}],
125
+ [#box(height: 7pt, width: 7pt, fill: RED) *Hybrid:* {{report.open_access_summary.hybrid}}],
126
+ )
127
+ ]
128
+ ],
129
+ )
130
+
131
+ #align(center, text(11pt)[Works from {{ report.works[0].work.publication_year }} to {{ report.works[-1].work.publication_year }}])
132
+ #table(
133
+ columns: (auto, 3fr, auto, auto, auto, auto, auto, auto, auto),
134
+ inset: 8pt,
135
+ align: horizon,
136
+ // Headers
137
+ [], [*Title*], [*Type*], [*DOI*], [*Publication Date*], [*Cited by count*], [*Type A*], [*Type B*], [*OA*],
138
+
139
+ // Content
140
+ {% for work in report.works %}
141
+ [#underline([#link(label("work_{{ loop.index }}"))[@work_{{ loop.index }}]])],
142
+ [#"{{ work.work.title.replace('"', '\\"') }}"],
143
+ [{{ work.work.type }}],
144
+ [{% if work.work.ids.doi %}#underline([#link("{{ work.work.ids.doi }}")[DOI]]){% else %}-{% endif %}],
145
+ [{{ work.work.publication_date }}],
146
+ [{{ work.citation_summary.type_a_count + work.citation_summary.type_b_count }}],
147
+ [{{ work.citation_summary.type_a_count }}],
148
+ [{{ work.citation_summary.type_b_count }}],
149
+ [{{ work.work.open_access.oa_status.value }}],
150
+ {% endfor %}
151
+ )
152
+ #pagebreak()
@@ -1,11 +1,10 @@
1
- == Extended info.
2
1
  {% for work in report.works %}
3
2
 
4
3
  {% if not loop.first %}
5
4
  #pagebreak()
6
5
  {% endif %}
7
6
 
8
- === #text()[#"{{ work.work.title.replace('"', '\\"') }}"] <work_{{ loop.index }}>
7
+ == #text()[#"{{ work.work.title.replace('"', '\\"') }}"] <work_{{ loop.index }}>
9
8
 
10
9
  #linebreak()
11
10
 
@@ -43,8 +43,12 @@ class PubAnalyzerApp(App[DOMNode]):
43
43
 
44
44
  def compose(self) -> ComposeResult:
45
45
  """Create child widgets for the app."""
46
+ footer = Footer()
47
+ footer.upper_case_keys = True
48
+ footer.ctrl_to_caret = False
49
+
46
50
  yield Body()
47
- yield Footer()
51
+ yield footer
48
52
 
49
53
  def action_toggle_dark(self) -> None:
50
54
  """Toggle dark mode."""
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "pub-analyzer"
7
- version = "0.3.0"
7
+ version = "0.4.0"
8
8
  description = "A text user interface, written in python, which automates the generation of scientific production reports using OpenAlex"
9
9
 
10
10
  authors = ["Alejandro Gaspar <alejandro@gaspar.land>"]
@@ -40,21 +40,21 @@ pub-analyzer = "pub_analyzer.main:run"
40
40
  [tool.poetry.dependencies]
41
41
  python = "^3.10"
42
42
 
43
- textual = "0.58.0"
43
+ textual = "0.70.0"
44
44
  httpx = "0.27.0"
45
- pydantic = "2.7.1"
45
+ pydantic = "2.7.4"
46
46
 
47
- typst = "0.11.0"
48
- jinja2 = "3.1.3"
47
+ typst = "0.11.1"
48
+ jinja2 = "3.1.4"
49
49
 
50
50
  [tool.poetry.group.dev.dependencies]
51
51
  textual-dev = "1.5.1"
52
52
 
53
- pre-commit = "3.7.0"
53
+ pre-commit = "3.7.1"
54
54
  mypy = "1.10.0"
55
- ruff = "0.4.2"
55
+ ruff = "0.4.8"
56
56
 
57
- pytest = "8.2.0"
57
+ pytest = "8.2.2"
58
58
  pytest-asyncio = "0.21.1"
59
59
  respx = "0.21.1"
60
60
  vcrpy = "6.0.1"
@@ -64,8 +64,8 @@ pytest-recording = "0.13.1"
64
64
  mkdocs = "1.5.3"
65
65
  mkdocs-material = "9.5.18"
66
66
 
67
- mkdocstrings = {extras = ["python"], version = "0.25.0"}
68
- mkdocstrings-python = "1.10.0"
67
+ mkdocstrings = {extras = ["python"], version = "0.25.1"}
68
+ mkdocstrings-python = "1.10.3"
69
69
 
70
70
  [tool.mypy]
71
71
  strict = true
@@ -1,97 +0,0 @@
1
- // Author Summary
2
- = Author.
3
-
4
- // Cards
5
- #grid(
6
- columns: (1fr, 1fr, 1fr),
7
- column-gutter: 15pt,
8
- [
9
- // Card
10
- #rect(
11
- width: 100%,
12
- height: 150pt,
13
- fill: rgb("e5e7eb"),
14
- stroke: 1pt,
15
- radius: 2pt,
16
- [#linebreak()
17
- #grid(
18
- columns: 1fr,
19
- row-gutter: (15pt, 12pt),
20
-
21
- // Card Title
22
- [#align(center)[#text(size: 12pt)[Last institution:]]],
23
-
24
- // Card content
25
- {% if report.author.last_known_institutions%}
26
- {% set last_known_institution = report.author.last_known_institutions[0] %}
27
- [#align(left)[#text(size: 10pt)[- *Name:* {{ last_known_institution.display_name }}]]],
28
- [#align(left)[#text(size: 10pt)[- *Country:* MX]]],
29
- [#align(left)[#text(size: 10pt)[- *Type:* education]]],
30
- {% endif %}
31
- )]
32
- )
33
- ],
34
- [
35
- // Card
36
- #rect(
37
- width: 100%,
38
- height: 150pt,
39
- fill: rgb("e5e7eb"),
40
- stroke: 1pt,
41
- radius: 2pt,
42
- [#linebreak()
43
- #grid(
44
- columns: 1fr,
45
- row-gutter: (15pt, 12pt),
46
-
47
- // Card Title
48
- [#align(center)[#text(size: 12pt)[Identifiers:]]],
49
-
50
- // Card content
51
- {% for key, value in report.author.ids.model_dump().items() %}
52
- {% if value %}
53
- [#align(left)[#text(size: 10pt)[- #underline( [#link("{{ value }}")[{{ key }}]] )]]],
54
- {% endif %}
55
- {% endfor %}
56
- )]
57
- )
58
- ],
59
- [
60
- // Card
61
- #rect(
62
- width: 100%,
63
- height: 150pt,
64
- fill: rgb("e5e7eb"),
65
- stroke: 1pt,
66
- radius: 2pt,
67
- [#linebreak()
68
- #grid(
69
- columns: 1fr,
70
- row-gutter: (15pt, 12pt),
71
-
72
- // Card Title
73
- [#align(center)[#text(size: 12pt)[Citation metrics:]]],
74
-
75
- // Card content
76
- [#align(left)[#text(size: 10pt)[- *2-year mean:* {{ report.author.summary_stats.two_yr_mean_citedness|round(5) }}]]],
77
- [#align(left)[#text(size: 10pt)[- *h-index:* {{ report.author.summary_stats.h_index }}]]],
78
- [#align(left)[#text(size: 10pt)[- *i10 index:* {{ report.author.summary_stats.i10_index }}]]],
79
- )]
80
- )
81
- ],
82
- )
83
-
84
- #align(center, text(11pt)[_Counts by year_])
85
- #table(
86
- columns: (1fr, 2fr, 2fr),
87
- inset: 8pt,
88
- align: horizon,
89
- // Headers
90
- [*Year*], [*Works count*], [*Cited by count*],
91
-
92
- // Content
93
- {% for year_count in report.author.counts_by_year[:8] %}
94
- [{{ year_count.year }}], [{{ year_count.works_count }}], [{{ year_count.cited_by_count }}],
95
- {% endfor %}
96
- )
97
- #pagebreak()
@@ -1,65 +0,0 @@
1
- // Works
2
- = Works.
3
-
4
- #linebreak()
5
-
6
- #grid(
7
- columns: (1fr, 1fr, 1fr),
8
- column-gutter: 30pt,
9
- [
10
- #align(center)[_Citation metrics_]
11
- #parbreak()
12
- - *Count:* {{ report.citation_summary.type_a_count + report.citation_summary.type_b_count }}
13
- - *Type A:* {{ report.citation_summary.type_a_count }}
14
- - *Type B:* {{ report.citation_summary.type_b_count }}
15
- ],
16
- [
17
- #align(center)[_Work Type_]
18
- #parbreak()
19
- {% for work_type in report.works_type_summary %}
20
- - *{{ work_type.type_name }}:* {{ work_type.count }}
21
- {% endfor %}
22
- ],
23
- [
24
- #align(center)[_Open Access_]
25
- #parbreak()
26
- #grid(
27
- columns: (1fr, 1fr),
28
- column-gutter: 15pt,
29
- [
30
- - *gold:* {{report.open_access_summary.gold}}
31
- - *green:* {{report.open_access_summary.green}}
32
- - *hybrid:* {{report.open_access_summary.hybrid}}
33
- ],
34
- [
35
- - *bronze:* {{report.open_access_summary.bronze}}
36
- - *closed:* {{report.open_access_summary.closed}}
37
- ],
38
- )
39
- ],
40
- )
41
-
42
- #linebreak()
43
-
44
- #align(center, text(11pt)[Works from {{ report.works[0].work.publication_year }} to {{ report.works[-1].work.publication_year }}])
45
- #table(
46
- columns: (auto, 3fr, auto, auto, auto, auto, auto, auto, auto),
47
- inset: 8pt,
48
- align: horizon,
49
- // Headers
50
- [], [*Title*], [*Type*], [*DOI*], [*Publication Date*], [*Cited by count*], [*Type A*], [*Type B*], [*OA*],
51
-
52
- // Content
53
- {% for work in report.works %}
54
- [#underline([#link(label("work_{{ loop.index }}"))[@work_{{ loop.index }}]])],
55
- [#"{{ work.work.title.replace('"', '\\"') }}"],
56
- [{{ work.work.type }}],
57
- [{% if work.work.ids.doi %}#underline([#link("{{ work.work.ids.doi }}")[DOI]]){% else %}-{% endif %}],
58
- [{{ work.work.publication_date }}],
59
- [{{ work.citation_summary.type_a_count + work.citation_summary.type_b_count }}],
60
- [{{ work.citation_summary.type_a_count }}],
61
- [{{ work.citation_summary.type_b_count }}],
62
- [{{ work.work.open_access.oa_status.value }}],
63
- {% endfor %}
64
- )
65
- #pagebreak()
File without changes
File without changes