New md: module.

This commit is contained in:
Qi Xiao 2024-02-26 10:40:24 +00:00
parent 175b835bbd
commit 4f822ab654
9 changed files with 128 additions and 2 deletions

View File

@ -3,6 +3,9 @@
- The `os` module has gained the following new commands: `mkdir-all`, - The `os` module has gained the following new commands: `mkdir-all`,
`symlink` and `rename`. `symlink` and `rename`.
- A new `md` module, currently containing a single function `md:show` for
rendering Markdown in the terminal.
# Notable bugfixes # Notable bugfixes
- The string comparison commands `<s`, `<=s`, `==s`, `>s` and `>=s` (but not - The string comparison commands `<s`, `<=s`, `==s`, `>s` and `>=s` (but not

View File

@ -9,8 +9,13 @@
# the explicit `builtin:` namespace (like `builtin:put`). # the explicit `builtin:` namespace (like `builtin:put`).
# #
# The `&width` option specifies the width to wrap the output to. If it is 0 (the # The `&width` option specifies the width to wrap the output to. If it is 0 (the
# default) or negative, `show` queries the width of the terminal and use it as # default) or negative, `show` queries the terminal width of the standard output
# the width, falling back to 80 if the query fails. # and use it as the width, falling back to 80 if the query fails (for example
# when the standard output is not a terminal).
#
# This command is roughly equivalent to `md:show &width=$width (doc:show
# $symbol)`, but has some extra processing of relative links to point them to
# the Elvish website.
# #
# Examples: # Examples:
# #
@ -24,6 +29,8 @@
# ~> doc:show doc:show # ~> doc:show doc:show
# [ omitted ] # [ omitted ]
# ``` # ```
#
# See also [`md:show`]().
fn show {|symbol &width=0| } fn show {|symbol &width=0| }
# Finds symbols whose documentation contains all strings in `$queries`. # Finds symbols whose documentation contains all strings in `$queries`.

20
pkg/mods/md/md.d.elv Normal file
View File

@ -0,0 +1,20 @@
# Renders `$markdown` in the terminal.
#
# The `&width` option specifies the width to wrap the output to. If it is 0 (the
# default) or negative, `show` queries the terminal width of the standard output
# and use it as the width, falling back to 80 if the query fails (for example
# when the standard output is not a terminal).
#
# Examples:
#
# ```elvish-transcript
# ~> md:show "#h1 heading\n- List\n- Item"
# #h1 heading
#
# • List
#
# • Item
# ```
#
# See also [`doc:show`]().
fn show {|&width=0| markdown}

37
pkg/mods/md/md.go Normal file
View File

@ -0,0 +1,37 @@
// Package md exposes functionality from src.elv.sh/pkg/md.
package md
import (
"src.elv.sh/pkg/elvdoc"
"src.elv.sh/pkg/eval"
"src.elv.sh/pkg/md"
"src.elv.sh/pkg/sys"
)
// Ns is the namespace for the md: module.
var Ns = eval.BuildNsNamed("md").
AddGoFns(map[string]any{
"show": show,
}).Ns()
type showOpts struct {
Width int
}
func (*showOpts) SetDefaultOptions() {}
func show(fm *eval.Frame, opts showOpts, markdown string) error {
width := opts.Width
if width <= 0 {
_, width = sys.WinSize(fm.Port(1).File)
if width <= 0 {
width = 80
}
}
codec := &md.TTYCodec{
Width: width,
HighlightCodeBlock: elvdoc.HighlightCodeBlock,
}
_, err := fm.ByteOutput().WriteString(md.RenderString(markdown, codec))
return err
}

24
pkg/mods/md/md_test.elvts Normal file
View File

@ -0,0 +1,24 @@
//each:eval use md
///////////
# md:show #
///////////
// Transcript tests are not run with a real terminal connected to the output, so
// the width will fall back to 80.
~> md:show 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
~> md:show "#h1 heading\n- List\n- Item"
#h1 heading
• List
• Item
## explicit &width ##
~> md:show &width=40 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua.

15
pkg/mods/md/md_test.go Normal file
View File

@ -0,0 +1,15 @@
package md_test
import (
"embed"
"testing"
"src.elv.sh/pkg/eval/evaltest"
)
//go:embed *.elvts
var transcripts embed.FS
func TestTranscripts(t *testing.T) {
evaltest.TestTranscriptsInFS(t, transcripts)
}

View File

@ -8,6 +8,7 @@ import (
"src.elv.sh/pkg/mods/file" "src.elv.sh/pkg/mods/file"
"src.elv.sh/pkg/mods/flag" "src.elv.sh/pkg/mods/flag"
"src.elv.sh/pkg/mods/math" "src.elv.sh/pkg/mods/math"
"src.elv.sh/pkg/mods/md"
"src.elv.sh/pkg/mods/os" "src.elv.sh/pkg/mods/os"
"src.elv.sh/pkg/mods/path" "src.elv.sh/pkg/mods/path"
"src.elv.sh/pkg/mods/platform" "src.elv.sh/pkg/mods/platform"
@ -33,6 +34,7 @@ func AddTo(ev *eval.Evaler) {
ev.AddModule("flag", flag.Ns) ev.AddModule("flag", flag.Ns)
ev.AddModule("doc", doc.Ns) ev.AddModule("doc", doc.Ns)
ev.AddModule("os", os.Ns) ev.AddModule("os", os.Ns)
ev.AddModule("md", md.Ns)
if unix.ExposeUnixNs { if unix.ExposeUnixNs {
ev.AddModule("unix", unix.Ns) ev.AddModule("unix", unix.Ns)
} }

View File

@ -44,6 +44,10 @@ title = "file: File Utilities"
name = "math" name = "math"
title = "math: Math Utilities" title = "math: Math Utilities"
[[articles]]
name = "md"
title = "md: Markdown Utilities"
[[articles]] [[articles]]
name = "os" name = "os"
title = "os: Operating system functionality" title = "os: Operating system functionality"

14
website/ref/md.md Normal file
View File

@ -0,0 +1,14 @@
<!-- toc -->
@module md
# Introduction
The `md:` module provides utilities for working with Markdown text.
Function usages are given in the same format as in the reference doc for the
[builtin module](builtin.html).
This module uses a custom implementation that supports
[a large subset](https://pkg.go.dev/src.elv.sh/pkg/md#hdr-Which_Markdown_variant_does_this_package_implement_)
of CommonMark.