File: _xref.tcl

package info (click to toggle)
tcllib 2.0%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 83,560 kB
  • sloc: tcl: 306,798; ansic: 14,272; sh: 3,035; xml: 1,766; yacc: 1,157; pascal: 881; makefile: 124; perl: 84; f90: 84; python: 33; ruby: 13; php: 11
file content (129 lines) | stat: -rw-r--r-- 2,939 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# -*- tcl -*-
##
# Shared code for the management of cross-references between
# documents. Origin in HTML. Other user: Markdown.
#
# Copyright (c) 2001,2019 Andreas Kupries <andreas_kupries@sourceforge.net>

# Hook:
# - MakeLink {label target} - Format specific
# - GetXref                 - Engine parameter access

# # ## ### ##### ######## ############# #####################
## API

proc XrefInit {} {
    global xref
    foreach item [GetXref] {
	foreach {pattern fname fragment} $item break
	set fname_ref [dt_fmap $fname]
	if {$fragment != {}} {append fname_ref #$fragment}
	set xref($pattern) $fname_ref
    }
    proc XrefInit {} {}
    return
}

proc XrefMatch {word args} {
    global xref

    foreach ext $args {
	if {$ext != {}} {
	    if {[info exists xref($ext,$word)]} {
		return [XrefLink $xref($ext,$word) $word]
	    }
	}
    }
    if {[info exists xref($word)]} {
	return [XrefLink $xref($word) $word]
    }

    # Convert the word to all-lower case and then try again.

    set lword [string tolower $word]

    foreach ext $args {
	if {$ext != {}} {
	    if {[info exists xref($ext,$lword)]} {
		return [XrefLink $xref($ext,$lword) $word]
	    }
	}
    }
    if {[info exists xref($lword)]} {
	return [XrefLink $xref($lword) $word]
    }

    return $word
}

proc XrefList {list {ext {}}} {
    set res [list]
    foreach w $list {lappend res [XrefMatch $w $ext]}
    return $res
}

proc XrefLink {dest label} {
    # Ensure that the link is properly done relative to this file!

    set here [LinkHere]
    set dest [LinkTo $dest $here]

    if {[string equal $dest [lindex [file split $here] end]]} {
	# Suppress self-referential links, i.e. links made from the
	# current file to itself. Note that links to specific parts of
	# the current file are not suppressed, only exact links.
	return $label
    }
    return [MakeLink $label $dest]
}

# # ## ### ##### ######## ############# #####################
## Internals

proc LinkHere {} {
    return [dt_fmap [dt_mainfile]]
}

proc LinkTo {dest here} {
    # Ensure that the link is properly done relative to this file!

    set save $dest

    #puts_stderr "XrefLink $dest $label"

    set here [file split $here]
    set dest [file split $dest]

    #puts_stderr "XrefLink < $here"
    #puts_stderr "XrefLink > $dest"

    while {[string equal [lindex $dest 0] [lindex $here 0]]} {
	set dest [lrange $dest 1 end]
	set here [lrange $here 1 end]
	if {[llength $dest] == 0} {break}
    }
    set ul [llength $dest]
    set hl [llength $here]

    if {$ul == 0} {
	set dest [lindex [file split $save] end]
    } else {
	while {$hl > 1} {
	    set dest [linsert $dest 0 ..]
	    incr hl -1
	}
	set dest [eval file join $dest]
    }

    #puts_stderr "XrefLink --> $dest"
    return $dest
}

# # ## ### ##### ######## ############# #####################
## State

global xref ; array set xref {}

##
# # ## ### ##### ######## ############# #####################
return