Skip to content

Commit f1fdac4

Browse files
committed
display source locations for @code blocks and inlined @snippets
1 parent 3eb392b commit f1fdac4

18 files changed

+166
-61
lines changed

Assets/css/Main.css

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/css/Main.css.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import Sources
2+
13
extension Markdown
24
{
35
@frozen public
@@ -8,11 +10,14 @@ extension Markdown
810
/// A reference to an HTML object. These originate from inline autolinks.
911
case link(SourceString)
1012
/// A reference to a file, by its file name. These originate from block directive
11-
/// arguments.
13+
/// arguments, such as those in an `@Image`.
1214
case file(SourceString)
1315
/// A reference to a file, by its file path, which is often relative. These originate
1416
/// from ``InlineImage``s.
1517
case filePath(SourceString)
18+
/// A reference to a source location, which has already been resolved. These originate
19+
/// from the inlining of code snippets.
20+
case location(SourceLocation<Int32>)
1621
}
1722
}
1823
extension Markdown.AnyReference
@@ -25,15 +30,15 @@ extension Markdown.AnyReference
2530
}
2631
extension Markdown.AnyReference
2732
{
28-
@inlinable public
29-
var text:Markdown.SourceString
30-
{
31-
switch self
32-
{
33-
case .code(let text): text
34-
case .link(let text): text
35-
case .file(let text): text
36-
case .filePath(let text): text
37-
}
38-
}
33+
// @inlinable public
34+
// var text:Markdown.SourceString
35+
// {
36+
// switch self
37+
// {
38+
// case .code(let text): text
39+
// case .link(let text): text
40+
// case .file(let text): text
41+
// case .filePath(let text): text
42+
// }
43+
// }
3944
}

Sources/MarkdownPluginSwift/Snippets/SnippetParser.SliceFetus.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ extension SnippetParser.SliceFetus
2323
static
2424
func anonymous(start position:AbsolutePosition) -> Self
2525
{
26-
.init(id: "", position: position, marker: (1, 0))
26+
// Note: line number is zero-indexed.
27+
// This is different from the SwiftSyntax convention.
28+
.init(id: "", position: position, marker: (0, 0))
2729
}
2830

2931
static

Sources/MarkdownPluginSwift/Snippets/SnippetParser.SliceMarker.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ extension SnippetParser
1212
let before:AbsolutePosition
1313
/// The UTF-8 offset of the newline after the slice marker, assuming it exists.
1414
let after:AbsolutePosition
15-
/// The line number (1-indexed) of the slice marker.
15+
/// The line number (0-indexed) of the slice marker.
1616
let line:Int
1717
}
1818
}

Sources/MarkdownPluginSwift/Snippets/SnippetParser.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ extension SnippetParser
9595
indent: indent,
9696
before: before,
9797
after: range.upperBound.advanced(by: 1),
98-
line: location.line))
98+
line: location.line - 1))
9999
}
100100
else
101101
{

Sources/MarkdownSemantics/AST/Media/Markdown.BlockCodeFragment.swift

+4-2
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ extension Markdown.BlockCodeFragment
134134

135135
if let slice:Markdown.SnippetSlice = snippet.slices[slice]
136136
{
137-
yield(Markdown.BlockCodeLiteral.init(bytecode: slice.code))
137+
yield(Markdown.BlockCodeLiteral.init(bytecode: slice.code,
138+
location: slice.location(in: snippet.id)))
138139
}
139140
else
140141
{
@@ -151,7 +152,8 @@ extension Markdown.BlockCodeFragment
151152
}
152153
for slice:Markdown.SnippetSlice in snippet.slices.values
153154
{
154-
yield(Markdown.BlockCodeLiteral.init(bytecode: slice.code))
155+
yield(Markdown.BlockCodeLiteral.init(bytecode: slice.code,
156+
location: slice.location(in: snippet.id)))
155157
}
156158
}
157159
}

Sources/MarkdownSemantics/AST/Media/Markdown.BlockCodeLiteral.swift

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import MarkdownABI
2+
import Sources
23

34
extension Markdown
45
{
@@ -12,10 +13,16 @@ extension Markdown
1213
private
1314
let language:String
1415

15-
init(bytecode:Markdown.Bytecode, language:String = "swift")
16+
private
17+
var location:Outlinable<SourceLocation<Int32>>?
18+
19+
init(bytecode:Markdown.Bytecode,
20+
language:String = "swift",
21+
location:SourceLocation<Int32>?)
1622
{
1723
self.bytecode = bytecode
1824
self.language = language
25+
self.location = location.map(Outlinable.inline(_:))
1926
}
2027

2128
override
@@ -25,6 +32,22 @@ extension Markdown
2532
{
2633
$0 += self.bytecode
2734
}
35+
if case .outlined(let reference) = self.location
36+
{
37+
binary &= reference
38+
}
39+
}
40+
41+
override
42+
func outline(by register:(Markdown.AnyReference) throws -> Int?) rethrows
43+
{
44+
if case .inline(let location) = self.location,
45+
let reference:Int = try register(.location(location))
46+
{
47+
self.location = .outlined(reference)
48+
}
49+
50+
try super.outline(by: register)
2851
}
2952
}
3053
}

Sources/MarkdownSemantics/AST/Media/Markdown.BlockCodeReference.swift

+26-1
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,24 @@ extension Markdown
77
public final
88
class BlockCodeReference:BlockContainer<BlockElement>
99
{
10+
/// This is the location of the block directive itself, not the code.
1011
public
1112
var source:SourceReference<Source>?
1213

1314
public private(set)
1415
var language:String?
16+
17+
/// The title of the snippet. This is entirely fictitious and only used for display
18+
/// purposes.
1519
public private(set)
1620
var title:String?
1721

1822
/// The name of the snippet, **including** its file extension.
1923
public private(set)
2024
var file:String?
25+
/// A link to the snippet.
26+
public
27+
var link:Outlinable<Int32>?
2128
/// The name of a second snippet, **including** its file extension, which will be used
2229
/// as the base for computing a diff.
2330
public private(set)
@@ -41,9 +48,9 @@ extension Markdown
4148
public override
4249
func emit(into binary:inout Markdown.BinaryEncoder)
4350
{
44-
binary[.h3] = self.title
4551
if let code:Markdown.Bytecode = self.code
4652
{
53+
binary[.pre] { $0[.class] = "title" } = self.title
4754
binary[.snippet, { $0[.language] = self.language }] { $0 += code }
4855
}
4956
else
@@ -57,6 +64,24 @@ extension Markdown
5764
}
5865
}
5966
}
67+
if case .outlined(let reference) = self.link
68+
{
69+
binary &= reference
70+
}
71+
72+
super.emit(into: &binary)
73+
}
74+
75+
public override
76+
func outline(by register:(Markdown.AnyReference) throws -> Int?) rethrows
77+
{
78+
if case .inline(let file) = self.link,
79+
let reference:Int = try register(.location(.init(position: .zero, file: file)))
80+
{
81+
self.link = .outlined(reference)
82+
}
83+
84+
try super.outline(by: register)
6085
}
6186
}
6287
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import Sources
2+
3+
extension Markdown.SnippetSlice
4+
{
5+
func location(in file:Int32) -> SourceLocation<Int32>?
6+
{
7+
guard
8+
let position:SourcePosition = .init(line: self.line, column: 0)
9+
else
10+
{
11+
return nil
12+
}
13+
14+
return .init(position: position, file: file)
15+
}
16+
}

Sources/SwiftinitRender/Formats/Swiftinit.RenderFormat.Assets.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ extension Swiftinit.RenderFormat.Assets
2222
/// To reduce cache churn, not all assets are versioned. For example, the fonts and
2323
/// the favicon do not use the version numbers.
2424
@inlinable public static
25-
var version:MajorVersion { .v(19) }
25+
var version:MajorVersion { .v(20) }
2626
}
2727
extension Swiftinit.RenderFormat.Assets
2828
{

Sources/SymbolGraphLinker/Resolution/SSGC.Outliner.swift

+4
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ extension SSGC.Outliner
160160
name = .init(
161161
source: link.source,
162162
string: String.init(link.string[link.string.index(after: i)...]))
163+
164+
case .location(let location):
165+
// This is almost a no-op, except we can optimize away duplicated locations.
166+
return self.cache.add(outline: .location(location))
163167
}
164168

165169
if let resource:SSGC.Resource = self.locate(resource: name.string)

Sources/SymbolGraphLinker/SSGC.Linker.Tables.swift

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ extension SSGC.Linker.Tables
8686
}
8787

8888
block.inline(code: code, base: base, with: parser)
89+
block.link = .inline(file.id)
8990
}
9091
}
9192
}

Sources/UnidocLinker/Resolver/Unidoc.Resolver.swift

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ extension Unidoc.Resolver
9191
switch outline
9292
{
9393
case .location(let location):
94+
// File references never cross packages, so this is basically a no-op.
9495
let line:Int? = location.position == .zero ? nil : location.position.line
9596
return .file(line: line, self.current.id + location.file)
9697

Stylesheets/Main.scss

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
@import 'p';
2020
@import 'pre';
2121
@import 'Search';
22+
@import 'section';
2223
@import 'section.availability';
2324
@import 'section.declaration';
2425
@import 'section.details';

Stylesheets/_section.details.scss

+21-2
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,29 @@ section.details
6868
}
6969
}
7070

71+
pre.title
72+
{
73+
//padding-left: 1rem;
74+
margin-top: 1rem;
75+
margin-bottom: 0;
76+
77+
//background-color: $light-code-well;
78+
font-family: $typeface-monospace;
79+
font-weight: 700;
80+
color: $light-foreground-fade;
81+
}
82+
pre.title + pre
83+
{
84+
margin-top: 0.5rem;
85+
}
7186
pre
7287
{
7388
font-size: 90.625%;
7489
}
75-
76-
90+
pre + a.source
91+
{
92+
margin-top: 0rem;
93+
position: relative;
94+
top: -1rem;
95+
}
7796
}

Stylesheets/_section.introduction.scss

-37
Original file line numberDiff line numberDiff line change
@@ -86,43 +86,6 @@ section.introduction
8686
max-width: inherit;
8787
}
8888

89-
a.source.github::before
90-
{
91-
display: inline-block;
92-
content: '';
93-
height: 1.125rem;
94-
width: 1.125rem;
95-
96-
margin-right: 0.5em;
97-
98-
background-image: url('data:image/svg+xml;utf8,\
99-
<svg xmlns="http://www.w3.org/2000/svg" width="98" height="98">\
100-
<path fill-rule="evenodd" fill="rgb(255, 86, 158)" clip-rule="evenodd" \
101-
d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"/>\
102-
</svg>');
103-
background-size: 100% 100%;
104-
}
105-
a.source
106-
{
107-
display: flex;
108-
align-items: center;
109-
110-
font-family: $typeface-monospace;
111-
font-size: 87.5%;
112-
color: $light-foreground-semi;
113-
text-decoration-color: $light-accent-barbie-pink;
114-
115-
span.file
116-
{
117-
font-weight: 500;
118-
}
119-
120-
span.file,
121-
span.line
122-
{
123-
color: $light-accent-barbie-pink;
124-
}
125-
}
12689
a.source + a.source
12790
{
12891
margin-top: 0.5rem;

Stylesheets/_section.scss

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
@import 'Colors';
2+
@import 'Typefaces';
3+
4+
section
5+
{
6+
a.source.github::before
7+
{
8+
display: inline-block;
9+
content: '';
10+
height: 1.125rem;
11+
width: 1.125rem;
12+
13+
margin-right: 0.5em;
14+
15+
background-image: url('data:image/svg+xml;utf8,\
16+
<svg xmlns="http://www.w3.org/2000/svg" width="98" height="98">\
17+
<path fill-rule="evenodd" fill="rgb(255, 86, 158)" clip-rule="evenodd" \
18+
d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"/>\
19+
</svg>');
20+
background-size: 100% 100%;
21+
}
22+
a.source
23+
{
24+
display: flex;
25+
align-items: center;
26+
27+
font-family: $typeface-monospace;
28+
font-size: 87.5%;
29+
color: $light-foreground-semi;
30+
text-decoration-color: $light-accent-barbie-pink;
31+
32+
span.file
33+
{
34+
font-weight: 500;
35+
}
36+
37+
span.file,
38+
span.line
39+
{
40+
color: $light-accent-barbie-pink;
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)