Skip to content

Commit cdfc7f2

Browse files
committed
feat: Initial attemp
1 parent 2302431 commit cdfc7f2

File tree

12 files changed

+490
-0
lines changed

12 files changed

+490
-0
lines changed

.github/workflows/test.yml

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Test
2+
3+
concurrency:
4+
group: ${{ github.workflow }}-${{ github.ref }}
5+
cancel-in-progress: true
6+
7+
on:
8+
push:
9+
branches: ["master"]
10+
pull_request:
11+
branches: ["master"]
12+
13+
jobs:
14+
build-and-test:
15+
name: Build and test
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Setup PHP-dev
22+
uses: shivammathur/setup-php@v2
23+
with:
24+
php-version: "8.4-dev"
25+
26+
- name: Setup rust
27+
run: |
28+
rustup toolchain install stable --profile minimal
29+
30+
- name: Build extension
31+
run: |
32+
cd php-typ
33+
cargo build --release
34+
35+
- name: Test extension
36+
run: |
37+
php -d extension=./php-typ/target/debug/libtyp_php.so ./test.php

README.md

+38
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,40 @@
11
# php-typst
2+
23
PHP extension for compiling Typst documents
4+
5+
## Development
6+
7+
### Install dev version of PHP
8+
9+
```sh
10+
sudo apt install php-dev
11+
```
12+
13+
OR
14+
15+
### Build PHP from source at `$HOME/build/php`
16+
17+
```sh
18+
sudo apt install bison re2c llvm clang libclang-dev
19+
git clone https://github.com/php/php-src.git
20+
cd php-src
21+
git checkout PHP-8.3
22+
./buildconf
23+
PREFIX="${HOME}/build/php"
24+
./configure --prefix="${PREFIX}" --enable-debug --disable-all --disable-cgi
25+
make -j "$(nproc)"
26+
make install
27+
```
28+
29+
### Build extension via Cargo
30+
31+
```sh
32+
# Specify paths to PHP and PHP_CONFIG
33+
PHP=$PREFIX/bin/php PHP_CONFIG=$PREFIX/bin/php-config cargo build
34+
${PHP} -d extension=./php-typ/target/debug/libtyp_php.so ./test.php
35+
```
36+
37+
## Built on
38+
39+
- [Ext PHP RS](https://github.com/davidcole1340/ext-php-rs)
40+
- [Typst](https://github.com/typst/typst)

dockerfile

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Use Ubuntu as base image
2+
FROM ubuntu:24.04
3+
4+
# Avoid timezone prompt during package installation
5+
ENV DEBIAN_FRONTEND=noninteractive
6+
7+
# Install basic build requirements
8+
RUN apt-get update && apt-get install -y \
9+
git \
10+
curl \
11+
build-essential \
12+
bison \
13+
re2c \
14+
llvm \
15+
clang \
16+
libclang-dev \
17+
php-dev \
18+
&& rm -rf /var/lib/apt/lists/*
19+
20+
# Set working directory
21+
# WORKDIR /build
22+
23+
# Clone PHP source code
24+
# RUN git clone https://github.com/php/php-src.git \
25+
# && cd php-src \
26+
# && git checkout PHP-8.3
27+
28+
# Build PHP from source
29+
# RUN cd php-src \
30+
# && ./buildconf \
31+
# && ./configure --prefix=/usr/local/php \
32+
# --enable-debug \
33+
# --disable-all \
34+
# --disable-cgi \
35+
# && make -j$(nproc) \
36+
# && make install
37+
38+
# Copy source code
39+
COPY . /usr/src/typ-php
40+
41+
# Download and install Rust
42+
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
43+
ENV PATH="/root/.cargo/bin:${PATH}"
44+
45+
# Build extension
46+
WORKDIR /usr/src/typ-php/php-typ
47+
ENV PHP=/usr/bin/php
48+
ENV PHP_CONFIG=/usr/bin/php-config
49+
RUN cargo build
50+
51+
# Run test
52+
WORKDIR /usr/src/typ-php
53+
CMD ["/usr/bin/php", "-d", "extension=./php-typ/target/debug/libtyp_php.so", "./test.php"]

fonts/Roboto-Regular.ttf

143 KB
Binary file not shown.

php-typ/.cargo/config.toml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[target.'cfg(not(target_os = "windows"))']
2+
rustflags = ["-C", "link-arg=-Wl,-undefined,dynamic_lookup"]
3+
4+
[target.x86_64-pc-windows-msvc]
5+
linker = "rust-lld"
6+
7+
[target.i686-pc-windows-msvc]
8+
linker = "rust-lld"

php-typ/Cargo.toml

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[package]
2+
name = "typ-php"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
7+
[lib]
8+
crate-type = ["cdylib"]
9+
10+
[dependencies]
11+
ext-php-rs = "*"
12+
typst = "0.12"
13+
typst-as-library = { path = "../typst-as-library" }
14+
typst-pdf = "0.12"
15+
typst-svg = "0.12"
16+
17+
[profile.release]
18+
strip = "debuginfo"

php-typ/src/lib.rs

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#![cfg_attr(windows, feature(abi_vectorcall))]
2+
use ext_php_rs::prelude::*;
3+
4+
use std::fs;
5+
use typst::layout::Abs;
6+
use typst_as_library::TypstWrapperWorld;
7+
use typst_pdf::PdfOptions;
8+
9+
#[php_function]
10+
pub fn typst_compile_code(content: String, root: String, out_pdf_file: String, out_svg_file: Option<String>) -> () {
11+
// Create world with content.
12+
let world = TypstWrapperWorld::new(root, content);
13+
14+
// Render document
15+
let document = typst::compile(&world)
16+
.output
17+
.expect("Error compiling typst");
18+
19+
// Output to pdf and svg
20+
let pdf = typst_pdf::pdf(&document, &PdfOptions::default()).expect("Error exporting PDF");
21+
fs::write(out_pdf_file, pdf).expect("Error writing PDF.");
22+
println!("Created pdf: `./output.pdf`");
23+
24+
if let Some(svg_file) = out_svg_file {
25+
let svg = typst_svg::svg_merged(&document, Abs::pt(2.0));
26+
fs::write(svg_file, svg).expect("Error writing SVG.");
27+
println!("Created svg: `./output.svg`");
28+
}
29+
}
30+
31+
#[php_module]
32+
pub fn get_module(module: ModuleBuilder) -> ModuleBuilder {
33+
module
34+
}

rust-toolchain.toml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[toolchain]
2+
channel = "stable"
3+
components = ["rustfmt", "clippy"]
4+
targets = ["x86_64-unknown-linux-gnu"]
5+
6+
[profile]
7+
opt-level = 3

test.php

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
var_dump(
4+
typst_compile_code(<<<TYP
5+
= Hello World
6+
Great to see ur
7+
== Heading 2
8+
TYP,
9+
"./",
10+
"./outputs/out.pdf",
11+
"./outputs/out.svg",
12+
)
13+
);

typst-as-library/Cargo.toml

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[package]
2+
name = "typst-as-library"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
# typst essentials
10+
typst = "0.12"
11+
comemo = "0.4"
12+
13+
# Fetching and unzipping packages
14+
zune-inflate = { version = "0.2", default-features = false, features = [
15+
"gzip",
16+
"std",
17+
] }
18+
tar = "0.4"
19+
ureq = "2.9"
20+
21+
# utils
22+
time = "0.3"
23+
ttf-parser = "0.25"
24+
25+
[lib]
26+
name = "typst_as_library"
27+
28+
[dev-dependencies]
29+
typst-pdf = "0.12"

typst-as-library/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Typst lib
2+
3+
## Acknowledgment
4+
5+
- Copied from [typst-as-library](https://github.com/tfachmann/typst-as-library?tab=readme-ov-file)

0 commit comments

Comments
 (0)