File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -6,6 +6,7 @@ open Marksman.Syms
66
77type Heading = {
88 level: int
9+ isTitle: bool
910 text: string
1011 id: Slug
1112} with
@@ -111,14 +112,13 @@ module Element =
111112 // TODO: instead of checking for 'all whitespace' symbols all the time, create smart constructors
112113 let toSym ( parserSettings : Config.ParserSettings ) ( el : Element ) : option < Sym > =
113114 match el with
114- | Element.H { level = level; id = id } ->
115+ | Element.H { level = level; isTitle = isTitle ; id = id } ->
115116 if Slug.isEmpty id then
116117 None
117118 else
118119 let id = Slug.toString id
119120
120- // TODO: make this configurable
121- if level <= 1 then
121+ if isTitle then
122122 Syms.Sym.Def( Title( id)) |> Some
123123 else
124124 Syms.Sym.Def( Header( level, id)) |> Some
Original file line number Diff line number Diff line change @@ -252,7 +252,7 @@ type Element =
252252 | T n -> n.range
253253 | YML n -> n.range
254254
255- and Heading = { level: int ; title: TextNode ; scope: Range }
255+ and Heading = { level: int ; isTitle : bool ; title: TextNode ; scope: Range }
256256
257257let rec private fmtElement =
258258 function
@@ -298,14 +298,15 @@ module Heading =
298298
299299 let slug ( heading : Heading ) : Slug = name heading |> Slug.ofString
300300
301- let isTitle ( heading : Heading ) = heading.level <= 1
301+ let isTitle ( heading : Heading ) = heading.isTitle
302302
303303 let range ( heading : Heading ) : Range = heading.title.range
304304
305305 let scope ( heading : Heading ) : Range = heading.scope
306306
307307 let toAbstract ( cHead : Heading ) : Ast.Heading = {
308308 level = cHead.level
309+ isTitle = cHead.isTitle
309310 text = cHead.title.text
310311 id = slug cHead
311312 }
Original file line number Diff line number Diff line change @@ -7,6 +7,7 @@ open Marksman.Misc
77
88type Dictionary < 'K , 'V > = System.Collections.Generic.Dictionary< 'K, 'V>
99
10+ // TODO: get rid of this; use Structure directly
1011type Index = {
1112 titles: array < Node < Heading >>
1213 headings: array < Node < Heading >>
Original file line number Diff line number Diff line change @@ -5,6 +5,7 @@ open System.Collections.Generic
55open Ionide.LanguageServerProtocol .Types
66open Markdig.Syntax
77
8+ open Marksman.Config
89open Marksman.Misc
910open Marksman.Names
1011open Marksman.Text
@@ -216,7 +217,7 @@ module Markdown =
216217 }
217218
218219
219- let scrapeText ( text : Text ) : array < Element > =
220+ let scrapeText ( parserSettings : ParserSettings ) ( text : Text ) : array < Element > =
220221 let parsed : MarkdownObject = Markdown.Parse( text.content, markdigPipeline)
221222
222223 let elements = ResizeArray()
@@ -250,6 +251,7 @@ module Markdown =
250251 let heading =
251252 Node.mk fullText range {
252253 level = level
254+ isTitle = parserSettings.titleFromHeading && level <= 1
253255 title = Node.mkText title titleRange
254256 scope = range
255257 }
@@ -476,11 +478,11 @@ module Markdown =
476478
477479 { elements = elements; childMap = childMap }
478480
479- let parse ( parserSettings : Config. ParserSettings) ( text : Text ) : Structure =
481+ let parse ( parserSettings : ParserSettings ) ( text : Text ) : Structure =
480482 if String.IsNullOrEmpty text.content then
481483 let cst : Cst.Cst = { elements = [||]; childMap = Map.empty }
482484 Structure.ofCst parserSettings cst
483485 else
484- let flatElements = Markdown.scrapeText text
486+ let flatElements = Markdown.scrapeText parserSettings text
485487 let cst = Markdown.buildCst text flatElements
486488 Structure.ofCst parserSettings cst
Original file line number Diff line number Diff line change 11module Marksman.AstTests
22
3+ open Marksman.Config
34open Xunit
45open Snapper
56
@@ -62,3 +63,51 @@ let testAstLookup () =
6263
6364 let madeUpAbstract = Element.MR( Collapsed " WAT" )
6465 Assert.Equal( Structure.tryFindConcreteForAbstract madeUpAbstract struct1, None)
66+
67+ [<Fact>]
68+ let testSymsWhenTitleFromHeadingIsOff () =
69+ let doc =
70+ """
71+ # H1
72+ Is this a title?
73+ # H2
74+ Is this another title?
75+ ## H2.2
76+ # H3
77+ And this?
78+ """
79+
80+ let strukt =
81+ Parser.parse { ParserSettings.Default with titleFromHeading = false } ( Text.mkText doc)
82+
83+ Helpers.checkInlineSnapshot _. ToString() strukt.Symbols [
84+ " Doc"
85+ " H1 {h1}"
86+ " H1 {h2}"
87+ " H1 {h3}"
88+ " H2 {h22}"
89+ ]
90+
91+ [<Fact>]
92+ let testSymsWhenTitleFromHeadingIsOn () =
93+ let doc =
94+ """
95+ # H1
96+ Is this a title?
97+ # H2
98+ Is this another title?
99+ ## H2.2
100+ # H3
101+ And this?
102+ """
103+
104+ let strukt =
105+ Parser.parse { ParserSettings.Default with titleFromHeading = true } ( Text.mkText doc)
106+
107+ Helpers.checkInlineSnapshot _. ToString() strukt.Symbols [
108+ " Doc"
109+ " T {h1}"
110+ " T {h2}"
111+ " T {h3}"
112+ " H2 {h22}"
113+ ]
Original file line number Diff line number Diff line change 11module Marksman.ConnTest
22
3+ open Marksman.Config
34open Xunit
45
56open Snapper
@@ -363,3 +364,35 @@ module ConnGraphTests =
363364 let d2 = FakeDoc.Mk( path = " d2.md" , contentLines = [| " #tag2" ; " #tag3" |])
364365 let f ' = mkFolder [ d1; d2 ] |> Folder.withDoc d1'
365366 checkSnapshot ( Folder.conn f')
367+
368+ [<StoreSnapshotsPerClass>]
369+ module ConnGraphTests_TitleLess =
370+ let incrConfig = {
371+ Config.Config.Default with
372+ coreIncrementalReferences = Some true
373+ coreTitleFromHeading = Some false
374+ complWikiStyle = Some ComplWikiStyle.TitleSlug
375+ }
376+
377+ let mkFolder docs = FakeFolder.Mk( config = incrConfig, docs = docs)
378+ let mkDoc path content = FakeDoc.Mk( path = path, config = incrConfig, contentLines = content)
379+
380+ [<Fact>]
381+ let updateH1 () =
382+ let d1 =
383+ mkDoc " ocaml.md" [| " # OCaml" ; " [[#Multicore]]" ; " ## Multicore" |]
384+
385+ let d1 ' =
386+ mkDoc " ocaml.md" [| " # OCaml L" ; " [[#Multicore]]" ; " ## Multicore" |]
387+
388+ let d2 = mkDoc " test.md" [| " # Test" ; " [[OCaml#Multicore]]" |]
389+
390+ let incr =
391+ mkFolder [ d1 ]
392+ |> Folder.withDoc d2
393+ |> Folder.withDoc d1'
394+ |> Folder.conn
395+
396+ let fromScratch = mkFolder [ d1'; d2 ] |> Folder.conn
397+ let connDiff = Conn.difference fromScratch incr
398+ checkInlineSnapshot id [ connDiff.CompactFormat() ] [ " " ]
Original file line number Diff line number Diff line change 11module Marksman.Helpers
22
33open System.Runtime .InteropServices
4+ open Marksman.Config
45open Snapper
56open Marksman.Misc
67open Marksman.Paths
@@ -53,21 +54,22 @@ let stripMarginTrim (str: string) = stripMargin (str.Trim())
5354
5455type FakeDoc =
5556 class
56- static member Mk ( content : string , ? path : string , ? root : string ) : Doc =
57+ static member Mk ( content : string , ? path : string , ? root : string , ? config : Config ) : Doc =
5758 let text = Text.mkText content
5859 let path = defaultArg path " fake.md"
5960 let pathUri = pathToUri ( dummyRootPath ( pathComps path))
6061 let root = Option.map pathComps root |> Option.defaultValue []
6162 let rootUri = dummyRootPath root |> pathToUri
63+ let config = defaultArg config Config.Default
6264
6365 let docId =
6466 DocId( UriWith.mkRooted ( UriWith.mkRoot rootUri) ( LocalPath.ofUri pathUri))
6567
66- Doc.mk Config. ParserSettings.Default docId None text
68+ Doc.mk ( ParserSettings.OfConfig ( config )) docId None text
6769
68- static member Mk ( contentLines : array < string >, ? path : string ) : Doc =
70+ static member Mk ( contentLines : array < string >, ? path : string , ? config : Config ) : Doc =
6971 let content = String.concat System.Environment.NewLine contentLines
70- FakeDoc.Mk( content, ?path = path)
72+ FakeDoc.Mk( content, ?path = path, ?config = config )
7173 end
7274
7375type FakeFolder =
Original file line number Diff line number Diff line change @@ -2,6 +2,7 @@ module Marksman.RefsTests
22
33open Ionide.LanguageServerProtocol .Types
44open System.IO
5+ open Marksman.Config
56open Xunit
67
78open Marksman.Cst
@@ -574,6 +575,39 @@ module EncodingTests =
574575 let refs = resolveAtPos doc1 14 5
575576 checkInlineSnapshot ( fun x -> x.ToString()) refs [ " doc.3.with.dots" ]
576577
578+ // Cases where title_from_heading = false
579+ module TitleLess =
580+ [<Fact>]
581+ let refToH1 () =
582+ let baseConfig = {
583+ Config.Config.Default with
584+ complWikiStyle = Some ComplWikiStyle.TitleSlug
585+ }
586+
587+ let mkFolder config =
588+ let d1 =
589+ FakeDoc.Mk( path = " d1.md" , config = config, contentLines = [| " # Doc1" |])
590+
591+ let d2 =
592+ // 012345
593+ FakeDoc.Mk( path = " d2.md" , config = config, contentLines = [| " [[Doc1]]" |])
594+
595+ let folder = FakeFolder.Mk([ d1; d2 ], config = config)
596+ d1, d2, folder
597+
598+ // In title-less mode headings are not referenceable cross-doc
599+ let _ , d2 , folder =
600+ mkFolder { baseConfig with coreTitleFromHeading = Some false }
601+
602+ let el = requireElementAtPos d2 0 2
603+ Assert.Empty( Dest.tryResolveElement folder d2 el)
604+
605+ // In title-full mode headings *are* referenceable cross-doc
606+ let _ , d2 , folder =
607+ mkFolder { baseConfig with coreTitleFromHeading = Some true }
608+
609+ Assert.NotEmpty( Dest.tryResolveElement folder d2 el)
610+
577611module RegressionTests =
578612 [<Fact>]
579613 let rootLink_issue275 () =
You can’t perform that action at this time.
0 commit comments