├── src ├── expr.jl ├── dict.jl ├── GarishPrint.jl ├── set.jl ├── numbers.jl ├── misc.jl ├── color.jl ├── struct.jl ├── pprint.jl ├── arrays.jl └── io.jl ├── .vscode └── settings.json ├── .gitignore ├── docs ├── src │ ├── assets │ │ └── readme-example.png │ ├── ref.md │ └── index.md ├── build │ ├── assets │ │ ├── readme-example.png │ │ ├── warner.js │ │ ├── themeswap.js │ │ ├── indigo.css │ │ ├── search.js │ │ └── documenter.js │ ├── search │ │ └── index.html │ ├── index.html │ ├── search_index.js │ └── ref │ │ └── index.html ├── Project.toml ├── make.jl └── Manifest.toml ├── test ├── runtests.jl ├── prefs.jl ├── Project.toml ├── basic.jl ├── dataframe.jl └── configs.jl ├── .github └── workflows │ ├── TagBot.yml │ ├── CompatHelper.yml │ ├── Documentation.yml │ └── CI.yml ├── Project.toml ├── LICENSE └── README.md /src/expr.jl: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /Manifest.toml 2 | /LocalPreferences.toml 3 | docs/src/assets/indigo.css 4 | -------------------------------------------------------------------------------- /docs/src/assets/readme-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/findmyway/GarishPrint.jl/HEAD/docs/src/assets/readme-example.png -------------------------------------------------------------------------------- /docs/build/assets/readme-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/findmyway/GarishPrint.jl/HEAD/docs/build/assets/readme-example.png -------------------------------------------------------------------------------- /docs/src/ref.md: -------------------------------------------------------------------------------- 1 | ```@meta 2 | CurrentModule = GarishPrint 3 | ``` 4 | 5 | # Reference 6 | 7 | ```@autodocs 8 | Modules = [GarishPrint] 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/Project.toml: -------------------------------------------------------------------------------- 1 | [deps] 2 | DocThemeIndigo = "8bac0ac5-51bf-41f9-885e-2bf1ac2bec5f" 3 | Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" 4 | GarishPrint = "b0ab02a7-8576-43f7-aa76-eaa7c3897c54" 5 | -------------------------------------------------------------------------------- /test/runtests.jl: -------------------------------------------------------------------------------- 1 | using Test 2 | 3 | @static if VERSION ≥ v"1.6" 4 | @testset "prefs" begin 5 | include("prefs.jl") 6 | end 7 | end 8 | 9 | include("basic.jl") 10 | include("configs.jl") 11 | include("dataframe.jl") 12 | -------------------------------------------------------------------------------- /test/prefs.jl: -------------------------------------------------------------------------------- 1 | using Test 2 | using UUIDs 3 | using Preferences 4 | set_preferences!( 5 | UUID("b0ab02a7-8576-43f7-aa76-eaa7c3897c54"), 6 | "color"=>Dict("fieldname"=>"blue"), 7 | force=true, 8 | ) 9 | 10 | using GarishPrint 11 | @test GarishPrint.ColorPreference().fieldname === :blue 12 | -------------------------------------------------------------------------------- /test/Project.toml: -------------------------------------------------------------------------------- 1 | [deps] 2 | Configurations = "5218b696-f38b-4ac9-8b61-a12ec717816d" 3 | Preferences = "21216c6a-2e73-6563-6e65-726566657250" 4 | DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" 5 | TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76" 6 | UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" 7 | Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" 8 | -------------------------------------------------------------------------------- /src/dict.jl: -------------------------------------------------------------------------------- 1 | function pprint(io::GarishIO, mime::MIME"text/plain", d::AbstractDict) 2 | # use default printing if it's the root 3 | io.state.level == 0 && return show(io, mime, d) 4 | # heurostics to print Dict in compact form 5 | if length(d) < 20 && !max_indent_reached(io, length(string(d))) 6 | pprint_list_like(io, d, "(", ")"; compact=true) 7 | else 8 | pprint_list_like(io, d, "(", ")") 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /.github/workflows/TagBot.yml: -------------------------------------------------------------------------------- 1 | name: TagBot 2 | on: 3 | issue_comment: 4 | types: 5 | - created 6 | workflow_dispatch: 7 | jobs: 8 | TagBot: 9 | if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: JuliaRegistries/TagBot@v1 13 | with: 14 | token: ${{ secrets.GITHUB_TOKEN }} 15 | ssh: ${{ secrets.DOCUMENTER_KEY }} 16 | -------------------------------------------------------------------------------- /.github/workflows/CompatHelper.yml: -------------------------------------------------------------------------------- 1 | name: CompatHelper 2 | on: 3 | schedule: 4 | - cron: 0 0 * * * 5 | workflow_dispatch: 6 | jobs: 7 | CompatHelper: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Pkg.add("CompatHelper") 11 | run: julia -e 'using Pkg; Pkg.add("CompatHelper")' 12 | - name: CompatHelper.main() 13 | env: 14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 15 | COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }} 16 | run: julia -e 'using CompatHelper; CompatHelper.main()' 17 | -------------------------------------------------------------------------------- /docs/make.jl: -------------------------------------------------------------------------------- 1 | using Documenter 2 | using GarishPrint 3 | using DocThemeIndigo 4 | 5 | indigo = DocThemeIndigo.install(GarishPrint) 6 | 7 | makedocs(; 8 | modules = [GarishPrint], 9 | format = Documenter.HTML( 10 | prettyurls = !("local" in ARGS), 11 | canonical="https://Roger-luo.github.io/GarishPrint.jl", 12 | assets=String[indigo], 13 | ), 14 | pages = [ 15 | "Home" => "index.md", 16 | "References" => "ref.md", 17 | ], 18 | repo = "https://github.com/Roger-luo/GarishPrint.jl", 19 | sitename = "GarishPrint.jl", 20 | ) 21 | 22 | deploydocs(; repo = "github.com/Roger-luo/GarishPrint.jl") 23 | -------------------------------------------------------------------------------- /src/GarishPrint.jl: -------------------------------------------------------------------------------- 1 | module GarishPrint 2 | 3 | export pprint, pprint_struct 4 | using Configurations 5 | 6 | # 1.0 Compat 7 | @static if !@isdefined(isnothing) 8 | isnothing(x) = x === nothing 9 | end 10 | 11 | @static if VERSION ≥ v"1.6" 12 | using Preferences 13 | end 14 | 15 | @static if VERSION ≥ v"1.6" 16 | const color_prefs_toml = @load_preference("color") 17 | else 18 | const color_prefs_toml = nothing 19 | end 20 | 21 | include("color.jl") 22 | include("io.jl") 23 | include("pprint.jl") 24 | include("struct.jl") 25 | include("misc.jl") 26 | include("numbers.jl") 27 | include("arrays.jl") 28 | include("dict.jl") 29 | include("set.jl") 30 | 31 | end 32 | -------------------------------------------------------------------------------- /Project.toml: -------------------------------------------------------------------------------- 1 | name = "GarishPrint" 2 | uuid = "b0ab02a7-8576-43f7-aa76-eaa7c3897c54" 3 | authors = ["Roger-Luo and contributors"] 4 | version = "0.5.0" 5 | 6 | [deps] 7 | Configurations = "5218b696-f38b-4ac9-8b61-a12ec717816d" 8 | Preferences = "21216c6a-2e73-6563-6e65-726566657250" 9 | 10 | [compat] 11 | Configurations = "0.16, 0.17" 12 | Preferences = "1" 13 | julia = "1" 14 | 15 | [extras] 16 | DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" 17 | TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76" 18 | Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" 19 | UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" 20 | 21 | [targets] 22 | test = ["Test", "TOML", "DataFrames"] 23 | -------------------------------------------------------------------------------- /.github/workflows/Documentation.yml: -------------------------------------------------------------------------------- 1 | name: Documentation 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | tags: '*' 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | - uses: julia-actions/setup-julia@latest 15 | with: 16 | version: 1 17 | - name: Install dependencies 18 | run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()' 19 | - name: Build and deploy 20 | env: 21 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token 22 | DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # For authentication with SSH deploy key 23 | run: julia --project=docs/ docs/make.jl 24 | -------------------------------------------------------------------------------- /src/set.jl: -------------------------------------------------------------------------------- 1 | function pprint(io::GarishIO, ::MIME"text/plain", s::Set) 2 | # use default printing if it's the root 3 | io.state.level == 0 && return show(io, mime, d) 4 | 5 | if isempty(s) 6 | if get(io, :typeinfo, Any) == typeof(s) 7 | print_token(io, :type, "Set") 8 | else 9 | print_token(io, :type, typeof(s)) 10 | print(io, "()") 11 | end 12 | else 13 | print_token(io, :type, "Set") 14 | print(io, "(") 15 | # io.compact && return pprint_list_like(io, X) 16 | # heurostics to print vector in compact form 17 | if length(s) < 20 && !max_indent_reached(io, length(string(s))) 18 | pprint_list_like(io, s; compact=true) 19 | else 20 | pprint_list_like(io, s) 21 | end 22 | print(io, ")") 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /src/numbers.jl: -------------------------------------------------------------------------------- 1 | pprint(io::GarishIO, m::MIME"text/plain", x::Number) = show(io.bland_io, m, x) 2 | 3 | # normal literal 4 | function pprint(io::GarishIO, ::MIME"text/plain", x::Union{Int, Float64}) 5 | print_token(io, :number, x) 6 | end 7 | 8 | function pprint(io::GarishIO, ::MIME"text/plain", x::Float32) 9 | print_token(io, :number, x) 10 | print_token(io, :literal, "f0") 11 | end 12 | 13 | for irrational in [:π, :ℯ, :γ, :ϕ, :catalan] 14 | @eval function pprint(io::GarishIO, ::MIME"text/plain", ::Irrational{$(QuoteNode(irrational))}) 15 | print_token(io, :constant, $(string(irrational))) 16 | end 17 | end 18 | 19 | function pprint(io::GarishIO, ::MIME"text/plain", z::Complex) 20 | re, im = real(z), imag(z) 21 | iszero(re) || pprint(io, re) 22 | 23 | iszero(re) || print_operator(io, '+') 24 | 25 | # NOTE: don't omit + for imag part 26 | # this is intentional, we want to be 27 | # able to tell the type of the value 28 | # from just printing 29 | pprint(io, im) 30 | print_token(io, :constant, "im") 31 | end 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Roger-Luo and contributors 4 | 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: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 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. 22 | -------------------------------------------------------------------------------- /test/basic.jl: -------------------------------------------------------------------------------- 1 | module TestBasic 2 | 3 | using GarishPrint 4 | using Test 5 | 6 | struct T1 7 | x::Int 8 | end 9 | 10 | struct T2 11 | x::Int 12 | y::Float64 13 | end 14 | 15 | struct T3 16 | x::Int 17 | y::T1 18 | z::T2 19 | end 20 | 21 | struct T4{T} 22 | x::T 23 | y::T 24 | end 25 | 26 | struct T5{T} 27 | x::T 28 | end 29 | 30 | struct TTTTTTTTTTTTTTTTTTTT{A,B} 31 | x::A 32 | y::B 33 | end 34 | 35 | pprint(T1(1)) 36 | 37 | pprint(T2(1, 2.0)) 38 | 39 | pprint(T3(1, T1(2), T2(1, 2.0))) 40 | 41 | pprint(T4(1+2im, 2im)) 42 | pprint(T4(2 + 0im, 2im)) 43 | 44 | pprint(T5(Any[1, 2, 3])) 45 | pprint(stdout, fill(undef)) 46 | 47 | T4(T5([1, 2, 3]), T5([1, 2, 3]))|>pprint 48 | 49 | pprint(T5(π)) 50 | 51 | pprint(T5(rand(100))) 52 | pprint(T5(Dict(1=>2))) 53 | pprint(T5(Dict())) 54 | pprint(T5(π)) 55 | pprint(T5(ℯ)) 56 | pprint(T5(fill(π))) 57 | 58 | pprint(T5(0.10f0)) 59 | pprint(T5("0.10f0")) 60 | pprint(T5(Dict("a"=>2.0, "b"=>2im))) 61 | pprint(T5(Dict("a"=>T4(T5([1, 2, 3]), T5([1, 2, 3])), "b"=>2im))) 62 | 63 | pprint(T5(Dict("a"=>(1, 2, 3), "b"=>Any))) 64 | 65 | a = TTTTTTTTTTTTTTTTTTTT(1, 2) 66 | b = TTTTTTTTTTTTTTTTTTTT(a, a) 67 | c = TTTTTTTTTTTTTTTTTTTT(b, b) 68 | 69 | pprint(c) 70 | 71 | end 72 | -------------------------------------------------------------------------------- /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | - push 4 | - pull_request 5 | jobs: 6 | test: 7 | name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | version: 13 | - '1' 14 | - '1.0' 15 | - 'nightly' 16 | os: 17 | - ubuntu-latest 18 | - macOS-latest 19 | arch: 20 | - x64 21 | steps: 22 | - uses: actions/checkout@v2 23 | - uses: julia-actions/setup-julia@v1 24 | with: 25 | version: ${{ matrix.version }} 26 | arch: ${{ matrix.arch }} 27 | - uses: actions/cache@v1 28 | env: 29 | cache-name: cache-artifacts 30 | with: 31 | path: ~/.julia/artifacts 32 | key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} 33 | restore-keys: | 34 | ${{ runner.os }}-test-${{ env.cache-name }}- 35 | ${{ runner.os }}-test- 36 | ${{ runner.os }}- 37 | - uses: julia-actions/julia-buildpkg@v1 38 | - uses: julia-actions/julia-runtest@v1 39 | - uses: julia-actions/julia-processcoverage@v1 40 | - uses: codecov/codecov-action@v1 41 | with: 42 | file: lcov.info 43 | -------------------------------------------------------------------------------- /test/dataframe.jl: -------------------------------------------------------------------------------- 1 | module TestDataFrame 2 | 3 | using GarishPrint 4 | using DataFrames 5 | using Test 6 | 7 | struct ABC{T1, T2, T3} 8 | hee::T1 9 | haa::T2 10 | hoo::T3 11 | end 12 | 13 | struct Example{T1, T2} 14 | field_a::T1 15 | field_b::T2 16 | abc::ABC 17 | end 18 | 19 | df = DataFrame(A = 1:4, B = ["M", "F", "F", "M"]) 20 | 21 | x = Example( 22 | Dict( 23 | "a"=>Example( 24 | [1, 2, 3], 25 | 2.0, 26 | ABC(1, 2.0im, 3.12f0), 27 | ), 28 | "str" => Set([1, 2, 3]), 29 | "boolean"=> false, 30 | "missing" => missing, 31 | "empty set" => Set(), 32 | "set" => Set([1, 2, 3]), 33 | "set{any}" => Set(Any[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]), 34 | "type" => Any, 35 | "matrix" => rand(10, 10), 36 | "dataframe" => df, 37 | "named_tuple" => (name="ABC", age=25), 38 | "nested" => Example( 39 | Dict( 40 | "a"=>Example( 41 | [1, 2, 3], 42 | 2.0, 43 | ABC(1, 2.0im, 3.12f0), 44 | ), 45 | ), 46 | undef, 47 | ABC(nothing, 1.2+2.1im, π), 48 | ) 49 | ), 50 | undef, 51 | ABC(nothing, 1.2+2.1im, π), 52 | ) 53 | 54 | pprint(x) 55 | pprint(x; color=false) 56 | pprint(x; compact=true) 57 | pprint(x; show_indent=false) 58 | 59 | pprint(IOContext(stdout, :color=>false), x) 60 | 61 | end 62 | -------------------------------------------------------------------------------- /docs/src/index.md: -------------------------------------------------------------------------------- 1 | # GarishPrint 2 | 3 | [![CI](https://github.com/Roger-luo/GarishPrint.jl/workflows/CI/badge.svg)](https://github.com/Roger-luo/GarishPrint.jl/actions) 4 | [![codecov](https://codecov.io/gh/Roger-luo/GarishPrint.jl/branch/master/graph/badge.svg?token=U604BQGRV1)](https://codecov.io/gh/Roger-luo/GarishPrint.jl) 5 | 6 | An opinioned pretty printing package for Julia objects. 7 | 8 | ## Installation 9 | 10 | ```@raw html 11 |

12 | GarishPrint is a   13 | 14 | 15 | Julia Language 16 | 17 |   package. To install GarishPrint, 18 | please open 19 | Julia's interactive session (known as REPL) and press ] key in the REPL to use the package mode, then type the following command 20 |

21 | ``` 22 | 23 | ```julia 24 | pkg> add GarishPrint 25 | ``` 26 | 27 | ## Usage 28 | 29 | there is only one function exported that is `pprint`, 30 | 31 | ```@docs 32 | pprint 33 | ``` 34 | 35 | here is a quick example 36 | 37 | ```julia 38 | using GarishPrint 39 | 40 | struct ABC{T1, T2, T3} 41 | hee::T1 42 | haa::T2 43 | hoo::T3 44 | end 45 | 46 | struct Example{T1, T2} 47 | field_a::T1 48 | field_b::T2 49 | abc::ABC 50 | end 51 | 52 | x = Example( 53 | Dict( 54 | "a"=>Example( 55 | [1, 2, 3], 56 | 2.0, 57 | ABC(1, 2.0im, 3.12f0), 58 | ), 59 | "str" => Set([1, 2, 3]), 60 | ), 61 | undef, 62 | ABC(nothing, 1.2+2.1im, π), 63 | ) 64 | 65 | pprint(x) 66 | ``` 67 | 68 | it will print the following 69 | 70 | ![readme-example](assets/readme-example.png) 71 | 72 | 73 | ## License 74 | 75 | MIT License 76 | -------------------------------------------------------------------------------- /docs/build/assets/warner.js: -------------------------------------------------------------------------------- 1 | function maybeAddWarning () { 2 | // DOCUMENTER_NEWEST is defined in versions.js, DOCUMENTER_CURRENT_VERSION and DOCUMENTER_STABLE 3 | // in siteinfo.js. 4 | // If either of these are undefined something went horribly wrong, so we abort. 5 | if ( 6 | window.DOCUMENTER_NEWEST === undefined || 7 | window.DOCUMENTER_CURRENT_VERSION === undefined || 8 | window.DOCUMENTER_STABLE === undefined 9 | ) { 10 | return 11 | }; 12 | 13 | // Current version is not a version number, so we can't tell if it's the newest version. Abort. 14 | if (!/v(\d+\.)*\d+/.test(window.DOCUMENTER_CURRENT_VERSION)) { 15 | return 16 | }; 17 | 18 | // Current version is newest version, so no need to add a warning. 19 | if (window.DOCUMENTER_NEWEST === window.DOCUMENTER_CURRENT_VERSION) { 20 | return 21 | }; 22 | 23 | // Add a noindex meta tag (unless one exists) so that search engines don't index this version of the docs. 24 | if (document.body.querySelector('meta[name="robots"]') === null) { 25 | const meta = document.createElement('meta'); 26 | meta.name = 'robots'; 27 | meta.content = 'noindex'; 28 | 29 | document.getElementsByTagName('head')[0].appendChild(meta); 30 | }; 31 | 32 | const div = document.createElement('div'); 33 | div.classList.add('outdated-warning-overlay'); 34 | const closer = document.createElement('button'); 35 | closer.classList.add('outdated-warning-closer', 'delete'); 36 | closer.addEventListener('click', function () { 37 | document.body.removeChild(div); 38 | }); 39 | const href = window.documenterBaseURL + '/../' + window.DOCUMENTER_STABLE; 40 | div.innerHTML = 'This documentation is not for the latest version.
Go to the latest documentation.'; 41 | div.appendChild(closer); 42 | document.body.appendChild(div); 43 | }; 44 | 45 | if (document.readyState === 'loading') { 46 | document.addEventListener('DOMContentLoaded', maybeAddWarning); 47 | } else { 48 | maybeAddWarning(); 49 | }; 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GarishPrint 2 | 3 | [![CI](https://github.com/Roger-luo/GarishPrint.jl/workflows/CI/badge.svg)](https://github.com/Roger-luo/GarishPrint.jl/actions) 4 | [![codecov](https://codecov.io/gh/Roger-luo/GarishPrint.jl/branch/master/graph/badge.svg?token=U604BQGRV1)](https://codecov.io/gh/Roger-luo/GarishPrint.jl) 5 | [![][docs-stable-img]][docs-stable-url] 6 | [![][docs-dev-img]][docs-dev-url] 7 | 8 | An opinioned pretty printing package for Julia objects. 9 | 10 | ## Installation 11 | 12 |

13 | GarishPrint is a   14 | 15 | 16 | Julia Language 17 | 18 |   package. To install GarishPrint, 19 | please open 20 | Julia's interactive session (known as REPL) and press ] key in the REPL to use the package mode, then type the following command 21 |

22 | 23 | ```julia 24 | pkg> add GarishPrint 25 | ``` 26 | 27 | ## Usage 28 | 29 | there is only one function exported that is `pprint`, here is a quick example 30 | 31 | ```julia 32 | using GarishPrint 33 | 34 | struct ABC{T1, T2, T3} 35 | hee::T1 36 | haa::T2 37 | hoo::T3 38 | end 39 | 40 | struct Example{T1, T2} 41 | field_a::T1 42 | field_b::T2 43 | abc::ABC 44 | end 45 | 46 | x = Example( 47 | Dict( 48 | "a"=>Example( 49 | [1, 2, 3], 50 | 2.0, 51 | ABC(1, 2.0im, 3.12f0), 52 | ), 53 | "str" => Set([1, 2, 3]), 54 | ), 55 | undef, 56 | ABC(nothing, 1.2+2.1im, π), 57 | ) 58 | 59 | pprint(x) 60 | ``` 61 | 62 | it will print the following 63 | 64 | ![readme-example](docs/src/assets/readme-example.png) 65 | 66 | Please read [documentation][docs-stable-url] for more advanced usage. 67 | 68 | ## License 69 | 70 | MIT License 71 | 72 | [docs-dev-img]: https://img.shields.io/badge/docs-dev-blue.svg 73 | [docs-dev-url]: https://Roger-luo.github.io/GarishPrint.jl/dev/ 74 | [docs-stable-img]: https://img.shields.io/badge/docs-stable-blue.svg 75 | [docs-stable-url]: https://Roger-luo.github.io/GarishPrint.jl/stable 76 | -------------------------------------------------------------------------------- /src/misc.jl: -------------------------------------------------------------------------------- 1 | function pprint(io::GarishIO, ::MIME"text/plain", t::Tuple) 2 | pprint_list_like(io, t, "(", ")") 3 | end 4 | 5 | function pprint(io::GarishIO, ::MIME"text/plain", s::Pair) 6 | pprint(io, s.first) 7 | print_operator(io, "=>") 8 | if !io.compact 9 | buf = IOBuffer() 10 | pprint(GarishIO(IOContext(buf, :color=>false), io), s.first) 11 | io.state.offset = length(String(take!(buf))) + 4 12 | end 13 | 14 | within_nextlevel(io) do 15 | upperlevel_type = io.state.type 16 | upperlevel_noindent_in_first_line = io.state.noindent_in_first_line 17 | io.state.type = StructField 18 | io.state.noindent_in_first_line = true 19 | pprint(io, s.second) 20 | io.state.noindent_in_first_line = upperlevel_noindent_in_first_line 21 | io.state.type = upperlevel_type 22 | end 23 | return 24 | end 25 | 26 | function pprint(io::GarishIO, ::MIME"text/plain", bool::Bool) 27 | print_token(show, io, :constant, bool) 28 | end 29 | 30 | function pprint(io::GarishIO, ::MIME"text/plain", s::AbstractString) 31 | print_token(show, io, :string, s) 32 | end 33 | 34 | function pprint(io::GarishIO, ::MIME"text/plain", ::UndefInitializer) 35 | print_token(io, :undef, "undef") 36 | end 37 | 38 | function pprint(io::GarishIO, ::MIME"text/plain", ::Nothing) 39 | print_token(io, :constant, "nothing") 40 | end 41 | 42 | function pprint(io::GarishIO, ::MIME"text/plain", ::Missing) 43 | print_token(io, :constant, "missing") 44 | end 45 | 46 | """ 47 | print_indent(io::GarishIO) 48 | 49 | Print an indentation. This should be only used under `MIME"text/plain"` or equivalent. 50 | """ 51 | function print_indent(io::GarishIO) 52 | io.compact && return 53 | io.state.level > 0 || return 54 | 55 | io.show_indent || return print(io, " "^(io.indent * io.state.level)) 56 | for _ in 1:io.state.level 57 | print_token(io, :comment, "│") 58 | print(io, " "^(io.indent - 1)) 59 | end 60 | end 61 | 62 | """ 63 | print_operator(io::GarishIO, op) 64 | 65 | Print an operator, such as `=`, `+`, `=>` etc. This should be only used under `MIME"text/plain"` or equivalent. 66 | """ 67 | function print_operator(io::GarishIO, op) 68 | io.compact || print(io, " ") 69 | print_token(io, :operator, op) 70 | io.compact || print(io, " ") 71 | end 72 | -------------------------------------------------------------------------------- /test/configs.jl: -------------------------------------------------------------------------------- 1 | module TestConfigs 2 | 3 | using Test 4 | using GarishPrint 5 | using Configurations 6 | 7 | 8 | struct OptionA 9 | a::Int 10 | b::Int 11 | end 12 | 13 | struct OptionB 14 | a::Vector{Int} 15 | b::OptionA 16 | end 17 | 18 | Base.show(io::IO, x::OptionA) = GarishPrint.pprint_struct(io, x) 19 | Base.show(io::IO, x::OptionB) = GarishPrint.pprint_struct(io, x) 20 | 21 | opt = OptionB([1, 2, 3], OptionA(2, 2)) 22 | pprint_struct(opt) 23 | 24 | @option "geometry" struct Geometry 25 | L::Int 26 | graph::Int 27 | radius::Float64 = 1.5 28 | end 29 | 30 | @option "emulation" struct Emulation 31 | pulse::String 32 | algo::String # = "Vern8" 33 | precision::String # = "float32" 34 | reltol::Maybe{Float64} = nothing 35 | abstol::Maybe{Float64} = nothing 36 | dt::Maybe{Float64} = nothing 37 | total_time::Vector{Int} = collect(1:7) 38 | postprocess::Bool = false 39 | gen_subspace::Bool = false 40 | geometry::Geometry 41 | end 42 | 43 | @option "postprocess" struct PostProcess 44 | pulse::String 45 | algo::String 46 | precision::String 47 | total_time::Vector{Int} = collect(1:7) 48 | gen_mappings::Bool=false 49 | skip_done::Bool=false 50 | geometry::Geometry 51 | end 52 | 53 | @option "cache" struct Cache 54 | subspace::Maybe{Geometry} = nothing 55 | postprocess::Maybe{Geometry} = nothing 56 | end 57 | 58 | @option struct JobInstance 59 | project::String 60 | device::Maybe{Int} = nothing 61 | emulation::Vector{Emulation} = Emulation[] 62 | postprocess::Vector{PostProcess} = PostProcess[] 63 | cache::Vector{Cache} = Cache[] 64 | end 65 | 66 | Base.show(io::IO, x::JobInstance) = pprint_struct(io, x; include_defaults=get(io, :include_defaults, false)) 67 | Base.show(io::IO, x::Cache) = pprint_struct(io, x; include_defaults=false) 68 | Base.show(io::IO, x::PostProcess) = pprint_struct(io, x; include_defaults=false) 69 | Base.show(io::IO, x::Emulation) = pprint_struct(io, x; include_defaults=false) 70 | Base.show(io::IO, x::Geometry) = pprint_struct(io, x; include_defaults=false) 71 | 72 | opt = JobInstance( 73 | project="test", 74 | emulation=[ 75 | Emulation(;pulse="linear", algo="Vern8", precision="float32", geometry=Geometry(8, 188, 1.5)), 76 | Emulation(;pulse="linear", algo="Vern8", precision="float32", geometry=Geometry(8, 188, 1.5)), 77 | ], 78 | postprocess=[ 79 | PostProcess(pulse="linear", algo="Vern8", precision="float32", geometry=Geometry(8, 188, 1.5)), 80 | PostProcess(pulse="linear", algo="Vern8", precision="float32", geometry=Geometry(8, 188, 1.5)), 81 | ] 82 | ) 83 | 84 | show(stdout, MIME"text/plain"(), opt) 85 | end 86 | -------------------------------------------------------------------------------- /docs/build/assets/themeswap.js: -------------------------------------------------------------------------------- 1 | // Small function to quickly swap out themes. Gets put into the tag.. 2 | function set_theme_from_local_storage() { 3 | // Intialize the theme to null, which means default 4 | var theme = null; 5 | // If the browser supports the localstorage and is not disabled then try to get the 6 | // documenter theme 7 | if(window.localStorage != null) { 8 | // Get the user-picked theme from localStorage. May be `null`, which means the default 9 | // theme. 10 | theme = window.localStorage.getItem("documenter-theme"); 11 | } 12 | // Check if the browser supports user color preference 13 | var darkPreference = false; 14 | // Check if the users preference is for dark color scheme 15 | if(window.matchMedia('(prefers-color-scheme: dark)').matches === true) { 16 | darkPreference = true; 17 | } 18 | // Initialize a few variables for the loop: 19 | // 20 | // - active: will contain the index of the theme that should be active. Note that there 21 | // is no guarantee that localStorage contains sane values. If `active` stays `null` 22 | // we either could not find the theme or it is the default (primary) theme anyway. 23 | // Either way, we then need to stick to the primary theme. 24 | // 25 | // - disabled: style sheets that should be disabled (i.e. all the theme style sheets 26 | // that are not the currently active theme) 27 | var active = null; var disabled = []; var darkTheme = null; 28 | for (var i = 0; i < document.styleSheets.length; i++) { 29 | var ss = document.styleSheets[i]; 30 | // The tag of each style sheet is expected to have a data-theme-name attribute 31 | // which must contain the name of the theme. The names in localStorage much match this. 32 | var themename = ss.ownerNode.getAttribute("data-theme-name"); 33 | // attribute not set => non-theme stylesheet => ignore 34 | if(themename === null) continue; 35 | // To distinguish the default (primary) theme, it needs to have the data-theme-primary 36 | // attribute set. 37 | var isprimary = (ss.ownerNode.getAttribute("data-theme-primary") !== null); 38 | // Check if the theme is primary dark theme 39 | var isDarkTheme = (ss.ownerNode.getAttribute("data-theme-primary-dark") !== null); 40 | // If ss is for dark theme then set the value of darkTheme to the name of the theme 41 | if(isDarkTheme) darkTheme = themename; 42 | // If we find a matching theme (and it's not the default), we'll set active to non-null 43 | if(themename === theme) active = i; 44 | // Store the style sheets of inactive themes so that we could disable them 45 | if(themename !== theme) disabled.push(ss); 46 | } 47 | if(active !== null) { 48 | // If we did find an active theme, we'll (1) add the theme--$(theme) class to 49 | document.getElementsByTagName('html')[0].className = "theme--" + theme; 50 | // and (2) disable all the other theme stylesheets 51 | disabled.forEach(function(ss){ 52 | ss.disabled = true; 53 | }); 54 | } 55 | else if(darkTheme !== null && darkPreference === true) { 56 | // If we did find an active theme, we'll (1) add the theme--$(theme) class to 57 | document.getElementsByTagName('html')[0].className = "theme--" + darkTheme; 58 | // and (2) disable all the other theme stylesheets 59 | disabled.forEach(function(ss){ 60 | if (ss.ownerNode.getAttribute("data-theme-name") !== darkTheme) { 61 | ss.disabled = true; 62 | } 63 | }); 64 | } 65 | } 66 | set_theme_from_local_storage(); 67 | -------------------------------------------------------------------------------- /docs/build/assets/indigo.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: JuliaMono; 3 | src: local("JuliaMono"), url("https://cdn.jsdelivr.net/gh/cormullion/juliamono/webfonts/JuliaMono-Regular.woff2"); } 4 | 5 | html.theme--documenter-dark pre, 6 | html.theme--documenter-dark code { 7 | font-family: "JuliaMono"; } 8 | 9 | html:not(.theme--documenter-dark) body #documenter a { 10 | color: #4595D1; } 11 | 12 | html:not(.theme--documenter-dark) body #documenter a:hover, html:not(.theme--documenter-dark) body #documenter a:focus { 13 | color: #194E82; } 14 | 15 | html:not(.theme--documenter-dark) body #documenter .docs-sidebar { 16 | box-shadow: none; 17 | color: #FFFFFF; 18 | background-color: #194E82; } 19 | html:not(.theme--documenter-dark) body #documenter .docs-sidebar ul.docs-menu { 20 | border-top: none; } 21 | html:not(.theme--documenter-dark) body #documenter .docs-sidebar ul.docs-menu .tocitem:hover, html:not(.theme--documenter-dark) body #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem, html:not(.theme--documenter-dark) body #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover, html:not(.theme--documenter-dark) body #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover { 22 | color: #FFFFFF; 23 | background-color: #4595D1; } 24 | html:not(.theme--documenter-dark) body #documenter .docs-sidebar ul.docs-menu .tocitem { 25 | color: #FFFFFF; 26 | background: none; } 27 | html:not(.theme--documenter-dark) body #documenter .docs-sidebar ul.docs-menu li.is-active { 28 | border-top: none; 29 | border-bottom: none; } 30 | html:not(.theme--documenter-dark) body #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal { 31 | margin: 0; 32 | border-top: none; } 33 | html:not(.theme--documenter-dark) body #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal li { 34 | margin-top: 0; } 35 | html:not(.theme--documenter-dark) body #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem { 36 | color: #194E82; 37 | background-color: #FFFFFF; 38 | padding: 0.5em; 39 | padding-left: 1em; } 40 | 41 | html:not(.theme--documenter-dark) body #documenter article#documenter-page a.docs-heading-anchor { 42 | color: #194E82; } 43 | 44 | html:not(.theme--documenter-dark) body #documenter pre, html:not(.theme--documenter-dark) body #documenter code { 45 | color: inherit; 46 | font-family: "JuliaMono"; } 47 | html:not(.theme--documenter-dark) body #documenter pre .hljs-meta, html:not(.theme--documenter-dark) body #documenter code .hljs-meta { 48 | color: #4595D1; } 49 | html:not(.theme--documenter-dark) body #documenter pre .hljs-keyword, html:not(.theme--documenter-dark) body #documenter code .hljs-keyword { 50 | color: #194E82; } 51 | 52 | .admonition.is-category-terminology { 53 | background-color: #FFFEDD; 54 | border-color: #FFEC8B; } 55 | .admonition.is-category-terminology > .admonition-header { 56 | background-color: #FFEC8B; 57 | color: black; } 58 | .admonition.is-category-terminology > .admonition-header:before { 59 | content: "Terminology: "; 60 | font-family: inherit; 61 | font-weight: bold; } 62 | 63 | html.theme--documenter-dark .admonition.is-category-terminology { 64 | border-color: #FFEC8B; } 65 | 66 | details { 67 | padding-left: 1rem; 68 | padding-right: 1rem; 69 | padding-bottom: 1rem; 70 | background: aliceblue; } 71 | 72 | html.theme--documenter-dark details { 73 | background: #282f2f; } 74 | -------------------------------------------------------------------------------- /src/color.jl: -------------------------------------------------------------------------------- 1 | """ 2 | tty_has_color() 3 | 4 | Check if TTY supports color. This is mainly for lower 5 | Julia version like 1.0. 6 | """ 7 | function tty_has_color() 8 | if isdefined(Base, :get_have_color) 9 | return Base.get_have_color() 10 | else 11 | return Base.have_color 12 | end 13 | end 14 | 15 | """ 16 | supports_color256() 17 | 18 | Check if the terminal supports color 256. 19 | """ 20 | function supports_color256() 21 | haskey(ENV, "TERM") || return false 22 | try 23 | return parse(Int, readchomp(`tput colors 0`)) == 256 24 | catch 25 | return false 26 | end 27 | end 28 | 29 | const ColorType = Union{Int, Symbol} 30 | 31 | """ 32 | ColorPreference 33 | 34 | The color preference type. 35 | """ 36 | struct ColorPreference 37 | fieldname::ColorType 38 | type::ColorType 39 | operator::ColorType 40 | 41 | # literal-like 42 | literal::ColorType 43 | constant::ColorType 44 | number::ColorType 45 | string::ColorType 46 | 47 | # comment-like 48 | comment::ColorType 49 | undef::ColorType 50 | linenumber::ColorType 51 | end 52 | 53 | struct PreferenceInvalid <: Exception 54 | key::String 55 | type 56 | got 57 | end 58 | 59 | function Base.showerror(io::IO, x::PreferenceInvalid) 60 | print(io, "preference for ") 61 | printstyled(io, x.key; color=:light_blue) 62 | print(io, " is invalid, expect ") 63 | printstyled(io, x.type; color=:green) 64 | print(io, " got: ", repr(x.got)) 65 | end 66 | 67 | Base.show(io::IO, x::ColorPreference) = pprint_struct(io, x) 68 | 69 | """ 70 | ColorPreference(;kw...) 71 | 72 | See [`pprint`](@ref) for available keyword configurations. 73 | """ 74 | function ColorPreference(;kw...) 75 | colors = supports_color256() ? default_colors_256() : default_colors_ansi() 76 | if color_prefs_toml !== nothing 77 | merge!(colors, color_prefs_toml) 78 | end 79 | colors = merge!(colors, kw) 80 | 81 | args = map(fieldnames(ColorPreference)) do name 82 | val = colors[string(name)] 83 | if val isa String 84 | return Symbol(val) 85 | elseif val isa Int 86 | return val 87 | else 88 | throw(PreferenceInvalid("GarishPrint.color.$name", Union{String, Int}, val)) 89 | end 90 | end 91 | return ColorPreference(args...) 92 | end 93 | 94 | """ 95 | default_colors_ansi() 96 | 97 | The default ANSI color theme. 98 | """ 99 | function default_colors_ansi() 100 | Dict{String, Any}( 101 | "fieldname" => "light_blue", 102 | "type" => "green", 103 | "operator" => "normal", 104 | "literal" => "yellow", 105 | "constant" => "yellow", 106 | "number" => "normal", 107 | "string" => "yellow", 108 | "comment" => "light_black", 109 | "undef" => "normal", 110 | "linenumber" => "light_black", 111 | ) 112 | end 113 | 114 | """ 115 | default_colors_256() 116 | 117 | The default color 256 theme. 118 | """ 119 | function default_colors_256() 120 | Dict{String, Any}( 121 | "fieldname" => 039, 122 | "type" => 037, 123 | "operator" => 196, 124 | "literal" => 140, 125 | "constant" => 099, 126 | "number" => 140, 127 | "string" => 180, 128 | "comment" => 240, 129 | # undef is actually a constant 130 | "undef" => 099, 131 | "linenumber" => 240, 132 | ) 133 | end 134 | -------------------------------------------------------------------------------- /docs/build/search/index.html: -------------------------------------------------------------------------------- 1 | 2 | Search · GarishPrint.jl

Loading search...

    3 | -------------------------------------------------------------------------------- /src/struct.jl: -------------------------------------------------------------------------------- 1 | """ 2 | pprint_struct([io::IO=stdout], [mimetype], x; kw...) 3 | 4 | Pretty print object `x` that is a struct type (`isstructtype` returns `true`). 5 | 6 | # Keyword Arguments 7 | 8 | See [`pprint`](@ref), they share the same keyword arguments. 9 | """ 10 | function pprint_struct end 11 | 12 | pprint_struct(@nospecialize(x); kw...) = pprint_struct(stdout, x; kw...) 13 | 14 | function pprint_struct(io::IO, @nospecialize(x);kw...) 15 | pprint_struct(GarishIO(io; kw...), x) 16 | end 17 | 18 | function pprint_struct(io::GarishIO, @nospecialize(x)) 19 | pprint_struct(io, MIME"text/plain"(), x) 20 | end 21 | 22 | """ 23 | pprint_struct(io, ::MIME"text/plain", @nospecialize(x)) 24 | 25 | Print `x` as a struct type with mime type `MIME"text/plain"`. 26 | """ 27 | function pprint_struct(io::GarishIO, mime::MIME"text/plain", @nospecialize(x)) 28 | t = typeof(x) 29 | isstructtype(t) || throw(ArgumentError("expect a struct type, got $t")) 30 | pprint_struct_type(io, mime, t); print(io.bland_io, "(") 31 | 32 | nf = nfields(x)::Int 33 | nf == 0 && return print(io.bland_io, ")") 34 | 35 | io.compact || println(io.bland_io) 36 | 37 | # findout fields to print 38 | fields_to_print = Int[] 39 | for i in 1:nf 40 | f = fieldname(t, i) 41 | value = getfield(x, i) 42 | if !io.include_defaults && is_option(x) && value == field_default(t, f) 43 | else 44 | push!(fields_to_print, i) 45 | end 46 | end 47 | 48 | within_nextlevel(io) do 49 | for i in fields_to_print 50 | f = fieldname(t, i) 51 | value = getfield(x, i) 52 | print_indent(io) 53 | print_token(io, :fieldname, f) 54 | if io.compact 55 | print(io.bland_io, "=") 56 | else 57 | print(io.bland_io, " = ") 58 | io.state.offset = 3 + length(string(f)) 59 | end 60 | 61 | if !isdefined(x, f) # print undef as comment color 62 | pprint(io, undef) 63 | else 64 | new_io = GarishIO(io; limit=true) 65 | pprint_field(new_io, mime, value) 66 | end 67 | 68 | if !io.compact || i != last(fields_to_print) 69 | print(io.bland_io, ", ") 70 | end 71 | 72 | if i != last(fields_to_print) 73 | io.compact || println(io.bland_io) 74 | end 75 | end 76 | end 77 | io.compact || println(io.bland_io) 78 | print_indent(io) 79 | print(io.bland_io, ")") 80 | end 81 | 82 | function pprint_struct_type(io::GarishIO, mime::MIME"text/plain", @nospecialize(x)) 83 | if x isa DataType 84 | # max_indent_reached = io.indent * io.state.level + io.state.offset + length(string(t)) + 2 > io.displaysize[2] 85 | if max_indent_reached(io, length(string(x)) + 2) 86 | if isempty(x.parameters) 87 | # nothing we can do here, let it break line 88 | print_token(io, :type, x) 89 | else 90 | print_token(io, :type, nameof(x)); print_token(io, :type, "{") 91 | println(io.bland_io) 92 | within_nextlevel(io) do 93 | len_params = sum(length(string(p)) for p in x.parameters) + 2 * length(x.parameters) 94 | if max_indent_reached(io, len_params) 95 | for p in x.parameters 96 | print_indent(io) 97 | pprint_struct_type(io, mime, p) 98 | print(io.bland_io, ", ") 99 | println(io.bland_io) 100 | # if p !== last(x.parameters) 101 | # end 102 | end 103 | else 104 | # try to print parameters in one line 105 | print_indent(io) 106 | print_token(io, :type, join(x.parameters, ", ")) 107 | println(io.bland_io) 108 | end 109 | end 110 | print_indent(io) 111 | print_token(io, :type, "}") 112 | end 113 | else 114 | print_token(io, :type, x) 115 | end 116 | else 117 | print_token(io, :type, x) 118 | end 119 | end 120 | 121 | pprint_field(io::GarishIO, x) = pprint_field(io, MIME"text/plain"(), x) 122 | 123 | function pprint_field(io::GarishIO, mime::MIME"text/plain", x) 124 | upperlevel_type = io.state.type 125 | upperlevel_noindent_in_first_line = io.state.noindent_in_first_line 126 | io.state.type = StructField 127 | io.state.noindent_in_first_line = true 128 | pprint(io, mime, x) 129 | io.state.noindent_in_first_line = upperlevel_noindent_in_first_line 130 | io.state.type = upperlevel_type 131 | end 132 | -------------------------------------------------------------------------------- /docs/Manifest.toml: -------------------------------------------------------------------------------- 1 | # This file is machine-generated - editing it directly is not advised 2 | 3 | [[ArgTools]] 4 | uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" 5 | 6 | [[Artifacts]] 7 | uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" 8 | 9 | [[Base64]] 10 | uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" 11 | 12 | [[Dates]] 13 | deps = ["Printf"] 14 | uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" 15 | 16 | [[DocStringExtensions]] 17 | deps = ["LibGit2"] 18 | git-tree-sha1 = "a32185f5428d3986f47c2ab78b1f216d5e6cc96f" 19 | uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" 20 | version = "0.8.5" 21 | 22 | [[DocThemeIndigo]] 23 | deps = ["Sass"] 24 | git-tree-sha1 = "7b15d5e64ae6e27f8cc9eaff280c305199c6bfc7" 25 | uuid = "8bac0ac5-51bf-41f9-885e-2bf1ac2bec5f" 26 | version = "0.1.0" 27 | 28 | [[Documenter]] 29 | deps = ["Base64", "Dates", "DocStringExtensions", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "REPL", "Test", "Unicode"] 30 | git-tree-sha1 = "621850838b3e74dd6dd047b5432d2e976877104e" 31 | uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" 32 | version = "0.27.2" 33 | 34 | [[Downloads]] 35 | deps = ["ArgTools", "LibCURL", "NetworkOptions"] 36 | uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" 37 | 38 | [[GarishPrint]] 39 | path = ".." 40 | uuid = "b0ab02a7-8576-43f7-aa76-eaa7c3897c54" 41 | version = "0.1.0" 42 | 43 | [[IOCapture]] 44 | deps = ["Logging", "Random"] 45 | git-tree-sha1 = "f7be53659ab06ddc986428d3a9dcc95f6fa6705a" 46 | uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" 47 | version = "0.2.2" 48 | 49 | [[InteractiveUtils]] 50 | deps = ["Markdown"] 51 | uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" 52 | 53 | [[JLLWrappers]] 54 | deps = ["Preferences"] 55 | git-tree-sha1 = "642a199af8b68253517b80bd3bfd17eb4e84df6e" 56 | uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" 57 | version = "1.3.0" 58 | 59 | [[JSON]] 60 | deps = ["Dates", "Mmap", "Parsers", "Unicode"] 61 | git-tree-sha1 = "81690084b6198a2e1da36fcfda16eeca9f9f24e4" 62 | uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" 63 | version = "0.21.1" 64 | 65 | [[LibCURL]] 66 | deps = ["LibCURL_jll", "MozillaCACerts_jll"] 67 | uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" 68 | 69 | [[LibCURL_jll]] 70 | deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] 71 | uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" 72 | 73 | [[LibGit2]] 74 | deps = ["Base64", "NetworkOptions", "Printf", "SHA"] 75 | uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" 76 | 77 | [[LibSSH2_jll]] 78 | deps = ["Artifacts", "Libdl", "MbedTLS_jll"] 79 | uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" 80 | 81 | [[Libdl]] 82 | uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" 83 | 84 | [[Logging]] 85 | uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" 86 | 87 | [[Markdown]] 88 | deps = ["Base64"] 89 | uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" 90 | 91 | [[MbedTLS_jll]] 92 | deps = ["Artifacts", "Libdl"] 93 | uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" 94 | 95 | [[Mmap]] 96 | uuid = "a63ad114-7e13-5084-954f-fe012c677804" 97 | 98 | [[MozillaCACerts_jll]] 99 | uuid = "14a3606d-f60d-562e-9121-12d972cd8159" 100 | 101 | [[NetworkOptions]] 102 | uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" 103 | 104 | [[Parsers]] 105 | deps = ["Dates"] 106 | git-tree-sha1 = "c8abc88faa3f7a3950832ac5d6e690881590d6dc" 107 | uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" 108 | version = "1.1.0" 109 | 110 | [[Pkg]] 111 | deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] 112 | uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" 113 | 114 | [[Preferences]] 115 | deps = ["TOML"] 116 | git-tree-sha1 = "00cfd92944ca9c760982747e9a1d0d5d86ab1e5a" 117 | uuid = "21216c6a-2e73-6563-6e65-726566657250" 118 | version = "1.2.2" 119 | 120 | [[Printf]] 121 | deps = ["Unicode"] 122 | uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" 123 | 124 | [[REPL]] 125 | deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] 126 | uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" 127 | 128 | [[Random]] 129 | deps = ["Serialization"] 130 | uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" 131 | 132 | [[SHA]] 133 | uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" 134 | 135 | [[Sass]] 136 | deps = ["libsass_jll"] 137 | git-tree-sha1 = "aa841c3738cec78b5dbccd56dda332710f35f6a5" 138 | uuid = "322a6be2-4ae8-5d68-aaf1-3e960788d1d9" 139 | version = "0.2.0" 140 | 141 | [[Serialization]] 142 | uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" 143 | 144 | [[Sockets]] 145 | uuid = "6462fe0b-24de-5631-8697-dd941f90decc" 146 | 147 | [[TOML]] 148 | deps = ["Dates"] 149 | uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" 150 | 151 | [[Tar]] 152 | deps = ["ArgTools", "SHA"] 153 | uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" 154 | 155 | [[Test]] 156 | deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] 157 | uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" 158 | 159 | [[UUIDs]] 160 | deps = ["Random", "SHA"] 161 | uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" 162 | 163 | [[Unicode]] 164 | uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" 165 | 166 | [[Zlib_jll]] 167 | deps = ["Libdl"] 168 | uuid = "83775a58-1f1d-513f-b197-d71354ab007a" 169 | 170 | [[libsass_jll]] 171 | deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] 172 | git-tree-sha1 = "663428b7ebaf60c60ee147f0f9466430e9959ad6" 173 | uuid = "47bcb7c8-5119-555a-9eeb-0afcc36cd728" 174 | version = "3.5.5+0" 175 | 176 | [[nghttp2_jll]] 177 | deps = ["Artifacts", "Libdl"] 178 | uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" 179 | 180 | [[p7zip_jll]] 181 | deps = ["Artifacts", "Libdl"] 182 | uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" 183 | -------------------------------------------------------------------------------- /src/pprint.jl: -------------------------------------------------------------------------------- 1 | # NOTE: unlike `Base.show` we always ask for explicit MIME type 2 | 3 | """ 4 | pprint([io::IO=stdout], [mimetype], x; kw...) 5 | 6 | Pretty print an object `x` to `io`, default `io` is `stdout`. 7 | 8 | !!! note 9 | 10 | `pprint` will detect if an object type has overloaded `Base.show`, 11 | and use that if possible, overloading `Base.show` to `GarishPrint` 12 | for custom type should use [`pprint_struct`](@ref) to avoid 13 | recursive call into `Base.show`. 14 | 15 | # Keyword Arguments 16 | 17 | - `indent::Int`: indent size, default is `2`. 18 | - `compact::Bool`: whether print withint one line, default is `get(io, :compact, false)`. 19 | - `limit::Bool`: whether the print is limited, default is `get(io, :compact, false)`. 20 | - `displaysize::Tuple{Int, Int}`: the displaysize hint of printed string, note this is not stricted obeyed, 21 | default is `displaysize(io)`. 22 | - `show_indent::Bool`: whether print indentation hint, default is `true`. 23 | - `color::Bool`: whether print with color, default is `true`. 24 | 25 | ## Keyword Arguments for option struct defined by Configurations 26 | 27 | - `include_defaults::Bool`: whether print the default values, 28 | default is `false` to provide more compact printing in REPL. 29 | 30 | ## Color Preference 31 | 32 | color preference is available as keyword arguments to override the 33 | default color scheme. These arguments may take any of the values 34 | `:normal`, `:default`, `:bold`, `:black`, `:blink`, `:blue`, 35 | `:cyan`, `:green`, `:hidden`, `:light_black`, `:light_blue`, `:light_cyan`, `:light_green`, 36 | `:light_magenta`, `:light_red`, `:light_yellow`, `:magenta`, `:nothing`, `:red`, `:reverse`, 37 | `:underline`, `:white`, or `:yellow` or an integer between 0 and 255 inclusive. Note that 38 | not all terminals support 256 colors. 39 | 40 | The default color scheme can be checked via `GarishPrint.default_colors_256()` for 256 color, 41 | and `GarishPrint.default_colors_ansi()` for ANSI color. The 256 color will be used when 42 | the terminal is detected to support 256 color. 43 | 44 | - `fieldname`: field name of a struct. 45 | - `type`: the color of a type. 46 | - `operator`: the color of an operator, e.g `+`, `=>`. 47 | - `literal`: the color of literals. 48 | - `constant`: the color of constants, e.g `π`. 49 | - `number`: the color of numbers, e.g `1.2`, `1`. 50 | - `string`: the color of string. 51 | - `comment`: comments, e.g `# some comments` 52 | - `undef`: the const binding to `UndefInitializer` 53 | - `linenumber`: line numbers. 54 | 55 | # Notes 56 | 57 | The color print and compact print can also be turned on/off by 58 | setting `IOContext`, e.g `IOContext(io, :color=>false)` will print 59 | without color, and `IOContext(io, :compact=>true)` will print within 60 | one line. This is also what the standard Julia `IO` objects follows 61 | in printing by default. 62 | """ 63 | function pprint end 64 | 65 | pprint(x; kw...) = pprint(stdout, x; kw...) 66 | pprint(io::IO, x;kw...) = pprint(io, MIME"text/plain"(), x; kw...) 67 | # wrap other IO with GarishIO 68 | pprint(io::IO, m::MIME, x; kw...) = pprint(GarishIO(io; kw...), m, x) 69 | 70 | # Type 71 | pprint(io::GarishIO, mime::MIME, @specialize(x::Type)) = show(io, mime, x) 72 | pprint(io::GarishIO, ::MIME"text/plain", @specialize(x::Type)) = print_token(io, :type, x) 73 | 74 | # Struct 75 | function pprint(io::GarishIO, mime::MIME, @nospecialize(x)) 76 | if fallback_to_default_show(io, x) && isstructtype(typeof(x)) 77 | return pprint_struct(io, mime, x) 78 | elseif io.state.level > 0 # print show inside 79 | show_text_within(io, mime, x) 80 | else # fallback to show unless it is a struct type 81 | show(IOContext(io), mime, x) 82 | end 83 | end 84 | 85 | function show_text_within(io::GarishIO, mime::MIME, x) 86 | buf = IOBuffer() 87 | indentation = io.indent * io.state.level + io.state.offset 88 | new_displaysize = (io.displaysize[1], io.displaysize[2] - indentation) 89 | 90 | buf_io = GarishIO(buf, io; limit=true, displaysize=new_displaysize, state=PrintState()) 91 | show(buf_io, mime, x) 92 | raw = String(take!(buf)) 93 | buf_lines = split(raw, '\n') 94 | for k in 1:length(buf_lines)-1 95 | line = buf_lines[k] 96 | if !(io.state.noindent_in_first_line && k == 1) 97 | print_indent(io) 98 | end 99 | println(io.bland_io, line) 100 | end 101 | 102 | # pretty print last line 103 | last_line = buf_lines[end] 104 | length(buf_lines) == 1 || print_indent(io) 105 | if endswith(last_line, ')') 106 | print(io.bland_io, last_line) 107 | else 108 | print(io.bland_io, last_line) 109 | if length(buf_lines) > 1 110 | println(io) 111 | print_indent(io) # force put a new line at the end 112 | end 113 | end 114 | return 115 | end 116 | 117 | function fallback_to_default_show(io::IO, x) 118 | # NOTE: Base.show(::IO, ::MIME"text/plain", ::Any) forwards to 119 | # Base.show(::IO, ::Any) 120 | 121 | # check if we are gonna call Base.show(::IO, ::MIME"text/plain", ::Any) 122 | mt = methods(Base.show, (typeof(io), MIME"text/plain", typeof(x))) 123 | length(mt.ms) == 1 && any(mt.ms) do method 124 | method.sig == Tuple{typeof(Base.show), IO, MIME"text/plain", Any} 125 | end || return false 126 | 127 | # check if we are gonna call Base.show(::IO, ::Any) 128 | mt = methods(Base.show, (typeof(io), typeof(x))) 129 | length(mt.ms) == 1 && return any(mt.ms) do method 130 | method.sig == Tuple{typeof(Base.show), IO, Any} 131 | end 132 | end 133 | -------------------------------------------------------------------------------- /src/arrays.jl: -------------------------------------------------------------------------------- 1 | function pprint(io::GarishIO, mime::MIME"text/plain", X::AbstractArray) 2 | # use default array printing if it's the root 3 | io.state.level == 0 && return show(io, mime, X) 4 | ndims(X) == 0 && return pprint_zero_dim(io, X) 5 | 6 | if ndims(X) == 1 7 | # io.compact && return pprint_list_like(io, X) 8 | # heurostics to print vector in compact form 9 | if length(X) < 20 && !max_indent_reached(io, length(string(X))) 10 | pprint_list_like(io, X; compact=true) 11 | else 12 | pprint_list_like(io, X) 13 | end 14 | return 15 | end 16 | # fallback to compact show for high dimensional arrays 17 | # since we cannot control the indent in multi-line printing 18 | # not implemented with pprint interface 19 | if io.compact 20 | return show(io, X) 21 | else 22 | return show_text_within(io, MIME"text/plain"(), X) 23 | end 24 | # return show(io, X) 25 | end 26 | 27 | # NOTE: modified based on base/arrayshow.jl:show_zero_dim 28 | function pprint_zero_dim(io::GarishIO, X::AbstractArray{T, 0}) where T 29 | if isassigned(X) 30 | print(io, "fill(") 31 | pprint(io, X[]) 32 | else 33 | print_token(io, :type, "Array{", T, ", 0}(") 34 | pprint(io, undef) 35 | end 36 | print(io, ")") 37 | end 38 | 39 | # NOTE: modified based on base/arrayshow.jl:show_vector 40 | 41 | """ 42 | pprint_list_like(io::GarishIO, list, opn='[', cls=']'; compact::Bool=io.compact) 43 | 44 | Print a list-like object `list`. A list-like object should support the iterable interface 45 | such as `Base.iterate` and `Base.length`. This is modified based on `base/arrayshow.jl:show_vector`. 46 | 47 | # Arguments 48 | 49 | - `io::GarishIO`: the `GarishIO` object one wants to print to. 50 | - `list`: the list-like object. 51 | - `opn`: the openning marker, default is `[`. 52 | - `cls`: the closing marker, default is `]`. 53 | 54 | # Keyword Arguments 55 | 56 | - `compact::Bool`: print the list within one line or not. 57 | """ 58 | function pprint_list_like(io::GarishIO, list, opn='[', cls=']'; compact::Bool=io.compact) 59 | prefix, implicit = typeinfo_prefix(io.bland_io, list) 60 | io.state.noindent_in_first_line || print_indent(io) 61 | print_token(io, :type, prefix) 62 | 63 | # directly or indirectly, the context now knows about eltype(v) 64 | if !implicit 65 | io = GarishIO(IOContext(io.bland_io, :typeinfo => eltype(list)), io) 66 | end 67 | limited = get(io, :limit, false) 68 | 69 | if limited && length(list) > 20 70 | axs1 = Base.axes1(list) 71 | f, l = first(axs1), last(axs1) 72 | pprint_delim_list(io, list, opn, ",", "", false, compact, f, f+9) 73 | print(io, " … ") 74 | pprint_delim_list(io, list, "", ",", cls, false, compact, l-9, l) 75 | else 76 | pprint_delim_list(io, list, opn, ",", cls, false, compact) 77 | end 78 | end 79 | 80 | # NOTE: copied from base/show.jl:show_delim_array to use pprint for elements 81 | function pprint_delim_list(io::GarishIO, itr, op, delim, cl, delim_one, compact, i1=1, n=typemax(Int)) 82 | print(io.bland_io, op) 83 | compact || println(io) 84 | 85 | within_nextlevel(io) do 86 | if !Base.show_circular(io, itr) 87 | recur_io = IOContext(io.bland_io, :SHOWN_SET => itr) 88 | y = iterate(itr) 89 | first = true 90 | i0 = i1-1 91 | while i1 > 1 && y !== nothing 92 | y = iterate(itr, y[2]) 93 | i1 -= 1 94 | end 95 | if y !== nothing 96 | typeinfo = get(io.bland_io, :typeinfo, Any) 97 | while true 98 | x = y[1] 99 | y = iterate(itr, y[2]) 100 | io_typeinfo = itr isa typeinfo <: Tuple ? fieldtype(typeinfo, i1+i0) : typeinfo 101 | bland_io = IOContext(recur_io, :typeinfo => io_typeinfo) 102 | nested_io = GarishIO(bland_io, io) 103 | 104 | compact || print_indent(io) 105 | pprint(nested_io, x) 106 | 107 | i1 += 1 108 | if y === nothing || i1 > n 109 | if delim_one && first 110 | print(io.bland_io, delim) 111 | compact || println(io.bland_io) 112 | end 113 | break 114 | end 115 | first = false 116 | 117 | print(io.bland_io, delim) 118 | print(io.bland_io, ' ') 119 | compact || println(io.bland_io) 120 | end 121 | end 122 | end 123 | 124 | if !compact 125 | print(io.bland_io, delim) 126 | print(io.bland_io, ' ') 127 | println(io.bland_io) 128 | end 129 | end 130 | compact || print_indent(io) 131 | print(io.bland_io, cl) 132 | end 133 | 134 | 135 | # NOTE: copied from base/arrayshow.jl:typeinfo_prefix(io::IO, X) for compatiblity 136 | function typeinfo_prefix(io::IO, X) 137 | typeinfo = get(io, :typeinfo, Any)::Type 138 | 139 | if !(X isa typeinfo) 140 | typeinfo = Any 141 | end 142 | 143 | # what the context already knows about the eltype of X: 144 | eltype_ctx = Base.typeinfo_eltype(typeinfo) 145 | eltype_X = eltype(X) 146 | 147 | if X isa AbstractDict 148 | if eltype_X == eltype_ctx 149 | sprint(Base.show_type_name, typeof(X).name), false 150 | elseif !isempty(X) && typeinfo_implicit(keytype(X)) && typeinfo_implicit(valtype(X)) 151 | sprint(Base.show_type_name, typeof(X).name), true 152 | else 153 | string(typeof(X)), false 154 | end 155 | else 156 | # Types hard-coded here are those which are created by default for a given syntax 157 | if eltype_X == eltype_ctx 158 | "", false 159 | elseif !isempty(X) && typeinfo_implicit(eltype_X) 160 | "", true 161 | elseif Base.print_without_params(eltype_X) 162 | sprint(Base.show_type_name, Base.unwrap_unionall(eltype_X).name), false # Print "Array" rather than "Array{T,N}" 163 | else 164 | string(eltype_X), false 165 | end 166 | end 167 | end 168 | 169 | # NOTE: copied from base/arrayshow.jl:typeinfo_implicit(@nospecialize(T)) for compatiblity 170 | # types that can be parsed back accurately from their un-decorated representations 171 | function typeinfo_implicit(@nospecialize(T)) 172 | if T === Float64 || T === Int || T === Char || T === String || T === Symbol || 173 | Base.issingletontype(T) 174 | return true 175 | end 176 | return isconcretetype(T) && 177 | ((T <: Array && typeinfo_implicit(eltype(T))) || 178 | ((T <: Tuple || T <: Pair) && all(typeinfo_implicit, fieldtypes(T))) || 179 | (T <: AbstractDict && typeinfo_implicit(keytype(T)) && typeinfo_implicit(valtype(T)))) 180 | end -------------------------------------------------------------------------------- /src/io.jl: -------------------------------------------------------------------------------- 1 | """ 2 | @enum PrintType 3 | 4 | `PrintType` to tell lower level printing some useful context. 5 | Currently only supports `Unknown` and `StructField`. 6 | """ 7 | @enum PrintType begin 8 | Unknown 9 | StructField 10 | end 11 | 12 | mutable struct PrintState 13 | type::PrintType 14 | typeinfo 15 | noindent_in_first_line::Bool 16 | level::Int 17 | # the offset that should be applied 18 | # to whoever cares, e.g for the field 19 | # values 20 | offset::Int 21 | end 22 | 23 | PrintState() = PrintState(Unknown, Any, false, 0, 0) 24 | 25 | """ 26 | GarishIO{IO_t <: IO} <: IO 27 | 28 | `GarishIO` contains the pretty printing preference and states. 29 | 30 | # Members 31 | 32 | - `bland_io::IO_t`: the original io. 33 | - `indent::Int`: indentation size. 34 | - `compact::Bool`: whether the printing should be compact. 35 | - `displaysize::Tuple{Int, Int}`: the terminal displaysize. 36 | - `show_indent`: print the indentation hint or not. 37 | - `color`: color preference, either `ColorPreference` or `nothing` for no color. 38 | - `state`: the state of the printer, see [`PrintState`](@ref). 39 | """ 40 | struct GarishIO{IO_t <: IO} <: Base.AbstractPipe 41 | # the bland io we want look nice 42 | bland_io::IO_t 43 | indent::Int 44 | compact::Bool 45 | limit::Bool 46 | displaysize::Tuple{Int, Int} 47 | show_indent::Bool 48 | # option type 49 | include_defaults::Bool 50 | # use nothing for no color print 51 | color::Union{Nothing, ColorPreference} 52 | state::PrintState 53 | end 54 | 55 | """ 56 | GarishIO(io::IO; kw...) 57 | 58 | See [`pprint`](@ref) for available keywords. 59 | """ 60 | function GarishIO(io::IO; 61 | indent::Int=2, 62 | compact::Bool=get(io, :compact, false), 63 | limit::Bool=get(io, :limit, false), 64 | displaysize::Tuple{Int, Int}=displaysize(io), 65 | color::Bool=get(io, :color, true), 66 | # indent is similar to color 67 | show_indent::Bool=get(io, :color, true), 68 | include_defaults::Bool=get(io, :include_defaults, false), 69 | kw... 70 | ) 71 | 72 | if color 73 | color_prefs = ColorPreference(;kw...) 74 | else 75 | color_prefs = nothing 76 | end 77 | return GarishIO( 78 | io, indent, 79 | compact, limit, 80 | displaysize, 81 | show_indent, 82 | include_defaults, 83 | color_prefs, 84 | PrintState() 85 | ) 86 | end 87 | 88 | function GarishIO(io::GarishIO; 89 | indent::Int=io.indent, 90 | compact::Bool=io.compact, 91 | limit::Bool=io.limit, 92 | displaysize::Tuple{Int, Int}=io.displaysize, 93 | show_indent::Bool=io.show_indent, 94 | include_defaults::Bool=get(io, :include_defaults, false), 95 | color=io.color, 96 | state=io.state, 97 | kw...) 98 | 99 | if isempty(kw) 100 | color_prefs = color 101 | else 102 | color_prefs = ColorPreference(;kw...) 103 | end 104 | 105 | return GarishIO( 106 | io, indent, compact, limit, 107 | displaysize, show_indent, 108 | include_defaults, 109 | color_prefs, 110 | state 111 | ) 112 | end 113 | 114 | """ 115 | GarishIO(io::IO, garish_io::GarishIO; kw...) 116 | 117 | Create a new similar `GarishIO` with new bland IO object `io` 118 | based on an existing garish io preference. The preference can 119 | be overloaded by `kw`. See [`pprint`](@ref) for the available 120 | keyword arguments. 121 | """ 122 | function GarishIO(io::IO, garish_io::GarishIO; 123 | indent::Int=garish_io.indent, 124 | compact::Bool=garish_io.compact, 125 | limit::Bool=garish_io.limit, 126 | displaysize::Tuple{Int, Int}=garish_io.displaysize, 127 | show_indent::Bool=garish_io.show_indent, 128 | include_defaults::Bool=get(io, :include_defaults, false), 129 | color_prefs=garish_io.color, 130 | state=garish_io.state 131 | ) 132 | 133 | if haskey(io, :color) && io[:color] == false 134 | color = nothing 135 | else 136 | color = garish_io.color 137 | end 138 | 139 | return GarishIO( 140 | io, indent, 141 | compact, limit, 142 | displaysize, 143 | show_indent, 144 | include_defaults, 145 | color_prefs, 146 | state, 147 | ) 148 | end 149 | 150 | Base.pipe_reader(io::GarishIO) = io.bland_io 151 | Base.pipe_writer(io::GarishIO) = io.bland_io 152 | Base.lock(io::GarishIO) = lock(io.bland_io) 153 | Base.unlock(io::GarishIO) = unlock(io.bland_io) 154 | 155 | function Base.IOContext(io::GarishIO, KVs::Pair...) 156 | IOContext( 157 | io.bland_io, 158 | :compact=>io.compact, 159 | :limit=>io.limit, 160 | :color=>!isnothing(io.color), 161 | :displaysize=>io.displaysize, 162 | :typeinfo=>io.state.typeinfo, 163 | 164 | :pprint_indent=>io.indent, 165 | :color_preference=>io.color, 166 | :show_indent=>io.show_indent, 167 | :include_defaults=>io.include_defaults, 168 | :pprint_type=>io.state.type, 169 | :pprint_level=>io.state.level, 170 | :pprint_offset=>io.state.offset, 171 | :noindent_in_first_line=>io.state.noindent_in_first_line, 172 | 173 | KVs... 174 | ) 175 | end 176 | 177 | Base.displaysize(io::GarishIO) = io.displaysize 178 | Base.in(key_value::Pair, io::GarishIO) = in(key_value, IOContext(io).dict, ===) 179 | Base.haskey(io::GarishIO, key) = haskey(IOContext(io).dict, key) 180 | Base.getindex(io::GarishIO, key) = getindex(IOContext(io).dict, key) 181 | Base.get(io::GarishIO, key, default) = get(IOContext(io).dict, key, default) 182 | Base.keys(io::GarishIO) = keys(IOContext(io).dict) 183 | 184 | """ 185 | within_nextlevel(f, io::GarishIO) 186 | 187 | Run `f()` within the next level of indentation where `f` is a function 188 | that print into `io`. 189 | """ 190 | function within_nextlevel(f, io::GarishIO) 191 | io.state.level += 1 192 | ret = f() 193 | io.state.level -= 1 194 | 195 | # upperlevel_type = io.state.type 196 | # upperlevel_noindent_in_first_line = io.state.noindent_in_first_line 197 | # io.state.type = StructField 198 | # io.state.noindent_in_first_line = true 199 | # pprint(io, s.second) 200 | # io.state.noindent_in_first_line = upperlevel_noindent_in_first_line 201 | # io.state.type = upperlevel_type 202 | return ret 203 | end 204 | 205 | """ 206 | print_token(io::GarishIO, type::Symbol, xs...) 207 | 208 | Print `xs` to a `GarishIO` as given token type. The token type 209 | should match the field name of `ColorPreference`. 210 | """ 211 | function print_token(io::GarishIO, type::Symbol, xs...) 212 | print_token(print, io, type, xs...) 213 | end 214 | 215 | """ 216 | print_token(f, io::GarishIO, type::Symbol, xs...) 217 | 218 | Print `xs` to a `GarishIO` as given token type using `f(io, xs...)` 219 | """ 220 | function print_token(f, io::GarishIO, type::Symbol, xs...) 221 | isnothing(io.color) && return f(io, xs...) 222 | Base.with_output_color(f, getfield(io.color, type), io, xs...) 223 | end 224 | 225 | function max_indent_reached(io::GarishIO, offset::Int) 226 | io.indent * io.state.level + io.state.offset + offset > io.displaysize[2] 227 | end 228 | -------------------------------------------------------------------------------- /docs/build/assets/search.js: -------------------------------------------------------------------------------- 1 | // Generated by Documenter.jl 2 | requirejs.config({ 3 | paths: { 4 | 'lunr': 'https://cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.9/lunr.min', 5 | 'lodash': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min', 6 | 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min', 7 | } 8 | }); 9 | //////////////////////////////////////////////////////////////////////////////// 10 | require(['jquery', 'lunr', 'lodash'], function($, lunr, _) { 11 | 12 | $(document).ready(function() { 13 | // parseUri 1.2.2 14 | // (c) Steven Levithan 15 | // MIT License 16 | function parseUri (str) { 17 | var o = parseUri.options, 18 | m = o.parser[o.strictMode ? "strict" : "loose"].exec(str), 19 | uri = {}, 20 | i = 14; 21 | 22 | while (i--) uri[o.key[i]] = m[i] || ""; 23 | 24 | uri[o.q.name] = {}; 25 | uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { 26 | if ($1) uri[o.q.name][$1] = $2; 27 | }); 28 | 29 | return uri; 30 | }; 31 | parseUri.options = { 32 | strictMode: false, 33 | key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], 34 | q: { 35 | name: "queryKey", 36 | parser: /(?:^|&)([^&=]*)=?([^&]*)/g 37 | }, 38 | parser: { 39 | strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, 40 | loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ 41 | } 42 | }; 43 | 44 | $("#search-form").submit(function(e) { 45 | e.preventDefault() 46 | }) 47 | 48 | // list below is the lunr 2.1.3 list minus the intersect with names(Base) 49 | // (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with) 50 | // ideally we'd just filter the original list but it's not available as a variable 51 | lunr.stopWordFilter = lunr.generateStopWordFilter([ 52 | 'a', 53 | 'able', 54 | 'about', 55 | 'across', 56 | 'after', 57 | 'almost', 58 | 'also', 59 | 'am', 60 | 'among', 61 | 'an', 62 | 'and', 63 | 'are', 64 | 'as', 65 | 'at', 66 | 'be', 67 | 'because', 68 | 'been', 69 | 'but', 70 | 'by', 71 | 'can', 72 | 'cannot', 73 | 'could', 74 | 'dear', 75 | 'did', 76 | 'does', 77 | 'either', 78 | 'ever', 79 | 'every', 80 | 'from', 81 | 'got', 82 | 'had', 83 | 'has', 84 | 'have', 85 | 'he', 86 | 'her', 87 | 'hers', 88 | 'him', 89 | 'his', 90 | 'how', 91 | 'however', 92 | 'i', 93 | 'if', 94 | 'into', 95 | 'it', 96 | 'its', 97 | 'just', 98 | 'least', 99 | 'like', 100 | 'likely', 101 | 'may', 102 | 'me', 103 | 'might', 104 | 'most', 105 | 'must', 106 | 'my', 107 | 'neither', 108 | 'no', 109 | 'nor', 110 | 'not', 111 | 'of', 112 | 'off', 113 | 'often', 114 | 'on', 115 | 'or', 116 | 'other', 117 | 'our', 118 | 'own', 119 | 'rather', 120 | 'said', 121 | 'say', 122 | 'says', 123 | 'she', 124 | 'should', 125 | 'since', 126 | 'so', 127 | 'some', 128 | 'than', 129 | 'that', 130 | 'the', 131 | 'their', 132 | 'them', 133 | 'then', 134 | 'there', 135 | 'these', 136 | 'they', 137 | 'this', 138 | 'tis', 139 | 'to', 140 | 'too', 141 | 'twas', 142 | 'us', 143 | 'wants', 144 | 'was', 145 | 'we', 146 | 'were', 147 | 'what', 148 | 'when', 149 | 'who', 150 | 'whom', 151 | 'why', 152 | 'will', 153 | 'would', 154 | 'yet', 155 | 'you', 156 | 'your' 157 | ]) 158 | 159 | // add . as a separator, because otherwise "title": "Documenter.Anchors.add!" 160 | // would not find anything if searching for "add!", only for the entire qualification 161 | lunr.tokenizer.separator = /[\s\-\.]+/ 162 | 163 | // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names 164 | lunr.trimmer = function (token) { 165 | return token.update(function (s) { 166 | return s.replace(/^[^a-zA-Z0-9@!]+/, '').replace(/[^a-zA-Z0-9@!]+$/, '') 167 | }) 168 | } 169 | 170 | lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'juliaStopWordFilter') 171 | lunr.Pipeline.registerFunction(lunr.trimmer, 'juliaTrimmer') 172 | 173 | var index = lunr(function () { 174 | this.ref('location') 175 | this.field('title',{boost: 100}) 176 | this.field('text') 177 | documenterSearchIndex['docs'].forEach(function(e) { 178 | this.add(e) 179 | }, this) 180 | }) 181 | var store = {} 182 | 183 | documenterSearchIndex['docs'].forEach(function(e) { 184 | store[e.location] = {title: e.title, category: e.category, page: e.page} 185 | }) 186 | 187 | $(function(){ 188 | searchresults = $('#documenter-search-results'); 189 | searchinfo = $('#documenter-search-info'); 190 | searchbox = $('#documenter-search-query'); 191 | function update_search(querystring) { 192 | tokens = lunr.tokenizer(querystring) 193 | results = index.query(function (q) { 194 | tokens.forEach(function (t) { 195 | q.term(t.toString(), { 196 | fields: ["title"], 197 | boost: 100, 198 | usePipeline: true, 199 | editDistance: 0, 200 | wildcard: lunr.Query.wildcard.NONE 201 | }) 202 | q.term(t.toString(), { 203 | fields: ["title"], 204 | boost: 10, 205 | usePipeline: true, 206 | editDistance: 2, 207 | wildcard: lunr.Query.wildcard.NONE 208 | }) 209 | q.term(t.toString(), { 210 | fields: ["text"], 211 | boost: 1, 212 | usePipeline: true, 213 | editDistance: 0, 214 | wildcard: lunr.Query.wildcard.NONE 215 | }) 216 | }) 217 | }) 218 | searchinfo.text("Number of results: " + results.length) 219 | searchresults.empty() 220 | results.forEach(function(result) { 221 | data = store[result.ref] 222 | link = $(''+data.title+'') 223 | link.attr('href', documenterBaseURL+'/'+result.ref) 224 | if (data.category != "page"){ 225 | cat = $('('+data.category+', '+data.page+')') 226 | } else { 227 | cat = $('('+data.category+')') 228 | } 229 | li = $('
  • ').append(link).append(" ").append(cat) 230 | searchresults.append(li) 231 | }) 232 | } 233 | 234 | function update_search_box() { 235 | querystring = searchbox.val() 236 | update_search(querystring) 237 | } 238 | 239 | searchbox.keyup(_.debounce(update_search_box, 250)) 240 | searchbox.change(update_search_box) 241 | 242 | search_query_uri = parseUri(window.location).queryKey["q"] 243 | if(search_query_uri !== undefined) { 244 | search_query = decodeURIComponent(search_query_uri.replace(/\+/g, '%20')) 245 | searchbox.val(search_query) 246 | } 247 | update_search_box(); 248 | }) 249 | }) 250 | 251 | }) 252 | -------------------------------------------------------------------------------- /docs/build/assets/documenter.js: -------------------------------------------------------------------------------- 1 | // Generated by Documenter.jl 2 | requirejs.config({ 3 | paths: { 4 | 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.0.1/languages/julia.min', 5 | 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/headroom.min', 6 | 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min', 7 | 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.13.11/contrib/auto-render.min', 8 | 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min', 9 | 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/jQuery.headroom.min', 10 | 'katex': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.13.11/katex.min', 11 | 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.0.1/highlight.min', 12 | 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.0.1/languages/julia-repl.min', 13 | }, 14 | shim: { 15 | "highlight-julia": { 16 | "deps": [ 17 | "highlight" 18 | ] 19 | }, 20 | "katex-auto-render": { 21 | "deps": [ 22 | "katex" 23 | ] 24 | }, 25 | "headroom-jquery": { 26 | "deps": [ 27 | "jquery", 28 | "headroom" 29 | ] 30 | }, 31 | "highlight-julia-repl": { 32 | "deps": [ 33 | "highlight" 34 | ] 35 | } 36 | } 37 | }); 38 | //////////////////////////////////////////////////////////////////////////////// 39 | require(['jquery', 'katex', 'katex-auto-render'], function($, katex, renderMathInElement) { 40 | $(document).ready(function() { 41 | renderMathInElement( 42 | document.body, 43 | { 44 | "delimiters": [ 45 | { 46 | "left": "$", 47 | "right": "$", 48 | "display": false 49 | }, 50 | { 51 | "left": "$$", 52 | "right": "$$", 53 | "display": true 54 | }, 55 | { 56 | "left": "\\[", 57 | "right": "\\]", 58 | "display": true 59 | } 60 | ] 61 | } 62 | 63 | ); 64 | }) 65 | 66 | }) 67 | //////////////////////////////////////////////////////////////////////////////// 68 | require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($) { 69 | $(document).ready(function() { 70 | hljs.highlightAll(); 71 | }) 72 | 73 | }) 74 | //////////////////////////////////////////////////////////////////////////////// 75 | require(['jquery', 'headroom', 'headroom-jquery'], function($, Headroom) { 76 | 77 | // Manages the top navigation bar (hides it when the user starts scrolling down on the 78 | // mobile). 79 | window.Headroom = Headroom; // work around buggy module loading? 80 | $(document).ready(function() { 81 | $('#documenter .docs-navbar').headroom({ 82 | "tolerance": {"up": 10, "down": 10}, 83 | }); 84 | }) 85 | 86 | }) 87 | //////////////////////////////////////////////////////////////////////////////// 88 | require(['jquery'], function($) { 89 | 90 | // Modal settings dialog 91 | $(document).ready(function() { 92 | var settings = $('#documenter-settings'); 93 | $('#documenter-settings-button').click(function(){ 94 | settings.toggleClass('is-active'); 95 | }); 96 | // Close the dialog if X is clicked 97 | $('#documenter-settings button.delete').click(function(){ 98 | settings.removeClass('is-active'); 99 | }); 100 | // Close dialog if ESC is pressed 101 | $(document).keyup(function(e) { 102 | if (e.keyCode == 27) settings.removeClass('is-active'); 103 | }); 104 | }); 105 | 106 | }) 107 | //////////////////////////////////////////////////////////////////////////////// 108 | require(['jquery'], function($) { 109 | 110 | // Manages the showing and hiding of the sidebar. 111 | $(document).ready(function() { 112 | var sidebar = $("#documenter > .docs-sidebar"); 113 | var sidebar_button = $("#documenter-sidebar-button") 114 | sidebar_button.click(function(ev) { 115 | ev.preventDefault(); 116 | sidebar.toggleClass('visible'); 117 | if (sidebar.hasClass('visible')) { 118 | // Makes sure that the current menu item is visible in the sidebar. 119 | $("#documenter .docs-menu a.is-active").focus(); 120 | } 121 | }); 122 | $("#documenter > .docs-main").bind('click', function(ev) { 123 | if ($(ev.target).is(sidebar_button)) { 124 | return; 125 | } 126 | if (sidebar.hasClass('visible')) { 127 | sidebar.removeClass('visible'); 128 | } 129 | }); 130 | }) 131 | 132 | // Resizes the package name / sitename in the sidebar if it is too wide. 133 | // Inspired by: https://github.com/davatron5000/FitText.js 134 | $(document).ready(function() { 135 | e = $("#documenter .docs-autofit"); 136 | function resize() { 137 | var L = parseInt(e.css('max-width'), 10); 138 | var L0 = e.width(); 139 | if(L0 > L) { 140 | var h0 = parseInt(e.css('font-size'), 10); 141 | e.css('font-size', L * h0 / L0); 142 | // TODO: make sure it survives resizes? 143 | } 144 | } 145 | // call once and then register events 146 | resize(); 147 | $(window).resize(resize); 148 | $(window).on('orientationchange', resize); 149 | }); 150 | 151 | // Scroll the navigation bar to the currently selected menu item 152 | $(document).ready(function() { 153 | var sidebar = $("#documenter .docs-menu").get(0); 154 | var active = $("#documenter .docs-menu .is-active").get(0); 155 | if(typeof active !== 'undefined') { 156 | sidebar.scrollTop = active.offsetTop - sidebar.offsetTop - 15; 157 | } 158 | }) 159 | 160 | }) 161 | //////////////////////////////////////////////////////////////////////////////// 162 | require(['jquery'], function($) { 163 | 164 | function set_theme(theme) { 165 | var active = null; 166 | var disabled = []; 167 | for (var i = 0; i < document.styleSheets.length; i++) { 168 | var ss = document.styleSheets[i]; 169 | var themename = ss.ownerNode.getAttribute("data-theme-name"); 170 | if(themename === null) continue; // ignore non-theme stylesheets 171 | // Find the active theme 172 | if(themename === theme) active = ss; 173 | else disabled.push(ss); 174 | } 175 | if(active !== null) { 176 | active.disabled = false; 177 | if(active.ownerNode.getAttribute("data-theme-primary") === null) { 178 | document.getElementsByTagName('html')[0].className = "theme--" + theme; 179 | } else { 180 | document.getElementsByTagName('html')[0].className = ""; 181 | } 182 | disabled.forEach(function(ss){ 183 | ss.disabled = true; 184 | }); 185 | } 186 | 187 | // Store the theme in localStorage 188 | if(typeof(window.localStorage) !== "undefined") { 189 | window.localStorage.setItem("documenter-theme", theme); 190 | } else { 191 | console.error("Browser does not support window.localStorage"); 192 | } 193 | } 194 | 195 | // Theme picker setup 196 | $(document).ready(function() { 197 | // onchange callback 198 | $('#documenter-themepicker').change(function themepick_callback(ev){ 199 | var themename = $('#documenter-themepicker option:selected').attr('value'); 200 | set_theme(themename); 201 | }); 202 | 203 | // Make sure that the themepicker displays the correct theme when the theme is retrieved 204 | // from localStorage 205 | if(typeof(window.localStorage) !== "undefined") { 206 | var theme = window.localStorage.getItem("documenter-theme"); 207 | if(theme !== null) { 208 | $('#documenter-themepicker option').each(function(i,e) { 209 | e.selected = (e.value === theme); 210 | }) 211 | } else { 212 | $('#documenter-themepicker option').each(function(i,e) { 213 | e.selected = $("html").hasClass(`theme--${e.value}`); 214 | }) 215 | } 216 | } 217 | }) 218 | 219 | }) 220 | //////////////////////////////////////////////////////////////////////////////// 221 | require(['jquery'], function($) { 222 | 223 | // update the version selector with info from the siteinfo.js and ../versions.js files 224 | $(document).ready(function() { 225 | var version_selector = $("#documenter .docs-version-selector"); 226 | var version_selector_select = $("#documenter .docs-version-selector select"); 227 | 228 | version_selector_select.change(function(x) { 229 | target_href = version_selector_select.children("option:selected").get(0).value; 230 | window.location.href = target_href; 231 | }); 232 | 233 | // add the current version to the selector based on siteinfo.js, but only if the selector is empty 234 | if (typeof DOCUMENTER_CURRENT_VERSION !== 'undefined' && $('#version-selector > option').length == 0) { 235 | var option = $(""); 236 | version_selector_select.append(option); 237 | } 238 | 239 | if (typeof DOC_VERSIONS !== 'undefined') { 240 | var existing_versions = version_selector_select.children("option"); 241 | var existing_versions_texts = existing_versions.map(function(i,x){return x.text}); 242 | DOC_VERSIONS.forEach(function(each) { 243 | var version_url = documenterBaseURL + "/../" + each; 244 | var existing_id = $.inArray(each, existing_versions_texts); 245 | // if not already in the version selector, add it as a new option, 246 | // otherwise update the old option with the URL and enable it 247 | if (existing_id == -1) { 248 | var option = $(""); 249 | version_selector_select.append(option); 250 | } else { 251 | var option = existing_versions[existing_id]; 252 | option.value = version_url; 253 | option.disabled = false; 254 | } 255 | }); 256 | } 257 | 258 | // only show the version selector if the selector has been populated 259 | if (version_selector_select.children("option").length > 0) { 260 | version_selector.toggleClass("visible"); 261 | } 262 | }) 263 | 264 | }) 265 | -------------------------------------------------------------------------------- /docs/build/index.html: -------------------------------------------------------------------------------- 1 | 2 | Home · GarishPrint.jl

    GarishPrint

    CI codecov

    An opinioned pretty printing package for Julia objects.

    Installation

    3 | GarishPrint is a   4 | 5 | 6 | Julia Language 7 | 8 |   package. To install GarishPrint, 9 | please open 10 | Julia's interactive session (known as REPL) and press ] key in the REPL to use the package mode, then type the following command 11 |

    pkg> add GarishPrint

    Usage

    there is only one function exported that is pprint,

    GarishPrint.pprintFunction
    pprint([io::IO=stdout, ]xs...; kw...)

    Pretty print given objects xs to io, default io is stdout.

    Keyword Arguments

    • indent::Int: indent size, default is 2.
    • compact::Bool: whether print withint one line, default is get(io, :compact, false).
    • width::Int: the width hint of printed string, note this is not stricted obeyed,

    default is displaysize(io)[2].

    • show_indent::Bool: whether print indentation hint, default is true.
    • color::Bool: whether print with color, default is true.

    Color Preference

    color preference is available as keyword arguments to override the default color scheme. These arguments may take any of the values :normal, :default, :bold, :black, :blink, :blue, :cyan, :green, :hidden, :light_black, :light_blue, :light_cyan, :light_green, :light_magenta, :light_red, :light_yellow, :magenta, :nothing, :red, :reverse, :underline, :white, or :yellow or an integer between 0 and 255 inclusive. Note that not all terminals support 256 colors.

    The default color scheme can be checked via GarishPrint.default_colors_256() for 256 color, and GarishPrint.default_colors_ansi() for ANSI color. The 256 color will be used when the terminal is detected to support 256 color.

    • fieldname: field name of a struct.
    • type: the color of a type.
    • operator: the color of an operator, e.g +, =>.
    • literal: the color of literals.
    • constant: the color of constants, e.g π.
    • number: the color of numbers, e.g 1.2, 1.
    • string: the color of string.
    • comment: comments, e.g # some comments
    • undef: the const binding to UndefInitializer
    • linenumber: line numbers.

    Notes

    The color print and compact print can also be turned on/off by setting IOContext, e.g IOContext(io, :color=>false) will print without color, and IOContext(io, :compact=>true) will print within one line. This is also what the standard Julia IO objects follows in printing by default.

    source
    pprint(io::IO, mime::MIME, x; kw...)

    Pretty print an object x with given MIME type.

    Warning

    currently only supports MIME"text/plain", the implementation of MIME"text/html" is coming soon. Please also feel free to file an issue if you have a desired format wants to support.

    source

    here is a quick example

    using GarishPrint
    12 | 
    13 | struct ABC{T1, T2, T3}
    14 |     hee::T1
    15 |     haa::T2
    16 |     hoo::T3
    17 | end
    18 | 
    19 | struct Example{T1, T2}
    20 |     field_a::T1
    21 |     field_b::T2
    22 |     abc::ABC
    23 | end
    24 | 
    25 | x = Example(
    26 |     Dict(
    27 |         "a"=>Example(
    28 |             [1, 2, 3],
    29 |             2.0,
    30 |             ABC(1, 2.0im, 3.12f0),
    31 |         ),
    32 |         "str" => Set([1, 2, 3]),
    33 |     ),
    34 |     undef,
    35 |     ABC(nothing, 1.2+2.1im, π),
    36 | )
    37 | 
    38 | pprint(x)

    it will print the following

    readme-example

    License

    MIT License

    39 | -------------------------------------------------------------------------------- /docs/build/search_index.js: -------------------------------------------------------------------------------- 1 | var documenterSearchIndex = {"docs": 2 | [{"location":"ref/","page":"References","title":"References","text":"CurrentModule = GarishPrint","category":"page"},{"location":"ref/#Reference","page":"References","title":"Reference","text":"","category":"section"},{"location":"ref/","page":"References","title":"References","text":"Modules = [GarishPrint]","category":"page"},{"location":"ref/#GarishPrint.ColorPreference","page":"References","title":"GarishPrint.ColorPreference","text":"ColorPreference\n\nThe color preference type.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GarishPrint.ColorPreference-Tuple{}","page":"References","title":"GarishPrint.ColorPreference","text":"ColorPreference(;kw...)\n\nSee pprint for available keyword configurations.\n\n\n\n\n\n","category":"method"},{"location":"ref/#GarishPrint.GarishIO","page":"References","title":"GarishPrint.GarishIO","text":"GarishIO{IO_t <: IO} <: IO\n\nGarishIO contains the pretty printing preference and states.\n\nMembers\n\nbland_io::IO_t: the original io.\nindent::Int: indentation size.\ncompact::Bool: whether the printing should be compact.\nwidth::Int: the terminal width.\nshow_indent: print the indentation hint or not.\ncolor: color preference, either ColorPreference or nothing for no color.\nstate: the state of the printer, see PrintState.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GarishPrint.GarishIO-Tuple{IO, GarishPrint.GarishIO}","page":"References","title":"GarishPrint.GarishIO","text":"GarishIO(io::IO, garish_io::GarishIO; kw...)\n\nCreate a new similar GarishIO with new bland IO object io based on an existing garish io preference. The preference can be overloaded by kw. See pprint for the available keyword arguments.\n\n\n\n\n\n","category":"method"},{"location":"ref/#GarishPrint.GarishIO-Tuple{IO}","page":"References","title":"GarishPrint.GarishIO","text":"GarishIO(io::IO; kw...)\n\nSee pprint for available keywords.\n\n\n\n\n\n","category":"method"},{"location":"ref/#GarishPrint.PrintType","page":"References","title":"GarishPrint.PrintType","text":"@enum PrintType\n\nPrintType to tell lower level printing some useful context. Currently only supports Unknown and StructField.\n\n\n\n\n\n","category":"type"},{"location":"ref/#GarishPrint.default_colors_256-Tuple{}","page":"References","title":"GarishPrint.default_colors_256","text":"default_colors_256()\n\nThe default color 256 theme.\n\n\n\n\n\n","category":"method"},{"location":"ref/#GarishPrint.default_colors_ansi-Tuple{}","page":"References","title":"GarishPrint.default_colors_ansi","text":"default_colors_ansi()\n\nThe default ANSI color theme.\n\n\n\n\n\n","category":"method"},{"location":"ref/#GarishPrint.pprint-Tuple{IO, MIME, Any}","page":"References","title":"GarishPrint.pprint","text":"pprint(io::IO, mime::MIME, x; kw...)\n\nPretty print an object x with given MIME type.\n\nwarning: Warning\ncurrently only supports MIME\"text/plain\", the implementation of MIME\"text/html\" is coming soon. Please also feel free to file an issue if you have a desired format wants to support.\n\n\n\n\n\n","category":"method"},{"location":"ref/#GarishPrint.pprint-Tuple{IO, Vararg{Any, N} where N}","page":"References","title":"GarishPrint.pprint","text":"pprint([io::IO=stdout, ]xs...; kw...)\n\nPretty print given objects xs to io, default io is stdout.\n\nKeyword Arguments\n\nindent::Int: indent size, default is 2.\ncompact::Bool: whether print withint one line, default is get(io, :compact, false).\nwidth::Int: the width hint of printed string, note this is not stricted obeyed,\n\ndefault is displaysize(io)[2].\n\nshow_indent::Bool: whether print indentation hint, default is true.\ncolor::Bool: whether print with color, default is true.\n\nColor Preference\n\ncolor preference is available as keyword arguments to override the default color scheme. These arguments may take any of the values :normal, :default, :bold, :black, :blink, :blue, :cyan, :green, :hidden, :light_black, :light_blue, :light_cyan, :light_green, :light_magenta, :light_red, :light_yellow, :magenta, :nothing, :red, :reverse, :underline, :white, or :yellow or an integer between 0 and 255 inclusive. Note that not all terminals support 256 colors.\n\nThe default color scheme can be checked via GarishPrint.default_colors_256() for 256 color, and GarishPrint.default_colors_ansi() for ANSI color. The 256 color will be used when the terminal is detected to support 256 color.\n\nfieldname: field name of a struct.\ntype: the color of a type.\noperator: the color of an operator, e.g +, =>.\nliteral: the color of literals.\nconstant: the color of constants, e.g π.\nnumber: the color of numbers, e.g 1.2, 1.\nstring: the color of string.\ncomment: comments, e.g # some comments\nundef: the const binding to UndefInitializer\nlinenumber: line numbers.\n\nNotes\n\nThe color print and compact print can also be turned on/off by setting IOContext, e.g IOContext(io, :color=>false) will print without color, and IOContext(io, :compact=>true) will print within one line. This is also what the standard Julia IO objects follows in printing by default.\n\n\n\n\n\n","category":"method"},{"location":"ref/#GarishPrint.pprint_list_like","page":"References","title":"GarishPrint.pprint_list_like","text":"pprint_list_like(io::GarishIO, list, opn='[', cls=']'; compact::Bool=io.compact)\n\nPrint a list-like object list. A list-like object should support the iterable interface such as Base.iterate and Base.length. This is modified based on base/arrayshow.jl:show_vector.\n\nArguments\n\nio::GarishIO: the GarishIO object one wants to print to.\nlist: the list-like object.\nopn: the openning marker, default is [.\ncls: the closing marker, default is ].\n\nKeyword Arguments\n\ncompact::Bool: print the list within one line or not.\n\n\n\n\n\n","category":"function"},{"location":"ref/#GarishPrint.pprint_struct-Tuple{GarishPrint.GarishIO, MIME{Symbol(\"text/plain\")}, Any}","page":"References","title":"GarishPrint.pprint_struct","text":"pprint_struct(io::GarishIO, ::MIME, x)\n\nPrint x as a struct type.\n\n\n\n\n\n","category":"method"},{"location":"ref/#GarishPrint.print_indent-Tuple{GarishPrint.GarishIO}","page":"References","title":"GarishPrint.print_indent","text":"print_indent(io::GarishIO)\n\nPrint an indentation. This should be only used under MIME\"text/plain\" or equivalent.\n\n\n\n\n\n","category":"method"},{"location":"ref/#GarishPrint.print_operator-Tuple{GarishPrint.GarishIO, Any}","page":"References","title":"GarishPrint.print_operator","text":"print_operator(io::GarishIO, op)\n\nPrint an operator, such as =, +, => etc. This should be only used under MIME\"text/plain\" or equivalent.\n\n\n\n\n\n","category":"method"},{"location":"ref/#GarishPrint.print_token-Tuple{Any, GarishPrint.GarishIO, Symbol, Vararg{Any, N} where N}","page":"References","title":"GarishPrint.print_token","text":"print_token(f, io::GarishIO, type::Symbol, xs...)\n\nPrint xs to a GarishIO as given token type using f(io, xs...)\n\n\n\n\n\n","category":"method"},{"location":"ref/#GarishPrint.print_token-Tuple{GarishPrint.GarishIO, Symbol, Vararg{Any, N} where N}","page":"References","title":"GarishPrint.print_token","text":"print_token(io::GarishIO, type::Symbol, xs...)\n\nPrint xs to a GarishIO as given token type. The token type should match the field name of ColorPreference.\n\n\n\n\n\n","category":"method"},{"location":"ref/#GarishPrint.supports_color256-Tuple{}","page":"References","title":"GarishPrint.supports_color256","text":"supports_color256()\n\nCheck if the terminal supports color 256.\n\n\n\n\n\n","category":"method"},{"location":"ref/#GarishPrint.tty_has_color-Tuple{}","page":"References","title":"GarishPrint.tty_has_color","text":"tty_has_color()\n\nCheck if TTY supports color. This is mainly for lower Julia version like 1.0.\n\n\n\n\n\n","category":"method"},{"location":"ref/#GarishPrint.within_nextlevel-Tuple{Any, GarishPrint.GarishIO}","page":"References","title":"GarishPrint.within_nextlevel","text":"within_nextlevel(f, io::GarishIO)\n\nRun f() within the next level of indentation where f is a function that print into io.\n\n\n\n\n\n","category":"method"},{"location":"#GarishPrint","page":"Home","title":"GarishPrint","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"(Image: CI) (Image: codecov)","category":"page"},{"location":"","page":"Home","title":"Home","text":"An opinioned pretty printing package for Julia objects.","category":"page"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"

    \nGarishPrint is a  \n \n \n Julia Language\n \n   package. To install GarishPrint,\n please open\n Julia's interactive session (known as REPL) and press ] key in the REPL to use the package mode, then type the following command\n

    ","category":"page"},{"location":"","page":"Home","title":"Home","text":"pkg> add GarishPrint","category":"page"},{"location":"#Usage","page":"Home","title":"Usage","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"there is only one function exported that is pprint,","category":"page"},{"location":"","page":"Home","title":"Home","text":"pprint","category":"page"},{"location":"#GarishPrint.pprint","page":"Home","title":"GarishPrint.pprint","text":"pprint([io::IO=stdout, ]xs...; kw...)\n\nPretty print given objects xs to io, default io is stdout.\n\nKeyword Arguments\n\nindent::Int: indent size, default is 2.\ncompact::Bool: whether print withint one line, default is get(io, :compact, false).\nwidth::Int: the width hint of printed string, note this is not stricted obeyed,\n\ndefault is displaysize(io)[2].\n\nshow_indent::Bool: whether print indentation hint, default is true.\ncolor::Bool: whether print with color, default is true.\n\nColor Preference\n\ncolor preference is available as keyword arguments to override the default color scheme. These arguments may take any of the values :normal, :default, :bold, :black, :blink, :blue, :cyan, :green, :hidden, :light_black, :light_blue, :light_cyan, :light_green, :light_magenta, :light_red, :light_yellow, :magenta, :nothing, :red, :reverse, :underline, :white, or :yellow or an integer between 0 and 255 inclusive. Note that not all terminals support 256 colors.\n\nThe default color scheme can be checked via GarishPrint.default_colors_256() for 256 color, and GarishPrint.default_colors_ansi() for ANSI color. The 256 color will be used when the terminal is detected to support 256 color.\n\nfieldname: field name of a struct.\ntype: the color of a type.\noperator: the color of an operator, e.g +, =>.\nliteral: the color of literals.\nconstant: the color of constants, e.g π.\nnumber: the color of numbers, e.g 1.2, 1.\nstring: the color of string.\ncomment: comments, e.g # some comments\nundef: the const binding to UndefInitializer\nlinenumber: line numbers.\n\nNotes\n\nThe color print and compact print can also be turned on/off by setting IOContext, e.g IOContext(io, :color=>false) will print without color, and IOContext(io, :compact=>true) will print within one line. This is also what the standard Julia IO objects follows in printing by default.\n\n\n\n\n\npprint(io::IO, mime::MIME, x; kw...)\n\nPretty print an object x with given MIME type.\n\nwarning: Warning\ncurrently only supports MIME\"text/plain\", the implementation of MIME\"text/html\" is coming soon. Please also feel free to file an issue if you have a desired format wants to support.\n\n\n\n\n\n","category":"function"},{"location":"","page":"Home","title":"Home","text":"here is a quick example","category":"page"},{"location":"","page":"Home","title":"Home","text":"using GarishPrint\n\nstruct ABC{T1, T2, T3}\n hee::T1\n haa::T2\n hoo::T3\nend\n\nstruct Example{T1, T2}\n field_a::T1\n field_b::T2\n abc::ABC\nend\n\nx = Example(\n Dict(\n \"a\"=>Example(\n [1, 2, 3],\n 2.0,\n ABC(1, 2.0im, 3.12f0),\n ),\n \"str\" => Set([1, 2, 3]),\n ),\n undef,\n ABC(nothing, 1.2+2.1im, π),\n)\n\npprint(x)","category":"page"},{"location":"","page":"Home","title":"Home","text":"it will print the following","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: readme-example)","category":"page"},{"location":"#License","page":"Home","title":"License","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"MIT License","category":"page"}] 3 | } 4 | -------------------------------------------------------------------------------- /docs/build/ref/index.html: -------------------------------------------------------------------------------- 1 | 2 | References · GarishPrint.jl

    Reference

    GarishPrint.GarishIOType
    GarishIO{IO_t <: IO} <: IO

    GarishIO contains the pretty printing preference and states.

    Members

    • bland_io::IO_t: the original io.
    • indent::Int: indentation size.
    • compact::Bool: whether the printing should be compact.
    • width::Int: the terminal width.
    • show_indent: print the indentation hint or not.
    • color: color preference, either ColorPreference or nothing for no color.
    • state: the state of the printer, see PrintState.
    source
    GarishPrint.GarishIOMethod
    GarishIO(io::IO, garish_io::GarishIO; kw...)

    Create a new similar GarishIO with new bland IO object io based on an existing garish io preference. The preference can be overloaded by kw. See pprint for the available keyword arguments.

    source
    GarishPrint.PrintTypeType
    @enum PrintType

    PrintType to tell lower level printing some useful context. Currently only supports Unknown and StructField.

    source
    GarishPrint.pprintMethod
    pprint(io::IO, mime::MIME, x; kw...)

    Pretty print an object x with given MIME type.

    Warning

    currently only supports MIME"text/plain", the implementation of MIME"text/html" is coming soon. Please also feel free to file an issue if you have a desired format wants to support.

    source
    GarishPrint.pprintMethod
    pprint([io::IO=stdout, ]xs...; kw...)

    Pretty print given objects xs to io, default io is stdout.

    Keyword Arguments

    • indent::Int: indent size, default is 2.
    • compact::Bool: whether print withint one line, default is get(io, :compact, false).
    • width::Int: the width hint of printed string, note this is not stricted obeyed,

    default is displaysize(io)[2].

    • show_indent::Bool: whether print indentation hint, default is true.
    • color::Bool: whether print with color, default is true.

    Color Preference

    color preference is available as keyword arguments to override the default color scheme. These arguments may take any of the values :normal, :default, :bold, :black, :blink, :blue, :cyan, :green, :hidden, :light_black, :light_blue, :light_cyan, :light_green, :light_magenta, :light_red, :light_yellow, :magenta, :nothing, :red, :reverse, :underline, :white, or :yellow or an integer between 0 and 255 inclusive. Note that not all terminals support 256 colors.

    The default color scheme can be checked via GarishPrint.default_colors_256() for 256 color, and GarishPrint.default_colors_ansi() for ANSI color. The 256 color will be used when the terminal is detected to support 256 color.

    • fieldname: field name of a struct.
    • type: the color of a type.
    • operator: the color of an operator, e.g +, =>.
    • literal: the color of literals.
    • constant: the color of constants, e.g π.
    • number: the color of numbers, e.g 1.2, 1.
    • string: the color of string.
    • comment: comments, e.g # some comments
    • undef: the const binding to UndefInitializer
    • linenumber: line numbers.

    Notes

    The color print and compact print can also be turned on/off by setting IOContext, e.g IOContext(io, :color=>false) will print without color, and IOContext(io, :compact=>true) will print within one line. This is also what the standard Julia IO objects follows in printing by default.

    source
    GarishPrint.pprint_list_likeFunction
    pprint_list_like(io::GarishIO, list, opn='[', cls=']'; compact::Bool=io.compact)

    Print a list-like object list. A list-like object should support the iterable interface such as Base.iterate and Base.length. This is modified based on base/arrayshow.jl:show_vector.

    Arguments

    • io::GarishIO: the GarishIO object one wants to print to.
    • list: the list-like object.
    • opn: the openning marker, default is [.
    • cls: the closing marker, default is ].

    Keyword Arguments

    • compact::Bool: print the list within one line or not.
    source
    GarishPrint.print_indentMethod
    print_indent(io::GarishIO)

    Print an indentation. This should be only used under MIME"text/plain" or equivalent.

    source
    GarishPrint.print_operatorMethod
    print_operator(io::GarishIO, op)

    Print an operator, such as =, +, => etc. This should be only used under MIME"text/plain" or equivalent.

    source
    GarishPrint.print_tokenMethod
    print_token(f, io::GarishIO, type::Symbol, xs...)

    Print xs to a GarishIO as given token type using f(io, xs...)

    source
    GarishPrint.print_tokenMethod
    print_token(io::GarishIO, type::Symbol, xs...)

    Print xs to a GarishIO as given token type. The token type should match the field name of ColorPreference.

    source
    3 | --------------------------------------------------------------------------------