Go · 2840 bytes Raw Blame History
1 // SPDX-License-Identifier: AGPL-3.0-or-later
2
3 package markdown
4
5 import "context"
6
7 // RepoContext is the optional repo binding for `#N` reference
8 // resolution. When nil, `#N` renders as plain text (matches
9 // "repo-context-less rendering" in the spec).
10 type RepoContext struct {
11 OwnerUsername string
12 RepoName string
13 RepoID int64
14 }
15
16 // Resolvers wire the package against the rest of the runtime without
17 // importing usersdb / issuesdb directly (avoids a cycle with packages
18 // that themselves render markdown). Each resolver is optional; a nil
19 // resolver means "render as plain text" for that flavor of reference.
20 //
21 // All resolvers MUST be visibility-aware: they receive the viewer
22 // (Options.ViewerUserID) and return ok=false when the resource isn't
23 // visible. Returning a link to a hidden resource leaks existence.
24 type Resolvers struct {
25 // User: @username → "/username" if the user exists, isn't
26 // suspended, and (post-S30) is org-team-visible to the viewer.
27 User func(ctx context.Context, username string) (href string, ok bool)
28 // Issue: (repoOwner, repoName, number) → "/owner/repo/issues/N".
29 // Returns ok=false when the repo isn't visible to viewer or the
30 // number wasn't allocated yet.
31 Issue func(ctx context.Context, owner, name string, number int64, viewerUserID int64) (href string, ok bool)
32 // Commit: short-or-full SHA inside the current repo context →
33 // "/owner/repo/commit/<full_sha>". Only invoked when
34 // Opts.Repo != nil.
35 Commit func(ctx context.Context, repoOwner, repoName, shaPrefix string) (href, fullSHA string, ok bool)
36 // Team: @org/team → "/org/teams/team". Visibility-aware: a
37 // secret team the viewer can't see should return ok=false so
38 // the renderer falls back to plain text. (S31)
39 Team func(ctx context.Context, orgSlug, teamSlug string, viewerUserID int64) (href string, ok bool)
40 }
41
42 // Options tunes a single Render call. Zero-value Options is valid
43 // and yields a safe, generic render with no reference resolution.
44 type Options struct {
45 // Repo is the binding for same-repo `#N` resolution. nil means
46 // "no repo context"; `#N` renders as plain text.
47 Repo *RepoContext
48
49 // ViewerUserID gates cross-repo `#N` and `@user` resolution.
50 // 0 = anonymous viewer.
51 ViewerUserID int64
52
53 // SoftBreakAsBR controls newline-as-<br> rendering:
54 // true — comment / issue / PR body shape (matches GitHub UI)
55 // false — README / structured-doc shape (preserve markdown semantics)
56 SoftBreakAsBR bool
57
58 // LinkTargetBlank, when true, sets target="_blank" rel="noopener
59 // noreferrer" on autolinks + reference links. Default off; READMEs
60 // keep links in-page so the user doesn't lose context.
61 LinkTargetBlank bool
62
63 // Resolvers wires reference resolution. nil resolvers in the
64 // struct mean "render that flavor as plain text".
65 Resolvers Resolvers
66 }
67