diff --git a/packages/preview/codly/0.1.0/LICENSE b/packages/preview/codly/0.1.0/LICENSE new file mode 100644 index 000000000..a5a5f2f23 --- /dev/null +++ b/packages/preview/codly/0.1.0/LICENSE @@ -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. \ No newline at end of file diff --git a/packages/preview/codly/0.1.0/README.md b/packages/preview/codly/0.1.0/README.md new file mode 100644 index 000000000..572fdee1e --- /dev/null +++ b/packages/preview/codly/0.1.0/README.md @@ -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. \ No newline at end of file diff --git a/packages/preview/codly/0.1.0/codly.typ b/packages/preview/codly/0.1.0/codly.typ new file mode 100644 index 000000000..7814be9ee --- /dev/null +++ b/packages/preview/codly/0.1.0/codly.typ @@ -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: + // `: (name: , icon: , 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 +} \ No newline at end of file diff --git a/packages/preview/codly/0.1.0/demo.png b/packages/preview/codly/0.1.0/demo.png new file mode 100644 index 000000000..ae7550b3f Binary files /dev/null and b/packages/preview/codly/0.1.0/demo.png differ diff --git a/packages/preview/codly/0.1.0/example/brand-python.svg b/packages/preview/codly/0.1.0/example/brand-python.svg new file mode 100644 index 000000000..eb7b9657f --- /dev/null +++ b/packages/preview/codly/0.1.0/example/brand-python.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/preview/codly/0.1.0/example/brand-rust.svg b/packages/preview/codly/0.1.0/example/brand-rust.svg new file mode 100644 index 000000000..19ffb9843 --- /dev/null +++ b/packages/preview/codly/0.1.0/example/brand-rust.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/preview/codly/0.1.0/example/main.pdf b/packages/preview/codly/0.1.0/example/main.pdf new file mode 100644 index 000000000..d32129621 Binary files /dev/null and b/packages/preview/codly/0.1.0/example/main.pdf differ diff --git a/packages/preview/codly/0.1.0/example/main.typ b/packages/preview/codly/0.1.0/example/main.typ new file mode 100644 index 000000000..e1ee9d962 --- /dev/null +++ b/packages/preview/codly/0.1.0/example/main.typ @@ -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!"); +} +``` \ No newline at end of file diff --git a/packages/preview/codly/0.1.0/typst.toml b/packages/preview/codly/0.1.0/typst.toml new file mode 100644 index 000000000..bf221f8b1 --- /dev/null +++ b/packages/preview/codly/0.1.0/typst.toml @@ -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" ] \ No newline at end of file