Save a link's context as a snippet

pull/6/head
Mickaël Menu 3 years ago
parent 1270aab7bb
commit fb78993fbc
No known key found for this signature in database
GPG Key ID: 53D73664CD359895

@ -140,7 +140,7 @@ func TestShellHelper(t *testing.T) {
testString(t, testString(t,
`{{sh "echo 'Hello, world!'"}}`, `{{sh "echo 'Hello, world!'"}}`,
nil, nil,
"Hello, world!\n", "Hello, world!",
) )
} }

@ -135,6 +135,7 @@ func parseLinks(root ast.Node, source []byte) ([]note.Link, error) {
Href: href, Href: href,
Rels: strings.Fields(string(link.Title)), Rels: strings.Fields(string(link.Title)),
External: strutil.IsURL(href), External: strutil.IsURL(href),
Snippet: extractLines(n.Parent(), source),
}) })
} }
} }
@ -143,6 +144,19 @@ func parseLinks(root ast.Node, source []byte) ([]note.Link, error) {
return links, err return links, err
} }
func extractLines(n ast.Node, source []byte) string {
if n == nil {
return ""
}
segs := n.Lines()
if segs.Len() == 0 {
return ""
}
start := segs.At(0).Start
end := segs.At(segs.Len() - 1).Stop
return string(source[start:end])
}
// frontmatter contains metadata parsed from a YAML frontmatter. // frontmatter contains metadata parsed from a YAML frontmatter.
type frontmatter struct { type frontmatter struct {
values map[string]interface{} values map[string]interface{}

@ -175,42 +175,53 @@ A link can have [one relation](one "rel-1") or [several relations](several "rel-
Href: "heading", Href: "heading",
Rels: []string{}, Rels: []string{},
External: false, External: false,
Snippet: "Heading with a [link](heading)",
}, },
{ {
Title: "multiple links", Title: "multiple links",
Href: "stripped-formatting", Href: "stripped-formatting",
Rels: []string{}, Rels: []string{},
External: false, External: false,
Snippet: `Paragraph containing [multiple **links**](stripped-formatting), here's one [relative](../other).
A link can have [one relation](one "rel-1") or [several relations](several "rel-1 rel-2").`,
}, },
{ {
Title: "relative", Title: "relative",
Href: "../other", Href: "../other",
Rels: []string{}, Rels: []string{},
External: false, External: false,
Snippet: `Paragraph containing [multiple **links**](stripped-formatting), here's one [relative](../other).
A link can have [one relation](one "rel-1") or [several relations](several "rel-1 rel-2").`,
}, },
{ {
Title: "one relation", Title: "one relation",
Href: "one", Href: "one",
Rels: []string{"rel-1"}, Rels: []string{"rel-1"},
External: false, External: false,
Snippet: `Paragraph containing [multiple **links**](stripped-formatting), here's one [relative](../other).
A link can have [one relation](one "rel-1") or [several relations](several "rel-1 rel-2").`,
}, },
{ {
Title: "several relations", Title: "several relations",
Href: "several", Href: "several",
Rels: []string{"rel-1", "rel-2"}, Rels: []string{"rel-1", "rel-2"},
External: false, External: false,
Snippet: `Paragraph containing [multiple **links**](stripped-formatting), here's one [relative](../other).
A link can have [one relation](one "rel-1") or [several relations](several "rel-1 rel-2").`,
}, },
{ {
Title: "External links", Title: "External links",
Href: "http://example.com", Href: "http://example.com",
Rels: []string{}, Rels: []string{},
External: true, External: true,
Snippet: `[External links](http://example.com) are marked [as such](ftp://domain).`,
}, },
{ {
Title: "as such", Title: "as such",
Href: "ftp://domain", Href: "ftp://domain",
Rels: []string{}, Rels: []string{},
External: true, External: true,
Snippet: `[External links](http://example.com) are marked [as such](ftp://domain).`,
}, },
}) })
} }

@ -85,7 +85,8 @@ func (db *DB) Migrate() error {
title TEXT DEFAULT('') NOT NULL, title TEXT DEFAULT('') NOT NULL,
href TEXT NOT NULL, href TEXT NOT NULL,
external INT DEFAULT(0) NOT NULL, external INT DEFAULT(0) NOT NULL,
rels TEXT DEFAULT('') NOT NULL rels TEXT DEFAULT('') NOT NULL,
snippet TEXT DEFAULT('') NOT NULL
)`, )`,
`CREATE INDEX IF NOT EXISTS index_links_source_id_target_id ON links (source_id, target_id)`, `CREATE INDEX IF NOT EXISTS index_links_source_id_target_id ON links (source_id, target_id)`,

@ -4,6 +4,7 @@
title: "Missing target" title: "Missing target"
href: "missing" href: "missing"
external: false external: false
snippet: "There's a Missing target"
- id: 2 - id: 2
source_id: 1 source_id: 1
@ -11,6 +12,7 @@
title: "An internal link" title: "An internal link"
href: "log/2021-01-04.md" href: "log/2021-01-04.md"
external: false external: false
snippet: "[[An internal link]]"
- id: 3 - id: 3
source_id: 1 source_id: 1
@ -18,6 +20,7 @@
title: "An external link" title: "An external link"
href: "https://domain.com" href: "https://domain.com"
external: true external: true
snippet: "[[An external link]]"
- id: 4 - id: 4
source_id: 4 source_id: 4
@ -25,6 +28,7 @@
title: "Another link" title: "Another link"
href: "log/2021-01-03.md" href: "log/2021-01-03.md"
external: false external: false
snippet: "[[Another link]]"
- id: 5 - id: 5
source_id: 4 source_id: 4
@ -32,3 +36,4 @@
title: "Link from 4 to 6" title: "Link from 4 to 6"
href: "ref/test/a" href: "ref/test/a"
external: false external: false
snippet: "[[Link from 4 to 6]]"

@ -78,8 +78,8 @@ func NewNoteDAO(tx Transaction, logger util.Logger) *NoteDAO {
// Add a new link. // Add a new link.
addLinkStmt: tx.PrepareLazy(` addLinkStmt: tx.PrepareLazy(`
INSERT INTO links (source_id, target_id, title, href, external, rels) INSERT INTO links (source_id, target_id, title, href, external, rels, snippet)
VALUES (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?)
`), `),
// Set links matching a given href and missing a target ID to the given // Set links matching a given href and missing a target ID to the given
@ -203,7 +203,7 @@ func (d *NoteDAO) addLinks(id int64, note note.Metadata) error {
return err return err
} }
_, err = d.addLinkStmt.Exec(id, targetId, link.Title, link.Href, link.External, joinLinkRels(link.Rels)) _, err = d.addLinkStmt.Exec(id, targetId, link.Title, link.Href, link.External, joinLinkRels(link.Rels), link.Snippet)
if err != nil { if err != nil {
return err return err
} }

@ -143,8 +143,9 @@ func TestNoteDAOAddWithLinks(t *testing.T) {
Rels: []string{"rel-1", "rel-2"}, Rels: []string{"rel-1", "rel-2"},
}, },
{ {
Title: "Relative", Title: "Relative",
Href: "f39c8", Href: "f39c8",
Snippet: "[Relative](f39c8) link",
}, },
{ {
Title: "Second is added", Title: "Second is added",
@ -159,6 +160,7 @@ func TestNoteDAOAddWithLinks(t *testing.T) {
Title: "URL", Title: "URL",
Href: "http://example.com", Href: "http://example.com",
External: true, External: true,
Snippet: "External [URL](http://example.com)",
}, },
}, },
}) })
@ -179,6 +181,7 @@ func TestNoteDAOAddWithLinks(t *testing.T) {
Title: "Relative", Title: "Relative",
Href: "f39c8", Href: "f39c8",
Rels: "", Rels: "",
Snippet: "[Relative](f39c8) link",
}, },
{ {
SourceId: id, SourceId: id,
@ -201,6 +204,7 @@ func TestNoteDAOAddWithLinks(t *testing.T) {
Href: "http://example.com", Href: "http://example.com",
External: true, External: true,
Rels: "", Rels: "",
Snippet: "External [URL](http://example.com)",
}, },
}) })
}) })
@ -220,6 +224,7 @@ func TestNoteDAOAddFillsLinksMissingTargetId(t *testing.T) {
TargetId: &id, TargetId: &id,
Title: "Missing target", Title: "Missing target",
Href: "missing", Href: "missing",
Snippet: "There's a Missing target",
}, },
}) })
}) })
@ -282,6 +287,7 @@ func TestNoteDAOUpdateWithLinks(t *testing.T) {
TargetId: intPointer(2), TargetId: intPointer(2),
Title: "An internal link", Title: "An internal link",
Href: "log/2021-01-04.md", Href: "log/2021-01-04.md",
Snippet: "[[An internal link]]",
}, },
{ {
SourceId: 1, SourceId: 1,
@ -289,6 +295,7 @@ func TestNoteDAOUpdateWithLinks(t *testing.T) {
Title: "An external link", Title: "An external link",
Href: "https://domain.com", Href: "https://domain.com",
External: true, External: true,
Snippet: "[[An external link]]",
}, },
}) })
@ -300,11 +307,13 @@ func TestNoteDAOUpdateWithLinks(t *testing.T) {
Href: "index", Href: "index",
External: false, External: false,
Rels: []string{"rel"}, Rels: []string{"rel"},
Snippet: "[[A new link]]",
}, },
{ {
Title: "An external link", Title: "An external link",
Href: "https://domain.com", Href: "https://domain.com",
External: true, External: true,
Snippet: "[[An external link]]",
}, },
}, },
}) })
@ -318,6 +327,7 @@ func TestNoteDAOUpdateWithLinks(t *testing.T) {
Title: "A new link", Title: "A new link",
Href: "index", Href: "index",
Rels: "\x01rel\x01", Rels: "\x01rel\x01",
Snippet: "[[A new link]]",
}, },
{ {
SourceId: 1, SourceId: 1,
@ -325,6 +335,7 @@ func TestNoteDAOUpdateWithLinks(t *testing.T) {
Title: "An external link", Title: "An external link",
Href: "https://domain.com", Href: "https://domain.com",
External: true, External: true,
Snippet: "[[An external link]]",
}, },
}) })
}) })
@ -740,17 +751,17 @@ func queryNoteRow(tx Transaction, where string) (noteRow, error) {
} }
type linkRow struct { type linkRow struct {
SourceId int64 SourceId int64
TargetId *int64 TargetId *int64
Href, Title, Rels string Href, Title, Rels, Snippet string
External bool External bool
} }
func queryLinkRows(t *testing.T, tx Transaction, where string) []linkRow { func queryLinkRows(t *testing.T, tx Transaction, where string) []linkRow {
links := make([]linkRow, 0) links := make([]linkRow, 0)
rows, err := tx.Query(fmt.Sprintf(` rows, err := tx.Query(fmt.Sprintf(`
SELECT source_id, target_id, title, href, external, rels SELECT source_id, target_id, title, href, external, rels, snippet
FROM links FROM links
WHERE %v WHERE %v
ORDER BY id ORDER BY id
@ -759,7 +770,7 @@ func queryLinkRows(t *testing.T, tx Transaction, where string) []linkRow {
for rows.Next() { for rows.Next() {
var row linkRow var row linkRow
err = rows.Scan(&row.SourceId, &row.TargetId, &row.Title, &row.Href, &row.External, &row.Rels) err = rows.Scan(&row.SourceId, &row.TargetId, &row.Title, &row.Href, &row.External, &row.Rels, &row.Snippet)
assert.Nil(t, err) assert.Nil(t, err)
links = append(links, row) links = append(links, row)
} }

@ -20,6 +20,7 @@ type Link struct {
Href string Href string
External bool External bool
Rels []string Rels []string
Snippet string
} }
type Parser interface { type Parser interface {

Loading…
Cancel
Save