Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 17 additions & 10 deletions gemaraconv/markdown/lexicon_link.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ func lexiconIsWrapped(text, matched string) bool {
return openBrackets > closeBrackets
}

func addLexiconLinksForTerm(lexicon []lexiconEntry, text, term string) string {
func addLexiconLinksForTerm(lexicon []lexiconEntry, text, term string) (string, error) {
escapedTerm := regexp.QuoteMeta(term)
termRegex := regexp.MustCompile(`(?i)\b` + escapedTerm + `(?:s)?\b`)

termIdx := slices.IndexFunc(lexicon, func(entry lexiconEntry) bool {
return containsLexiconSynonym(entry.Synonyms, entry.Canonical, term)
})
if termIdx == -1 {
panic(fmt.Sprintf("markdown: addLexiconLinksForTerm called for unknown term %q", term))
return "", fmt.Errorf("markdown: cannot link unknown lexicon term %q", term)
}
canonical := lexicon[termIdx].Canonical

Expand All @@ -49,25 +49,32 @@ func addLexiconLinksForTerm(lexicon []lexiconEntry, text, term string) string {
return matched
}
return fmt.Sprintf("[%s][%s]", matched, canonical)
})
}), nil
}

// addLexiconLinks applies baseline-style reference autolinks for every canonical term and synonym.
func addLexiconLinks(lexicon []lexiconEntry, text string) string {
func addLexiconLinks(lexicon []lexiconEntry, text string) (string, error) {
for _, entry := range lexicon {
text = addLexiconLinksForTerm(lexicon, text, entry.Canonical)
var err error
text, err = addLexiconLinksForTerm(lexicon, text, entry.Canonical)
if err != nil {
return "", err
}
for _, syn := range entry.Synonyms {
text = addLexiconLinksForTerm(lexicon, text, syn)
text, err = addLexiconLinksForTerm(lexicon, text, syn)
if err != nil {
return "", err
}
}
}
return text
return text, nil
}

func newLexiconLinker(entries []lexiconEntry) func(string) string {
func newLexiconLinker(entries []lexiconEntry) func(string) (string, error) {
if len(entries) == 0 {
return func(plain string) string { return plain }
return func(plain string) (string, error) { return plain, nil }
}
return func(text string) string {
return func(text string) (string, error) {
return addLexiconLinks(entries, text)
}
}
Expand Down
18 changes: 14 additions & 4 deletions gemaraconv/markdown/lexicon_link_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,39 @@ func TestAddLexiconLinks_basic(t *testing.T) {
Refs: nil,
},
}
out := addLexiconLinks(sampleLexicon, "Use Example Term and ET in prose.")
out, err := addLexiconLinks(sampleLexicon, "Use Example Term and ET in prose.")
require.NoError(t, err)
assert.Contains(t, out, "[Example Term][Example Term]")
assert.Contains(t, out, "[ET][Example Term]")
}

func TestAddLexiconLinks_pluralAndCase(t *testing.T) {
sampleLexicon := []lexiconEntry{{Canonical: "Widget", Definition: "d"}}
out := addLexiconLinks(sampleLexicon, "Many widgets here.")
out, err := addLexiconLinks(sampleLexicon, "Many widgets here.")
require.NoError(t, err)
assert.Contains(t, out, "[widgets][Widget]")
}

func TestAddLexiconLinks_skipsInsideBrackets(t *testing.T) {
sampleLexicon := []lexiconEntry{{Canonical: "Term", Definition: "d"}}
out := addLexiconLinks(sampleLexicon, "already [Term] linked")
out, err := addLexiconLinks(sampleLexicon, "already [Term] linked")
require.NoError(t, err)
assert.Equal(t, "already [Term] linked", out)
}

func TestAddLexiconLinksForTerm_unknownTerm(t *testing.T) {
_, err := addLexiconLinksForTerm(nil, "plain", "missing")
require.EqualError(t, err, `markdown: cannot link unknown lexicon term "missing"`)
}

func TestLexiconRefSlug(t *testing.T) {
assert.Equal(t, "#example-term", lexiconRefSlug("Example Term"))
assert.Equal(t, "#ab", lexiconRefSlug("a.b"))
}

func TestNewLexiconLinker_noop(t *testing.T) {
linkFunc := newLexiconLinker(nil)
require.Equal(t, "plain", linkFunc("plain"))
out, err := linkFunc("plain")
require.NoError(t, err)
require.Equal(t, "plain", out)
}
2 changes: 1 addition & 1 deletion gemaraconv/markdown/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func collapseExtraNewlines(s string) string {
return s
}

func markdownFuncMap(lexiconLink func(string) string) template.FuncMap {
func markdownFuncMap(lexiconLink func(string) (string, error)) template.FuncMap {
return template.FuncMap{
"lexiconLink": lexiconLink,
"anchor": Anchor,
Expand Down
2 changes: 1 addition & 1 deletion gemaraconv/markdown/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ func TestCatalogToMarkdown_inlineLexiconNormalizeError(t *testing.T) {
}

func TestMarkdownFuncMap_joinArtifactEntriesEmpty(t *testing.T) {
fn := markdownFuncMap(func(s string) string { return s })
fn := markdownFuncMap(func(s string) (string, error) { return s, nil })
join := fn["joinArtifactEntries"].(func([]gemara.ArtifactMapping, string) string)
assert.Equal(t, "", join(nil, " · "))
assert.Equal(t, "", join([]gemara.ArtifactMapping{}, " · "))
Expand Down
Loading