-
Notifications
You must be signed in to change notification settings - Fork 455
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
9 changed files
with
506 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) [2023] [slashformotion] | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
|
||
# Codly: simple and beautiful code blocks for Typst | ||
|
||
Codly is a package that lets you easily create beautiful code blocks for your Typst documents. | ||
It uses the newly added [`raw.line`](https://typst.app/docs/reference/text/raw/#definitions-line) | ||
function to work across all languages easily. You can customize the icons, colors, and more to | ||
suit your document's theme. By default it has zebra striping, line numbers, for ease of reading. | ||
|
||
````typ | ||
#let icon(codepoint) = { | ||
box( | ||
height: 0.8em, | ||
baseline: 0.05em, | ||
image(codepoint) | ||
) | ||
h(0.1em) | ||
} | ||
#show: codly-init.with() | ||
#codly(languages: ( | ||
rust: (name: "Rust", icon: icon("brand-python.svg"), color: rgb("#CE412B")), | ||
)) | ||
```rust | ||
pub fn main() { | ||
println!("Hello, world!"); | ||
} | ||
``` | ||
```` | ||
|
||
Which renders to: | ||
|
||
![Example](./demo.png) | ||
|
||
You can find all of the documentation in the [example](https://github.com/Dherse/codly/tree/main/example/main.typ) file. | ||
|
||
## Short manual | ||
|
||
### Setup | ||
|
||
To start using codly, you need to initialize codly using a show rule: | ||
|
||
```typ | ||
#show: codly-init.with() | ||
``` | ||
|
||
Then you need to congigure codly with your parameters: | ||
|
||
```typ | ||
#codly( | ||
languages: ( | ||
rust: (name: "Rust", icon: icon("\u{fa53}"), color: rgb("#CE412B")), | ||
) | ||
) | ||
``` | ||
|
||
Then you just need to add a code block and it will be automatically displayed correctly: | ||
|
||
```` | ||
```rust | ||
pub fn main() { | ||
println!("Hello, world!"); | ||
} | ||
``` | ||
```` | ||
|
||
### Disabling | ||
|
||
To locally disable codly, you can just do the following, you can then later re-enable it using the `codly` configuration function. | ||
|
||
```typ | ||
#disable-codly() | ||
``` | ||
|
||
### Setting an offset | ||
|
||
If you wish to add an offset to your code block, but without selecting a subset of lines, you can use the `codly-offset` function: | ||
|
||
```typ | ||
// Sets a 5 line offset | ||
#codly-offset(5) | ||
``` | ||
|
||
### Selecting a subset of lines | ||
|
||
If you wish to select a subset of lines, you can use the `codly-range` function. By setting the start to 1 and the end to `none` you can select all lines from the start to the end of the code block. | ||
|
||
```typ | ||
#codly-range(start: 5, end: 10) | ||
``` | ||
|
||
### Disabling line numbers | ||
|
||
You can configure this with the `codly` function: | ||
|
||
```typ | ||
#codly( | ||
width-numbers: none, | ||
) | ||
``` | ||
|
||
### Disabling zebra striping | ||
|
||
You disable zebra striping by setting the `zebra-color` to white. | ||
|
||
```typ | ||
#codly( | ||
zebra-color: white, | ||
) | ||
``` | ||
|
||
### Customize the stroke | ||
|
||
You can customize the stroke surrounding the figure using the `stroke-width` and `stroke-color` parameters of the `codly` function: | ||
|
||
```typ | ||
#codly( | ||
stroke-width: 1pt, | ||
stroke-color: red, | ||
) | ||
``` | ||
|
||
### Misc | ||
|
||
You can also disable the icon, by setting the `display-icon` parameter to `false`: | ||
|
||
```typ | ||
#codly( | ||
display-icon: false, | ||
) | ||
``` | ||
|
||
Same with the name, whether the block is breakable, the radius, the padding, and the width of the numbers columns. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,239 @@ | ||
// Lets you set a line number offset. | ||
#let codly-offset(offset: 0) = { | ||
state("codly-offset").update(offset) | ||
} | ||
|
||
// Lets you set a range of line numbers to highlight. | ||
#let codly-range( | ||
start: 1, | ||
end: none, | ||
) = { | ||
state("codly-range").update((start, end)) | ||
} | ||
|
||
// Disables codly. | ||
#let disable-codly() = { | ||
state("codly-config").update(none) | ||
} | ||
|
||
// Configures codly. | ||
#let codly( | ||
// The list of languages, allows setting a display name and an icon, | ||
// it should be a dict of the form: | ||
// `<language-name>: (name: <display-name>, icon: <icon-content>, color: <color>)` | ||
languages: (:), | ||
|
||
// Whether to display the language name. | ||
display-name: true, | ||
|
||
// Whether to display the language icon. | ||
display-icon: true, | ||
|
||
// The default color for a language not in the list. | ||
// Only used if `display-icon` or `display-name` is `true`. | ||
default-color: rgb("#283593"), | ||
|
||
// Radius of a code block. | ||
radius: 0.32em, | ||
|
||
// Padding of a code block. | ||
padding: 0.32em, | ||
|
||
// The zebra color to use or `none` to disable. | ||
zebra-color: luma(240), | ||
|
||
// The stroke width to use to surround the code block. | ||
// Set to `none` to disable. | ||
stroke-width: 0.1em, | ||
|
||
// The stroke color to use to surround the code block. | ||
stroke-color: luma(240), | ||
|
||
// The width of the numbers column. | ||
// If set to `none`, the numbers column will be disabled. | ||
width-numbers: 2em, | ||
|
||
// Whether this code block is breakable. | ||
breakable: true, | ||
) = locate(loc => { | ||
let old = state("codly-config").at(loc); | ||
if old == none { | ||
state("codly-config").update(( | ||
languages: languages, | ||
display-name: display-name, | ||
display-icon: display-icon, | ||
default-color: default-color, | ||
radius: radius, | ||
padding: padding, | ||
zebra-color: zebra-color, | ||
stroke-width: stroke-width, | ||
width-numbers: width-numbers, | ||
breakable: breakable, | ||
stroke-color: stroke-color, | ||
)) | ||
} else { | ||
let folded_langs = old.languages; | ||
for (lang, def) in languages { | ||
folded_langs.insert(lang, def) | ||
} | ||
|
||
state("codly-config").update(( | ||
languages: folded_langs, | ||
display-name: display-name, | ||
display-icon: display-icon, | ||
default-color: default-color, | ||
radius: radius, | ||
padding: padding, | ||
zebra-color: zebra-color, | ||
stroke-width: stroke-width, | ||
width-numbers: width-numbers, | ||
breakable: breakable, | ||
stroke-color: stroke-color, | ||
)) | ||
} | ||
}) | ||
|
||
#let codly-init( | ||
body, | ||
) = { | ||
show raw.where(block: true): it => locate(loc => { | ||
let config = state("codly-config").at(loc) | ||
let range = state("codly-range").at(loc) | ||
let in_range(line) = { | ||
if range == none { | ||
true | ||
} else if range.at(1) == none { | ||
line >= range.at(0) | ||
} else { | ||
line >= range.at(0) and line <= range.at(1) | ||
} | ||
} | ||
if config == none { | ||
return it | ||
} | ||
let language_block = if config.display-name == false and config.display-icon == false { | ||
none | ||
} else if it.lang == none { | ||
none | ||
} else if it.lang in config.languages { | ||
let lang =config. languages.at(it.lang); | ||
let content = if config.display-name == true and config.display-icon == true { | ||
lang.icon + lang.name | ||
} else if config.display-name == true { | ||
lang.name | ||
} else { | ||
lang.icon | ||
}; | ||
|
||
style(styles => { | ||
let height = measure(content, styles).height | ||
box( | ||
radius: config.radius, | ||
fill: lang.color.lighten(60%), | ||
inset: config.padding, | ||
height: height + config.padding * 2, | ||
stroke: config.stroke-width + lang.color, | ||
content, | ||
) | ||
}) | ||
} else { | ||
if config.display-name == false { | ||
style(styles => { | ||
let height = measure(it.lang, styles).height | ||
box( | ||
radius: config.radius, | ||
fill: config.default-color.lighten(60%), | ||
inset: config.padding, | ||
height: height + padding * 2, | ||
stroke: config.stroke-width + config.default-color, | ||
it.lang, | ||
) | ||
}) | ||
} else { | ||
none | ||
} | ||
}; | ||
|
||
let offset = state("codly-offset").at(loc); | ||
let start = if range == none { 1 } else { range.at(0) }; | ||
let border(i, len) = { | ||
let end = if range == none { len } else if range.at(1) == none { len } else { range.at(1) }; | ||
|
||
let stroke-width = if config.stroke-width == none { 0pt } else { config.stroke-width }; | ||
let radii = (:) | ||
let stroke = (x: config.stroke-color + stroke-width) | ||
|
||
if i == start { | ||
radii.insert("top-left", config.radius) | ||
radii.insert("top-right", config.radius) | ||
stroke.insert("top", config.stroke-color + stroke-width) | ||
} | ||
|
||
if i == end { | ||
radii.insert("bottom-left", config.radius) | ||
radii.insert("bottom-right", config.radius) | ||
stroke.insert("bottom", config.stroke-color + stroke-width) | ||
} | ||
|
||
radii.insert("rest", 0pt) | ||
|
||
(radius: radii, stroke: stroke) | ||
} | ||
|
||
let width = if config.width-numbers == none { 0pt } else { config.width-numbers } | ||
show raw.line: it => if not in_range(it.number) { | ||
none | ||
} else { | ||
block( | ||
width: 100%, | ||
height: 1.2em + config.padding * 2, | ||
inset: (left: config.padding + width, top: config.padding + 0.1em, rest: config.padding), | ||
fill: if calc.rem(it.number, 2) == 0 { | ||
config.zebra-color | ||
} else { | ||
white | ||
}, | ||
radius: border(it.number, it.count).radius, | ||
stroke: border(it.number, it.count).stroke, | ||
{ | ||
if it.number == start { | ||
place( | ||
top + right, | ||
language_block, | ||
dy: -config.padding * 0.66666, | ||
dx: config.padding * 0.66666 - 0.1em, | ||
) | ||
} | ||
|
||
set par(justify: false) | ||
if config.width-numbers != none { | ||
place( | ||
top + left, | ||
dx: -config.width-numbers, | ||
[#(offset + it.number)] | ||
) | ||
} | ||
it | ||
} | ||
) | ||
} | ||
|
||
let stroke = if config.stroke-width == 0pt or config.stroke-width == none { | ||
none | ||
} else { | ||
config.stroke-width + config.zebra-color | ||
}; | ||
|
||
block( | ||
breakable: config.breakable, | ||
clip: false, | ||
width: 100%, | ||
stack(dir: ttb, ..it.lines) | ||
) | ||
|
||
codly-offset() | ||
codly-range(start: 1, end: none) | ||
}) | ||
|
||
body | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#import "../codly.typ": * | ||
|
||
#show: codly-init.with() | ||
|
||
#let icon(codepoint) = { | ||
box( | ||
height: 0.8em, | ||
baseline: 0.05em, | ||
image(codepoint) | ||
) | ||
h(0.1em) | ||
} | ||
|
||
#codly(languages: ( | ||
rust: (name: "Rust", icon: icon("brand-python.svg"), color: rgb("#CE412B")), | ||
python: (name: "Python", icon: icon("brand-rust.svg"), color: rgb("#3572A5")), | ||
)) | ||
```rust | ||
pub fn main() { | ||
println!("Hello, world!"); | ||
} | ||
``` | ||
```python | ||
def fibonaci(n): | ||
if n <= 1: | ||
return n | ||
else: | ||
return(fibonaci(n-1) + fibonaci(n-2)) | ||
``` | ||
We can also set a line number offset with `codly-offset(int)`: | ||
#codly-offset(offset: 1) | ||
```rust | ||
println!("Hello, world!"); | ||
``` | ||
And we can also disable line numbers: | ||
#codly(width-numbers: none) | ||
```rust | ||
pub fn main() { | ||
println!("Hello, world!"); | ||
} | ||
``` | ||
We can also select only a range of lines to show: | ||
#codly-range(start: 5, end: 5) | ||
```python | ||
def fibonaci(n): | ||
if n <= 1: | ||
return n | ||
else: | ||
return(fibonaci(n-1) + fibonaci(n-2)) | ||
``` | ||
#codly( | ||
stroke-width: 1pt, | ||
stroke-color: red, | ||
) | ||
```rust | ||
pub fn main() { | ||
println!("Hello, world!"); | ||
} | ||
``` | ||
#codly( | ||
display-icon: false, | ||
) | ||
```rust | ||
pub fn main() { | ||
println!("Hello, world!"); | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[package] | ||
name = "codly" | ||
version = "0.1.0" | ||
entrypoint = "codly.typ" | ||
authors = ["Dherse"] | ||
license = "MIT" | ||
description = "Codly is a beautiful code presentation template." | ||
repository = "https://github.com/Dherse/codly" | ||
exclude = ["example/*", "demo.png" ] | ||
compiler = "0.9.0" | ||
keywords = [ "code", "pretty", "template", "raw" ] |