Skip to content

Commit c40f4c0

Browse files
authored
Merge pull request #11 from pharmaverse/setup-project
Set up project structure
2 parents 4d7bc6a + 0320ba7 commit c40f4c0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+5541
-19
lines changed

.github/workflows/ci-tests.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
on:
2+
push:
3+
branches:
4+
- main
5+
pull_request:
6+
branches:
7+
- main
8+
9+
name: CI Tests
10+
11+
jobs:
12+
build:
13+
runs-on: ubuntu-latest
14+
strategy:
15+
matrix:
16+
python-version: ["3.10", "3.11", "3.12", "3.13"]
17+
fail-fast: false
18+
19+
steps:
20+
- uses: actions/checkout@v4
21+
- name: Set up Python ${{ matrix.python-version }}
22+
uses: actions/setup-python@v5
23+
with:
24+
python-version: ${{ matrix.python-version }}
25+
- name: Install dependencies
26+
run: |
27+
# we are using the -e flag, so that code cov finds the source.
28+
# this is not ideal, since installing an editable can technically
29+
# differ from a normal install in surprising ways.
30+
pip install -e '.[all]'
31+
- name: Test with pytest
32+
run: |
33+
pip install pytest pytest-cov
34+
pytest --cov=rtflite --cov-report=xml
35+
36+
# - name: Upload coverage reports to Codecov
37+
# uses: codecov/codecov-action@v4
38+
# with:
39+
# name: "py${{ matrix.python-version }}"
40+
# token: ${{ secrets.CODECOV_TOKEN }}
41+
42+
test-windows:
43+
runs-on: windows-latest
44+
steps:
45+
- uses: actions/checkout@v4
46+
- name: Set up Python
47+
uses: actions/setup-python@v5
48+
with:
49+
python-version: "3.13"
50+
- name: Install dependencies
51+
run: |
52+
pip install -e '.[all]'
53+
- name: Test with pytest
54+
run: |
55+
pip install pytest pytest-cov
56+
pytest --cov=rtflite --cov-report=xml

.github/workflows/mkdocs.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: mkdocs
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
deploy:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
- name: Configure Git Credentials
17+
run: |
18+
git config user.name github-actions[bot]
19+
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
20+
21+
- uses: actions/setup-python@v5
22+
with:
23+
python-version: 3.x
24+
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
25+
26+
- uses: actions/cache@v4
27+
with:
28+
key: mkdocs-material-${{ env.cache_id }}
29+
path: .cache
30+
restore-keys: |
31+
mkdocs-material-
32+
33+
- name: Install dependencies
34+
run: |
35+
pip install mkdocs-material mkdocstrings-python
36+
pip install pytest pytest-cov
37+
pip install -e '.[all]'
38+
39+
- name: Generate coverage report and deploy mkdocs site
40+
run: |
41+
pytest --cov=rtflite --cov-report=html:docs/coverage/
42+
mkdocs gh-deploy --force

.gitignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# OS
2+
.DS_Store
3+
4+
# Python
5+
__pycache__/
6+
*.py[oc]
7+
build/
8+
dist/
9+
wheels/
10+
*.egg-info
11+
12+
# pytest
13+
.coverage
14+
15+
# venv
16+
.venv
17+
18+
# r2rtf
19+
Rplots.pdf

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.13.1

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Changelog
2+
3+
## rtflite 0.1.0
4+
5+
### New features
6+
7+
- Add `CHANGELOG.md` to record changes.
8+
- Add essential metadata to `pyproject.toml`.

LICENSE

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
1-
MIT License
2-
31
Copyright (c) 2025 pharmaverse
42

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:
3+
Permission is hereby granted, free of charge, to any person obtaining
4+
a copy of this software and associated documentation files (the
5+
"Software"), to deal in the Software without restriction, including
6+
without limitation the rights to use, copy, modify, merge, publish,
7+
distribute, sublicense, and/or sell copies of the Software, and to
8+
permit persons to whom the Software is furnished to do so, subject to
9+
the following conditions:
1110

12-
The above copyright notice and this permission notice shall be included in all
13-
copies or substantial portions of the Software.
11+
The above copyright notice and this permission notice shall be
12+
included in all copies or substantial portions of the Software.
1413

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.
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

LICENSES_THIRD_PARTY

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
rtflite uses third-party Python packages which may be distributed under
2+
different licenses. We have listed all of these third party packages and
3+
their licenses below. However, the most up-to-date information can be found
4+
via inspecting the dependencies field in the pyproject.toml file.
5+
6+
You must agree to the terms of these licenses, in addition to the rtflite
7+
source code license, in order to use this software.
8+
9+
--------------------------------------------------
10+
Third party Python packages listed by license type
11+
[Format: Name - URL]
12+
--------------------------------------------------
13+
14+
MIT License (https://opensource.org/license/mit)
15+
* pydantic - https://github.com/pydantic/pydantic/blob/main/LICENSE
16+
17+
BSD 3-Clause License (https://opensource.org/license/bsd-3-clause)
18+
* pandas - https://github.com/pandas-dev/pandas/blob/main/LICENSE
19+
20+
Modified BSD license (https://opensource.org/license/bsd-3-clause)
21+
* numpy - https://github.com/numpy/numpy/blob/main/LICENSE.txt
22+
23+
MIT-CMU License (https://opensource.org/license/cmu-license)
24+
* pillow - https://github.com/python-pillow/Pillow/blob/main/LICENSE

README.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,21 @@
1-
# rtflite
2-
Lightweight RTF composer for Python
1+
# rtflite <img src="docs/assets/logo.png" align="right" width="120" />
2+
3+
Lightweight RTF composer for Python.
4+
5+
Specializes in precise formatting of production-quality tables and figures. Inspired by r2rtf.
6+
7+
## Installation
8+
9+
You can install rtflite from PyPI:
10+
11+
```bash
12+
pip install rtflite
13+
```
14+
15+
Or install the development version from GitHub:
16+
17+
```bash
18+
git clone https://github.com/pharmaverse/rtflite.git
19+
cd rtflite
20+
python3 -m pip install -e .
21+
```

docs/articles/example-baseline.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Baseline characteristics
2+
3+
4+
<!-- `.md` and `.py` files are generated from the `.qmd` file. Please edit that file. -->
5+
6+
!!! tip
7+
8+
To run the code from this article as a Python script:
9+
10+
```bash
11+
python3 examples/example-baseline.py
12+
```
13+
14+
This article reproduces `vignettes/example-basechar.Rmd` in the r2rtf
15+
package.
16+
17+
## Imports
18+
19+
``` python
20+
from importlib.resources import files
21+
22+
import pandas as pd
23+
24+
import rtflite as rtf
25+
```
26+
27+
## Ingest data
28+
29+
Load data from CSV file:
30+
31+
``` python
32+
data_path = files("rtflite.data").joinpath("baseline.csv")
33+
df = pd.read_csv(data_path, na_filter=False)
34+
print(df)
35+
```
36+
37+
var 1 1_pct 2 2_pct 3 3_pct 9999 9999_pct var_label
38+
0 Female 53 10.4 50 9.8 40 7.9 143 28.1 Gender
39+
1 Male 33 6.5 34 6.7 44 8.7 111 21.9 Gender
40+
2 <65 14 2.8 8 1.6 11 2.2 33 6.5 Age (Years)
41+
3 65-80 42 8.3 47 9.3 55 10.8 144 28.3 Age (Years)
42+
4 >80 30 5.9 29 5.7 18 3.5 77 15.2 Age (Years)
43+
5 Age (Years)
44+
6 Subjects with data 86 84 84 254 Age (Years)
45+
7 Mean 75.2 75.7 74.4 75.1 Age (Years)
46+
8 SD 8.6 8.3 7.9 8.2 Age (Years)
47+
9 Median 76.0 77.5 76.0 77.0 Age (Years)
48+
10 Range 52 to 89 51 to 88 56 to 88 51 to 89 Age (Years)
49+
11 White 78 15.4 78 15.4 74 14.6 230 45.3 Race
50+
12 Black 8 1.6 6 1.2 9 1.8 23 4.5 Race
51+
13 Other 0 0.0 0 0.0 1 0.2 1 0.2 Race
52+
53+
Create header data frames:
54+
55+
``` python
56+
header1 = pd.DataFrame([["", "Placebo", "Drug Low Dose", "Drug High Dose", "Total"]])
57+
header2 = pd.DataFrame([["", "n", "(%)", "n", "(%)", "n", "(%)", "n", "(%)"]])
58+
```
59+
60+
## Compose RTF
61+
62+
Create RTF document:
63+
64+
``` python
65+
doc = rtf.RTFDocument(
66+
df=df,
67+
rtf_title=rtf.RTFTitle(
68+
text=["Demographic and Anthropometric Characteristics", "ITT Subjects"]
69+
),
70+
rtf_column_header=[
71+
rtf.RTFColumnHeader(df=header1, col_rel_width=[3] + [2] * 4),
72+
rtf.RTFColumnHeader(
73+
df=header2,
74+
col_rel_width=[3] + [1.2, 0.8] * 4,
75+
border_top=[""] + ["single"] * 8,
76+
border_left=["single"] + ["single", ""] * 4,
77+
),
78+
],
79+
rtf_body=rtf.RTFBody(
80+
page_by=["var_label"],
81+
col_rel_width=[3] + [1.2, 0.8] * 4 + [3],
82+
text_justification=["l"] + ["c"] * 8 + ["l"],
83+
text_format=[""] * 9 + ["b"],
84+
border_left=["single"] + ["single", ""] * 4 + ["single"],
85+
border_top=[""] * 9 + ["single"],
86+
border_bottom=[""] * 9 + ["single"],
87+
),
88+
)
89+
90+
doc.write_rtf("output.rtf")
91+
```
92+
93+
## Convert to PDF
94+
95+
``` python
96+
converter = rtf.LibreOfficeConverter()
97+
converter.convert(
98+
input_files="output.rtf", output_dir=".", format="pdf", overwrite=True
99+
)
100+
```
101+
102+
<embed src="../images/example-baseline/output.pdf" style="width:100%; height:400px" type="application/pdf">

0 commit comments

Comments
 (0)