diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml index dd821e6..0918161 100644 --- a/.github/workflows/CompatHelper.yml +++ b/.github/workflows/CompatHelper.yml @@ -1,19 +1,45 @@ name: CompatHelper - on: schedule: - - cron: '00 00 * * *' - + - cron: 0 0 * * * + workflow_dispatch: +permissions: + contents: write + pull-requests: write jobs: CompatHelper: runs-on: ubuntu-latest steps: - - uses: julia-actions/setup-julia@latest + - name: Check if Julia is already available in the PATH + id: julia_in_path + run: which julia + continue-on-error: true + - name: Install Julia, but only if it is not already available in the PATH + uses: julia-actions/setup-julia@v1 with: - version: 1.3 - - name: Pkg.add("CompatHelper") - run: julia -e 'using Pkg; Pkg.add("CompatHelper")' - - name: CompatHelper.main() + version: '1' + arch: ${{ runner.arch }} + if: steps.julia_in_path.outcome != 'success' + - name: "Add the General registry via Git" + run: | + import Pkg + ENV["JULIA_PKG_SERVER"] = "" + Pkg.Registry.add("General") + shell: julia --color=yes {0} + - name: "Install CompatHelper" + run: | + import Pkg + name = "CompatHelper" + uuid = "aa819f21-2bde-4658-8897-bab36330d9b7" + version = "3" + Pkg.add(; name, uuid, version) + shell: julia --color=yes {0} + - name: "Run CompatHelper" + run: | + import CompatHelper + CompatHelper.main() + shell: julia --color=yes {0} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: julia -e 'using CompatHelper; CompatHelper.main()' + COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }} + # COMPATHELPER_PRIV: ${{ secrets.COMPATHELPER_PRIV }} diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml index d77d3a0..b838c67 100644 --- a/.github/workflows/TagBot.yml +++ b/.github/workflows/TagBot.yml @@ -1,11 +1,17 @@ name: TagBot on: - schedule: - - cron: 0 * * * * + issue_comment: # THIS BIT IS NEW + types: + - created + workflow_dispatch: jobs: TagBot: + # THIS 'if' LINE IS NEW + if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' + # NOTHING BELOW HAS CHANGED runs-on: ubuntu-latest steps: - uses: JuliaRegistries/TagBot@v1 with: token: ${{ secrets.GITHUB_TOKEN }} + ssh: ${{ secrets.DOCUMENTER_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 256e7eb..c6d281b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,8 +15,8 @@ jobs: fail-fast: false matrix: julia-version: - - "1.3" - - "1" + - "1.9" + - "1" # Leave this line unchanged. '1' will automatically expand to the latest stable 1.x release of Julia - "nightly" os: - ubuntu-latest @@ -24,18 +24,17 @@ jobs: - windows-latest julia-arch: - x64 - - x86 exclude: - os: macOS-latest julia-arch: x86 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: julia-actions/setup-julia@v1 with: version: ${{ matrix.julia-version }} arch: ${{ matrix.julia-arch }} - - uses: actions/cache@v1 + - uses: actions/cache@v3 env: cache-name: cache-artifacts with: @@ -48,14 +47,16 @@ jobs: - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 - uses: julia-actions/julia-processcoverage@v1 - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v4 with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: false file: lcov.info docs: name: Documentation runs-on: macos-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: julia-actions/setup-julia@v1 with: version: '1' diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..7747f3e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,34 @@ +# Changelog + +## [v1.3.0] - 2024-02-25 + +### Added + +- large type + +- roundhand script + +## Changed + +- up to Documenter 1 + +### Removed + +### Deprecated + +################################################################### + +## [v1.2.0] - 2021-12-30 + +### Added + +- boxed letters + +## Changed + +### Removed + +### Deprecated + +################################################################### + diff --git a/docs/make.jl b/docs/make.jl index 24deecb..9b654d1 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -8,8 +8,8 @@ makedocs( prettyurls = get(ENV, "CI", nothing) == "true", size_threshold=nothing, collapselevel=1, - assets = [ - ]), + assets = ["assets/zalgo-docs.css"] + ), pages = Any[ "Introduction" => "index.md", "Index" => "functionindex.md" diff --git a/docs/src/assets/largetype.png b/docs/src/assets/largetype.png new file mode 100644 index 0000000..cfb48d9 Binary files /dev/null and b/docs/src/assets/largetype.png differ diff --git a/docs/src/assets/scripts.png b/docs/src/assets/scripts.png new file mode 100644 index 0000000..ffc0096 Binary files /dev/null and b/docs/src/assets/scripts.png differ diff --git a/docs/src/assets/terminal1.png b/docs/src/assets/terminal1.png new file mode 100644 index 0000000..f6e4b91 Binary files /dev/null and b/docs/src/assets/terminal1.png differ diff --git a/docs/src/assets/zalgo-docs.css b/docs/src/assets/zalgo-docs.css new file mode 100644 index 0000000..5c63a8e --- /dev/null +++ b/docs/src/assets/zalgo-docs.css @@ -0,0 +1,130 @@ +/* change Bulma Dark styles */ + +/* disclaimer - I hate CSS */ + +:root { + --signage: hsl(193, 46%, 60%); + --verydark: hsl(237, 20%, 10%); + --quitedark: hsl(237, 20%, 13%); + --lessdark: hsl(237, 20%, 16%); +} + +html.theme--documenter-dark body { + background-color: var(--verydark); + color: #eff; + font-size: 1.1em; + font-weight: 400; + line-height: 1.5rem; +} + +html.theme--documenter-dark a { + color: var(--signage); +} + +html.theme--documenter-dark p > a:after { + padding-left:0.2rem; + font-family: "JuliaMono"; + content: "⮻"; + color: var(--signage); + background-color: inherit; + font-size: 120%; +} + +html.theme--documenter-light p > a:after { + padding-left:0.2rem; + font-family: "JuliaMono"; + content: "⮻"; + background-color: inherit; + font-size: 120%; +} + +html.theme--documenter-dark .has-text-left, +html.theme--documenter-dark body, +html.theme--documenter-dark #documenter .docs-sidebar, +html.theme--documenter-dark .documenter-example-output, +html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem, +html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem:hover, +html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem, +html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover, +html.theme--documenter-dark #documenter .docs-main header.docs-navbar { + background-color: var(--verydark); + border: 0.5px solid hsla(237, 20%, 10%, 0.3) !important; +} + +html.theme--documenter-dark .modal-card-body , +html.theme--documenter-dark .modal-card-head , +html.theme--documenter-dark .modal-card-foot , +html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu , +html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active { + background-color: var(--verydark); +} + +html.theme--documenter-dark .docstring , +html.theme--documenter-dark .docstring>header { + background-color: var(--lessdark); +} + +html.theme--documenter-dark .content pre, +html.theme--documenter-dark pre { + background-color: var(--lessdark); + border: 0.5px solid hsla(237, 20%, 10%, 0.3) !important; +} + +html.theme--documenter-dark a { + color: var(--signage); +} + +html.theme--documenter-dark .modal-card-head { + border: none; +} + + +.schemename { + font-family: "JuliaMono"; +} + +.swatch { + +} + +.category { + font-family: "JuliaMono"; + font-size: 0.8em; +} + +html.theme--documenter-dark p > code { + color: #eff !important; +} + + +html.theme--documenter-dark li > code { + color: #eff !important; +} + + +html.theme--documenter-dark a > code { + color: #eff !important; +} + +html.theme--documenter-dark p > a { + color: #eff !important; + } + +html.theme--documenter-dark .select select:focus, +html.theme--documenter-dark .textarea:focus, +html.theme--documenter-dark .input:focus, +html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:focus, +html.theme--documenter-dark .select select.is-focused, +html.theme--documenter-dark .is-focused.textarea, +html.theme--documenter-dark .is-focused.input, +html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused, +html.theme--documenter-dark .select select:active, +html.theme--documenter-dark .textarea:active, +html.theme--documenter-dark .input:active, +html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:active, +html.theme--documenter-dark .select select.is-active, +html.theme--documenter-dark .is-active.textarea, +html.theme--documenter-dark .is-active.input, +html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active { + border-color: var(--signage); +} diff --git a/docs/src/index.md b/docs/src/index.md index acdb5d8..56441bd 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -1,10 +1,10 @@ # Zalgo -## z͍͌︡͢aͯͥͫ̂l̥̓g︡͛̽̑͢o̰͛̉︠ +## Z̝̫͈̝ͩ͒̔͐̑̆̔︠̈a̜̙̜̯͇̳̱ͯͫͦ͑ͦ͘͟l͙͙̻̱͌ͮ̐́ͮͯ͟͢g͚̋̈̎͋̎̒̐ͮͯͦò̻̉\n -Zalgo text is digital text that has been modified by the addition of combining characters, Unicode symbols more usually employed to position diacritics above and below glyphs. +Zalgo text is digital text that has been modified by the addition of combining characters, the Unicode symbols more usually employed to position diacritics above and below glyphs. -"Zalgo" was named for a 2004 Internet meme that ascribed it to the influence of an eldritch deity. There's no official connection with H. P. Lovecraft's Cthulhu. +“Zalgo” was named for a 2004 Internet meme that ascribed it to the influence of an eldritch deity. There’s no official connection with H. P. Lovecraft’s Cthulhu. Use the `zalgo` function to add diacritics to a string. The options let you control how many diacritics are used. For maximum degeneracy, set `maxmarks` to a large number. @@ -15,14 +15,65 @@ zalgo("Julia is cool", maxmarks=100) ``` -Results vary considerably from font to font. - ## Utilities -Because this package is useless - and occasionally bad, because it can cause some applicatipns to misbehave (it can crash Atom, for example) - it also provides some conversions to justify its existence. +!!! note + + These utility functions use glyphs from the current font. Not many fonts contain all the necessary glyphs! + +Because this package is useless — and occasionally bad, because it can cause some applications to misbehave — it also provides some utility functions to justify its existence. + +The following functions convert the input string to equivalent characters that are to be found in the eldritch lexicon of the Unicode realm, where arcane glyphs and cryptic symbols abound. + +```julia +blackboard("Hello World") # double-struck or 'blackboard' style +boldfraktur("Hello World") # bold Fraktur (black letter) +bolditalic("Hello World") # bold italic +bolditalicsans("Hello World") # bold italic sans-serif +boldroman("Hello World") # bold roman +boldsans("Hello World") # bold sans-serif +boldscript("Hello World") # bold script-style +fraktur("Hello World") # Fraktur (black letter) +large_type("Hello World") # Large Type (9 segments per glyph) +italic("Hello World") # italic +italicsans("Hello World") # italic sans-serif +sans("Hello World") # sans-serif +script("Hello World") # script +teletype("Hello World") # monospaced 'teletype' +upsidedown("Hello World") # might look like it's flipped upside down +circled("HELLO WORLD") # letters in circles +boxed("hello world") # letters in boxes +segmented("0123456789") # digits converted to 7-segment 'LED"-type display +``` + +![terminal example](assets/terminal1.png) + +You can see what's going on using: + +```julia-repl +julia-1.10> collect(blackboard("Hello World")) +11-element Vector{Char}: + 'ℍ': Unicode U+210D (category Lu: Letter, uppercase) + '𝕖': Unicode U+1D556 (category Ll: Letter, lowercase) + '𝕝': Unicode U+1D55D (category Ll: Letter, lowercase) + '𝕝': Unicode U+1D55D (category Ll: Letter, lowercase) + '𝕠': Unicode U+1D560 (category Ll: Letter, lowercase) + ' ': ASCII/Unicode U+0020 (category Zs: Separator, space) + '𝕎': Unicode U+1D54E (category Lu: Letter, uppercase) + '𝕠': Unicode U+1D560 (category Ll: Letter, lowercase) + '𝕣': Unicode U+1D563 (category Ll: Letter, lowercase) + '𝕝': Unicode U+1D55D (category Ll: Letter, lowercase) + '𝕕': Unicode U+1D555 (category Ll: Letter, lowercase) +``` + +### "Large Type" + +Unicode 16 defines a set of glyphs that can be combined in a 3 × 3 grid to build larger letters. + +![large type](assets/largetype.png) -The following functions convert the input string to equivalent characters that are to be found in the darkest recesses of the Unicode charts. +### Script styles -![example](assets/example.svg) +There are two mathematical script styles: -The current font should contain the various Unicode glyphs. +![script style](assets/scripts.png) diff --git a/src/Zalgo.jl b/src/Zalgo.jl index fba2633..54147df 100644 --- a/src/Zalgo.jl +++ b/src/Zalgo.jl @@ -3,8 +3,7 @@ Zalgo.jl does two things. - It adds pointless diacritics to text: `zalgo("Cthulhu")` -- It converts an input ASCII string to equivalent characters found in the -darkest recesses of the Unicode charts: +- It converts an input ASCII string to equivalent characters found in the darkest recesses of the Unicode charts: ``` blackboard("Hello World") @@ -27,14 +26,14 @@ upsidedown("Hello World") ``` ```large_type("Hello World")``` displays the text using -the Large Text glyphs defined in Unicode 16. +the Large Type glyphs added to Unicode in version 16. """ module Zalgo export zalgo, boldfraktur, bolditalic, bolditalicsans, -boldroman, boldsans, boldscript, fraktur, italic, -italicsans, sans, script, teletype, upsidedown, blackboard, -boxed, circled, segmented, large_type + boldroman, boldsans, boldscript, fraktur, italic, + italicsans, sans, script, teletype, upsidedown, blackboard, + boxed, circled, segmented, large_type include("largetype.jl") @@ -49,9 +48,9 @@ const middledc = vcat('\u031B', '\u0334':'\u0338') const downdc = vcat('\u0316':'\u0319', '\u031C':'\u0333', '\u0339':'\u033C', '\u0347':'\u0349', '\u034D':'\u034E', '\u0353':'\u0356', '\u0359', - '\u035A', '\u035C', '\u035F','\u0362') + '\u035A', '\u035C', '\u035F', '\u0362') -const upsidedowndict = Dict{String, String}("a" => "ɐ", +const upsidedowndict = Dict{String,String}("a" => "ɐ", "b" => "q", "c" => "ɔ", "d" => "p", "e" => "ǝ", "f" => "ɟ", "g" => "ƃ", "h" => "ɥ", "i" => "ı", "j" => "ɾ", "k" => "ʞ", "l" => "ן", "m" => "ɯ", "n" => "u", "o" => "o", "p" => "d", "q" => "b", "r" => "ɹ", "s" => "s", @@ -66,7 +65,7 @@ const upsidedowndict = Dict{String, String}("a" => "ɐ", # These are a shambles, Unicode Consortium! # build the fraktur dict -frakturdict = Dict{String, Char}() +frakturdict = Dict{String,Char}() [frakturdict[string(Char(i + 64))] = vcat( '\U1D504', # A '\U1D505', # B @@ -94,12 +93,12 @@ frakturdict = Dict{String, Char}() '\U1D51b', # X '\U1D51c', # Y '\u2128' # Z ! - )[i] for i = 1:26] +)[i] for i = 1:26] [frakturdict[string(Char(i + 96))] = vcat('\U1D586':'\U1D59F')[i] for i = 1:26] frakturdict[" "] = ' ' # build the blackboard (double-struck) dict -blackboarddict = Dict{String, Char}() +blackboarddict = Dict{String,Char}() [blackboarddict[string(Char(i + 64))] = vcat( '\U1D538', # A '\U1D539', # B @@ -127,15 +126,15 @@ blackboarddict = Dict{String, Char}() '\U1D54f', # X '\U1D550', # Y '\u2124' # Z ! - )[i] for i = 1:26] +)[i] for i = 1:26] [blackboarddict[string(Char(i + 96))] = vcat('\U1D552':'\U1D56B')[i] for i = 1:26] # digits -[blackboarddict[string(Char(i + 48))] = vcat('\U1D7D8':'\U1D7E1')[i + 1] for i in 0:9] +[blackboarddict[string(Char(i + 48))] = vcat('\U1D7D8':'\U1D7E1')[i+1] for i in 0:9] blackboarddict[" "] = ' ' # build the Script dict -scriptdict = Dict{String, Char}() +scriptdict = Dict{String,Char}() [scriptdict[string(Char(i + 64))] = vcat('\U1D49C':'\U1D4B5')[i] for i = 1:26] [scriptdict[string(Char(i + 96))] = vcat('\U1D4b6':'\U1D4cf')[i] for i = 1:26] scriptdict["B"] = '\u212c' @@ -152,77 +151,77 @@ scriptdict["o"] = '\u2134' scriptdict[" "] = ' ' # build the boldroman dict -boldromandict = Dict{String, Char}() +boldromandict = Dict{String,Char}() [boldromandict[string(Char(i + 64))] = vcat('\U1D400':'\U1D419')[i] for i = 1:26] [boldromandict[string(Char(i + 96))] = vcat('\U1D41a':'\U1D433')[i] for i = 1:26] -[boldromandict[string(Char(i + 48))] = vcat('\U1D7CE':'\U1D7D7')[i + 1] for i = 0:9] +[boldromandict[string(Char(i + 48))] = vcat('\U1D7CE':'\U1D7D7')[i+1] for i = 0:9] boldromandict[" "] = ' ' # build the italic dict -italicdict = Dict{String, Char}() +italicdict = Dict{String,Char}() [italicdict[string(Char(i + 64))] = vcat('\U1D434':'\U1D44d')[i] for i = 1:26] [italicdict[string(Char(i + 96))] = vcat('\U1D44e':'\U1D467')[i] for i = 1:26] italicdict[" "] = ' ' # build the bolditalic dict -bolditalicdict = Dict{String, Char}() +bolditalicdict = Dict{String,Char}() [bolditalicdict[string(Char(i + 64))] = vcat('\U1D468':'\U1D481')[i] for i = 1:26] [bolditalicdict[string(Char(i + 96))] = vcat('\U1D482':'\U1D49b')[i] for i = 1:26] bolditalicdict[" "] = ' ' # build the boldscript dict -boldscriptdict = Dict{String, Char}() +boldscriptdict = Dict{String,Char}() [boldscriptdict[string(Char(i + 64))] = vcat('\U1D4D0':'\U1D4E9')[i] for i = 1:26] [boldscriptdict[string(Char(i + 96))] = vcat('\U1D4ea':'\U1D503')[i] for i = 1:26] boldscriptdict[" "] = ' ' # build the boldfraktur dict -boldfrakturdict = Dict{String, Char}() +boldfrakturdict = Dict{String,Char}() [boldfrakturdict[string(Char(i + 64))] = vcat('\U1D56c':'\U1D585')[i] for i = 1:26] [boldfrakturdict[string(Char(i + 96))] = vcat('\U1D586':'\U1D59f')[i] for i = 1:26] boldfrakturdict[" "] = ' ' # build the sans dict -sansdict = Dict{String, Char}() +sansdict = Dict{String,Char}() [sansdict[string(Char(i + 64))] = vcat('\U1D5A0':'\U1D5B9')[i] for i = 1:26] [sansdict[string(Char(i + 96))] = vcat('\U1D5ba':'\U1D5d3')[i] for i = 1:26] -[sansdict[string(Char(i + 48))] = vcat('\U1D7E2':'\U1D7EB')[i + 1] for i = 0:9] +[sansdict[string(Char(i + 48))] = vcat('\U1D7E2':'\U1D7EB')[i+1] for i = 0:9] sansdict[" "] = ' ' # build the boldsans dict -boldsansdict = Dict{String, Char}() +boldsansdict = Dict{String,Char}() [boldsansdict[string(Char(i + 64))] = vcat('\U1D5d4':'\U1D5ed')[i] for i = 1:26] [boldsansdict[string(Char(i + 96))] = vcat('\U1D5ee':'\U1D607')[i] for i = 1:26] -[boldsansdict[string(Char(i + 48))] = vcat('\U1D7EC':'\U1D7F5')[i + 1] for i = 0:9] +[boldsansdict[string(Char(i + 48))] = vcat('\U1D7EC':'\U1D7F5')[i+1] for i = 0:9] boldsansdict[" "] = ' ' # build the italicsans dict -italicsansdict = Dict{String, Char}() +italicsansdict = Dict{String,Char}() [italicsansdict[string(Char(i + 64))] = vcat('\U1D608':'\U1D621')[i] for i = 1:26] [italicsansdict[string(Char(i + 96))] = vcat('\U1D622':'\U1D63b')[i] for i = 1:26] italicsansdict[" "] = ' ' # build the bolditalicsans dict -bolditalicsansdict = Dict{String, Char}() +bolditalicsansdict = Dict{String,Char}() [bolditalicsansdict[string(Char(i + 64))] = vcat('\U1D63c':'\U1D655')[i] for i = 1:26] [bolditalicsansdict[string(Char(i + 96))] = vcat('\U1D656':'\U1D66f')[i] for i = 1:26] bolditalicsansdict[" "] = ' ' # build the teletype dict -ttdict = Dict{String, Char}() +ttdict = Dict{String,Char}() [ttdict[string(Char(i + 64))] = vcat('\U1D670':'\U1D689')[i] for i = 1:26] [ttdict[string(Char(i + 96))] = vcat('\U1D68a':'\U1D6a3')[i] for i = 1:26] -[ttdict[string(Char(i + 48))] = vcat('\U1D7F6':'\U1D7FF')[i + 1] for i = 0:9] +[ttdict[string(Char(i + 48))] = vcat('\U1D7F6':'\U1D7FF')[i+1] for i = 0:9] ttdict[" "] = ' ' # build the boxed dict -boxeddict = Dict{String, Char}() +boxeddict = Dict{String,Char}() [boxeddict[string(Char(i + 64))] = vcat('\U1F130':'\U1F14A')[i] for i = 1:26] [boxeddict[string(Char(i + 96))] = vcat('\U1F170':'\U1F18A')[i] for i = 1:26] boxeddict[" "] = ' ' # build the circled dict -circleddict = Dict{String, Char}() +circleddict = Dict{String,Char}() [circleddict[string(Char(i + 64))] = vcat('\u24b6':'\u24cf')[i] for i = 1:26] [circleddict[string(Char(i + 96))] = vcat('\u24d0':'\u24e9')[i] for i = 1:26] [circleddict[string(Char(i + 0x30))] = vcat('\u2460':'\u2468')[i] for i = 1:9] @@ -232,13 +231,13 @@ circleddict[" "] = ' ' # negativecircled dict # build the circled dict -negativecircleddict = Dict{String, Char}() +negativecircleddict = Dict{String,Char}() [negativecircleddict[string(Char(i + 64))] = vcat('\U1F150':'\U1F169')[i] for i = 1:26] [negativecircleddict[string(Char(i + 96))] = vcat('\U1F170':'\U1F189')[i] for i = 1:26] negativecircleddict[" "] = ' ' # build the segmented dict -segmenteddict = Dict{String, Char}() +segmenteddict = Dict{String,Char}() [segmenteddict[string(Char(i + 0x2f))] = vcat('\U1FBF0':'\U1FBF9')[i] for i = 1:10] segmenteddict[" "] = ' ' @@ -255,10 +254,10 @@ Randomly add up to `maxmarks` diacritic marks to each letter of `str`. The `upma diacritic marks added to the letter at that position. """ function zalgo(text::String; - upmarks = 1:4, - middlemarks = 1:4, - downmarks = 1:4, - maxmarks = 6) + upmarks=1:4, + middlemarks=1:4, + downmarks=1:4, + maxmarks=6) letters = split(text, "") zalgostring = String[] for letter in letters @@ -267,8 +266,8 @@ function zalgo(text::String; push!(zalgostring, letter) continue end - upmarks_added = rand(upmarks.start:upmarks.stop) - downmarks_added = rand(downmarks.start:downmarks.stop) + upmarks_added = rand(upmarks.start:upmarks.stop) + downmarks_added = rand(downmarks.start:downmarks.stop) middlemarks_added = rand(middlemarks.start:middlemarks.stop) newletter = letter for i in 1:maxmarks @@ -316,13 +315,26 @@ function fraktur(str) end """ - script(str) + script(str; roundhand=false) -Return a version of string `str` with script letters from the Unicode table. +Return a version of string `str` with mathematical script letters from the Unicode table. + +There are two basic styles of mathematical script lettering: the “regular” +calligraphic or Chancery alphabet, and the “fancy script” or round hand alphabet. + +By default, the script style will be “script”. If `roundhand` is true, the style will +be “roundhand”. + +For more details, see [this Unicode document](https://www.unicode.org/L2/L2020/20275r-math-calligraphic.pdf). """ -function script(str) +function script(str; + roundhand=false) asciistr = filter!(c -> haskey(scriptdict, c), split(str, "")) - return join(map(c -> scriptdict[c], asciistr)) + if roundhand == true + return join(map(c -> string(Zalgo.scriptdict[c], Char(0xFE01)), asciistr)) + else + return join(map(c -> Zalgo.scriptdict[c], asciistr)) + end end """ @@ -457,15 +469,15 @@ end Return a version of string `str` with circled/boxed letters from the Unicode table. ``` -A-Z \u24b6:\u24cf "A" -> "Ⓐ" -a-z \u24d0:\u24e9 "a" -> "ⓐ" -0-9 \u2460:\u2468 "0" -> "⓪" -A-Z negative \U1F150:\U1F169 "A" -> "🅐" -a-z negative \U1F170:\U1F189 "a" -> "🅰" +A-Z "A" -> "Ⓐ" \u24b6:\u24cf +a-z "a" -> "ⓐ" \u24d0:\u24e9 +0-9 "0" -> "⓪" \u2460:\u2468 +A-Z inverse "A" -> "🅐" \U1F150:\U1F169 +a-z inverse "a" -> "🅰" \U1F170:\U1F189 ``` """ function circled(str; - negative=false) + negative=false) if negative asciistr = filter!(c -> haskey(negativecircleddict, c), split(str, "")) return join(map(c -> negativecircleddict[c], asciistr)) diff --git a/src/_build-glyphs.jl b/src/_build-glyphs.jl deleted file mode 100644 index 5c6c8a8..0000000 --- a/src/_build-glyphs.jl +++ /dev/null @@ -1,57 +0,0 @@ -s = [ - " 𜸜 𜸜𜸜 𜸚𜸺𜸤𜹇 𜹇𜸚𜸤 𜸜 𜸚𜸥𜸞𜸤 𜸣 𜸣 ", - " 𜸩 𜸺𜸺 𜸾𜸺𜸤𜸬𜸴𜸻𜸮𜹀𜸺 𜸩 𜸩 𜸪𜸲𜸸𜸞𜸺𜸥 𜸞𜸟𜸥 𜸞𜸟𜸥", - " 𜹊 𜸺𜸺 𜸾𜸺𜹃𜹐 𜹐𜸾𜸟𜹃 𜸾𜸥𜸞𜹃 𜸭 𜹃 ▘ 𜸭 ", - "𜸚𜸟𜸤 𜸦 𜸚𜸟𜸤𜸚𜸟𜸤𜸜 𜸜𜸛𜸟𜸥𜸚𜸟𜸤𜸞𜸟𜸧𜸚𜸟𜸤𜸚𜸟𜸤 𜸬 𜸢 𜸚𜸟𜸤", - "𜸩 𜸩 𜸩 𜸚𜸟𜹃 𜸟𜸷𜸽𜸟𜸺𜸽𜸟𜸤𜸨𜸟𜸤 𜸵𜸻𜸮𜸟𜸷𜸾𜸟𜸶 ▘ 𜹐 𜸫 𜸞𜸟𜸥 𜸻 𜸵𜸻", - "𜸾𜸟𜹃 𜸼 𜸽𜸟𜸥𜸾𜸟𜹃 𜸼𜸾𜸟𜹃𜸾𜸟𜹃 𜸼 𜸾𜸟𜹃𜸾𜸟𜹃 ▘ 𜹃 𜸞𜸟𜸥 𜹊 ", - "𜸚𜸟𜸤𜸚𜸟𜸤𜸛𜸟𜸤𜸚𜸟𜸤𜸛𜸟𜸤𜸛𜸟𜸥𜸛𜸟𜸥𜸚𜸟𜸤𜸜 𜸜 𜸠 𜸜𜸜 𜸜𜸜 𜸝𜸡𜸦𜸝𜸢𜸜𜸛𜸟𜸧", - "𜸚𜸧𜸩𜸨𜸟𜸶𜸨𜸟𜸷𜸩 𜸩 𜸩𜸨𜸟 𜸨𜸟 𜸩 𜸧𜸨𜸟𜸶 𜸩 𜸩𜸨𜸯𜸸𜸩 𜸩𜸰𜸩𜸩𜸫𜸹𜸩 𜸩", - "𜸾𜹀𜹃𜸼 𜸼𜸽𜸟𜹃𜸾𜸟𜹃𜸽𜸟𜹃𜸽𜸟𜸥𜸼 𜸾𜸟𜹃𜸼 𜸼 𜹀 𜸾𜸟𜹃𜸼 𜸼𜸽𜸟𜸥𜸼 𜸼𜸼 𜸼𜸽𜸟𜹄", - "𜸛𜸟𜸤𜸚𜸟𜸤𜸛𜸟𜸤𜸚𜸟𜸤𜸞𜸠𜸥𜸜 𜸜𜸜 𜸜𜸜 𜸜𜸜 𜸜𜸜 𜸜𜸛𜸟𜸧 𜸛𜸥𜸜 𜸞𜸧 𜸱 ", - "𜸨𜸟𜹃𜸩 𜸩𜸨𜸟𜸷𜸾𜸟𜸤 𜸩 𜸩 𜸩𜸩 𜸩𜸩𜸱𜸩𜸪𜸲𜸸𜸫𜸳𜸻𜸬𜸴𜸻 𜸩 𜸫𜸲𜸢 𜸩 𜹂 ", - "𜸼 𜸾𜸟𜹅𜸼 𜸼𜸾𜸟𜹃 𜸼 𜸾𜸟𜹃𜸫𜹁𜸻𜸿𜹂𜹆𜸼 𜸼 𜸼 𜸽𜸟𜹄 𜸽𜸥 𜸼𜸞𜹄 ▀▀▀", - " 𜸤 𜸜 𜸜 𜸚𜸤 𜸜 𜸣 𜸣 𜸜 𜸜 ", - " 𜸚𜸧 𜸨𜸤 𜸚𜸥 𜸚𜸶 𜸚𜸤 𜸺 𜸚𜸧 𜸨𜸤 𜸜 𜸜 𜸨𜸷 𜸩 𜸝𜸦 𜸛𜸤 𜸚𜸤 ", - " 𜸾𜹄 𜸽𜹃 𜸾𜸥 𜸾𜹄 𜸾𜸥 𜸼 𜸾𜸶 𜸼𜸼 𜸼 𜸾𜹃 𜸼𜸼 𜸼 𜸼𜸼 𜸼𜸼 𜸾𜹃 ", - " 𜸣 𜸚𜸥 𜹈 𜸞𜸤 ▚▚▚", - "𜸛𜸤 𜸚𜸧 𜸚𜸥 𜸚𜸥 𜸺 𜸜𜸜 𜸜𜸜 𜸜𜸜 𜸮𜸷 𜸜𜸜 𜸞𜸧 𜸷 𜸮 𜸚𜸟𜹃▚▚▚", - "𜸨𜹃 𜸾𜸶 𜸼 𜸞𜹃 𜸾𜹃 𜸽𜹄 𜸾𜹃 𜸿𜹆 𜸼𜸼 𜸾𜸶 𜸽𜸥 𜸾𜸥 𜹌 𜸞𜹃 ▚▚▚", -] - -A = Matrix{String}(undef, 18, 48) - -for (row, ln) in enumerate(s) - rw = split(ln, "") - for (n, c) in enumerate(rw) - A[row, n] = c - end -end - -function getglyph(row, col) - a = [] - for r in (3row-2):(3row-2)+2 - for g in (3col-2):(3col-2)+2 - push!(a, A[r, g]) - end - end - return a -end - -# "A" => _buildLargeTypeChar("𜸚𜸟𜸤𜸨𜸟𜸶𜸼 𜸼"), - -let - char = 32 - for row in 1:6 - for col in 1:16 - print("\"$(Char(char))\" => _buildLargeTypeChar(\"") - g = getglyph(row, col) - for gl in g - print(gl) - end - println("\"),") - char += 1 - end - println() - end -end diff --git a/src/largetype.jl b/src/largetype.jl index 8f82446..9e901ac 100644 --- a/src/largetype.jl +++ b/src/largetype.jl @@ -1,3 +1,6 @@ +# thanks to Philippe Majerus https://github.com/PhMajerus for documenting these +# in some detail + """ A single "LargeType" glyph, using the system of pieces defined in Unicode version 16. Each glyph is made up of nine pieces, each in the range U1CE1A to U1CE50. @@ -15,16 +18,19 @@ struct LargeTypeChar end """ -a sequence of large type glyphs +A sequence of LargeType glyphs """ struct LargeTypeString glyphs::Array{LargeTypeChar,1} end """ -make a LargeType glyph from a string +Construct a LargeType glyph from a string. """ function _buildLargeTypeChar(str) + if length(str) != 9 + throw(error("_buildLargeTypeChar: exactly nine characters required - $(str) is $(length(str))")) + end return LargeTypeChar([Char(e) for e in str]...) end diff --git a/test/runtests.jl b/test/runtests.jl index 7426040..8e826b7 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -48,6 +48,13 @@ s = "Julia is really cool" @test length(blackboard("Figure 2")) == 8 @test length(blackboard("Figure 22")) == 9 +# two script styles +sc1 = collect(script("Good Morning Sir", roundhand=false)) +sc2 = collect(script("Good Morning Sir", roundhand=true)) + +# they'll only differ by one: sc2 has a VS2 (U+FE01) after every glyph +@test length(setdiff(sc2, sc1) == 1) + @test length(large_type("ABC").glyphs) == 3 #=