1- import { EditorPosition , Plugin } from "obsidian" ;
1+ import { EditorPosition , ListItemCache , Plugin , SectionCache } from "obsidian" ;
22
33function generateId ( ) : string {
44 return Math . random ( ) . toString ( 36 ) . substr ( 2 , 6 ) ;
55}
66
7- const isHeadingRegEx = / ^ # { 1 , 6 } \s + [ ^ \s ] / ;
8- const blockIdRegEx = / \s \^ ( [ ^ \s ] + ) $ / ;
9-
10- // https://help.obsidian.md/How+to/Link+to+blocks
7+ function shouldInsertAfter ( block : ListItemCache | SectionCache ) {
8+ if ( ( block as any ) . type ) {
9+ return [
10+ "blockquote" ,
11+ "code" ,
12+ "table" ,
13+ "comment" ,
14+ "footnoteDefinition" ,
15+ ] . includes ( ( block as SectionCache ) . type ) ;
16+ }
17+ }
1118
1219export default class MyPlugin extends Plugin {
1320 async onload ( ) {
1421 this . registerEvent (
1522 this . app . workspace . on ( "editor-menu" , ( menu , editor , view ) => {
1623 const cursor = editor . getCursor ( "to" ) ;
17- const line = editor . getLine ( cursor . line ) ;
18- const basename = view . file . basename ;
24+ const fileCache = this . app . metadataCache . getFileCache ( view . file ) ;
1925
20- const isHeading = isHeadingRegEx . test ( line ) ;
26+ let blockCache : ListItemCache | SectionCache = (
27+ fileCache ?. sections || [ ]
28+ ) . find ( ( section ) => {
29+ return (
30+ section . position . start . line <= cursor . line &&
31+ section . position . end . line >= cursor . line
32+ ) ;
33+ } ) ;
34+
35+ if ( ! blockCache ) return ;
36+
37+ if ( blockCache . type === "list" ) {
38+ blockCache = ( fileCache ?. listItems || [ ] ) . find ( ( item ) => {
39+ return (
40+ item . position . start . line <= cursor . line &&
41+ item . position . end . line >= cursor . line
42+ ) ;
43+ } ) ;
44+ }
45+
46+ const isHeading = ( blockCache as any ) . type === "heading" ;
2147
2248 const onClick = ( isEmbed : boolean ) => {
2349 // Copy heading
2450 if ( isHeading ) {
25- return navigator . clipboard . writeText (
26- `${ isEmbed ? "!" : "" } [[${ basename } #${ line . replace (
27- / ^ # + \s / ,
28- ""
29- ) } ]]`
51+ const heading = fileCache . headings . find ( ( heading ) => {
52+ return (
53+ heading . position . start . line === blockCache . position . start . line
54+ ) ;
55+ } ) ;
56+
57+ return (
58+ heading &&
59+ navigator . clipboard . writeText (
60+ `${
61+ isEmbed ? "!" : ""
62+ } ${ this . app . fileManager . generateMarkdownLink (
63+ view . file ,
64+ "" ,
65+ "#" + heading . heading
66+ ) } `
67+ )
3068 ) ;
3169 }
3270
33- const match = line . match ( blockIdRegEx ) ;
71+ const blockId = blockCache . id ;
3472
3573 // Copy existing block id
36- if ( match ) {
74+ if ( blockId ) {
3775 return navigator . clipboard . writeText (
38- `${ isEmbed ? "!" : "" } [[${ basename } #^${ match [ 1 ] } ]]`
76+ `${ isEmbed ? "!" : "" } ${ this . app . fileManager . generateMarkdownLink (
77+ view . file ,
78+ "" ,
79+ "#^" + blockId
80+ ) } `
3981 ) ;
4082 }
4183
4284 // Add a block id
85+ const sectionEnd = blockCache . position . end ;
4386 const end : EditorPosition = {
44- line : cursor . line ,
45- ch : line . length ,
87+ ch : sectionEnd . col ,
88+ line : sectionEnd . line ,
4689 } ;
4790
4891 const id = generateId ( ) ;
49- const isBlockquote = / ^ \s * > + ./ . test ( line ) ;
50-
51- // TODO: better handle blockquotes and codeblocks
92+ const spacer = shouldInsertAfter ( blockCache ) ? "\n\n" : " " ;
5293
53- editor . replaceRange (
54- `${ isBlockquote ? "\n\n" : " " } ^${ id } ${ isBlockquote ? "\n" : "" } ` ,
55- end
56- ) ;
94+ editor . replaceRange ( `${ spacer } ^${ id } ` , end ) ;
5795 navigator . clipboard . writeText (
58- `${ isEmbed ? "!" : "" } [[${ basename } #^${ id } ]]`
96+ `${ isEmbed ? "!" : "" } ${ this . app . fileManager . generateMarkdownLink (
97+ view . file ,
98+ "" ,
99+ "#^" + id
100+ ) } `
59101 ) ;
60102 } ;
61103
@@ -68,11 +110,7 @@ export default class MyPlugin extends Plugin {
68110
69111 menu . addItem ( ( item ) => {
70112 item
71- . setTitle (
72- isHeading
73- ? "Copy heading embed"
74- : "Copy block embed"
75- )
113+ . setTitle ( isHeading ? "Copy heading embed" : "Copy block embed" )
76114 . setIcon ( "links-coming-in" )
77115 . onClick ( ( ) => onClick ( true ) ) ;
78116 } ) ;
0 commit comments