Edgewall Software

Changeset 1250

Show
Ignore:
Timestamp:
02/21/2005 09:58:03 PM (3 years ago)
Author:
cmlenz
Message:
  • Add id attributes to headings in wiki pages, so that they can be directly referenced as anchors in the page. Closes #847.
  • Make the links to headings available through the UI when hovering over the heading (using JavaScript).
Location:
trunk
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • trunk/htdocs/css/wiki.css

    r1228 r1250  
    1313#delete { margin-left: 6em } 
    1414#preview { background: #f4f4f4 url(../draft.png); margin: 1em 0 2em } 
     15 
     16/* Heading anchors */ 
     17.anchor:link, .anchor:visited { 
     18 border: none; 
     19 color: #d7d7d7; 
     20 font-size: .8em; 
     21 vertical-align: text-top; 
     22 visibility: hidden; 
     23} 
     24h1:hover .anchor, h2:hover .anchor, h3:hover .anchor, 
     25h4:hover .anchor, h5:hover .anchor, h6:hover .anchor { 
     26 visibility: visible; 
     27} 
    1528 
    1629/* Styles for the page history table 
  • trunk/htdocs/js/trac.js

    r1237 r1250  
    9999  } 
    100100} 
     101 
     102function addHeadingLinks(container) { 
     103  var base = document.location.pathname; 
     104  function addLinks(elems) { 
     105    for (var i = 0; i < elems.length; i++) { 
     106      var hn = elems[i]; 
     107      if (hn.id) { 
     108        var link = document.createElement('a'); 
     109        link.href = base + '#' + hn.id; 
     110        link.className = 'anchor'; 
     111        link.title = "Link to this section"; 
     112        link.appendChild(document.createTextNode(" \u00B6")); 
     113        hn.appendChild(link); 
     114      } 
     115    } 
     116  } 
     117  for (var lvl = 0; lvl <= 6; lvl++) { 
     118    addLinks(container.getElementsByTagName('h' + lvl)); 
     119  } 
     120} 
  • trunk/templates/wiki.cs

    r1228 r1250  
    245245 <?cs /if ?> 
    246246</div> 
     247<script type="text/javascript"> 
     248  addHeadingLinks(document.getElementById("searchable")); 
     249</script> 
    247250 
    248251<?cs include "footer.cs" ?> 
  • trunk/trac/Href.py

    r1233 r1250  
    144144 
    145145    def wiki(self, page=None, version=None, action=None): 
     146        anchor = '' 
     147        if page and page.find("#") != -1: 
     148            anchor = page[page.find('#'):] 
     149            page = page[:page.find('#')] 
    146150        params = [] 
    147151        if page: 
    148             href = href_join(self.base, 'wiki', page) 
     152            href = href_join(self.base, 'wiki', page) + anchor 
    149153        else: 
    150             href = href_join(self.base, 'wiki') 
     154            href = href_join(self.base, 'wiki') + anchor 
    151155        if action: 
    152156            params.append(('action', action)) 
  • trunk/trac/tests/wiki-tests.txt

    r1224 r1250  
    55Another paragraph 
    66------------------------------ 
    7 <h1>Heading 1</h1> 
     7<h1 id="Heading1">Heading 1</h1> 
    88<p> 
    99Paragraph 
     
    132132== Heading with trailing white-space ==  
    133133------------------------------ 
    134 <h2>Heading with trailing white-space</h2> 
     134<h2 id="Headingwithtrailingwhitespace">Heading with trailing white-space</h2> 
    135135============================== 
    136136A0B1, ST62T53C6, IR32V1H000 
  • trunk/trac/WikiFormatter.py

    r1232 r1250  
    4646              r"(?P<reporthref>!?\{\d+\})", 
    4747              r"(?P<modulehref>!?((?P<modulename>bug|ticket|browser|source|repos|report|changeset|wiki|milestone|search):(?P<moduleargs>(&#34;(.*?)&#34;|'(.*?)')|([^ ]*[^'~_\., \)]))))", 
    48               r"(?P<wikihref>!?(^|(?<=[^A-Za-z]))[A-Z][a-z]+(?:[A-Z][a-z]*[a-z/])+(?=\Z|\s|[.,;:!?\)}\]]))", 
     48              r"(?P<wikihref>!?(^|(?<=[^A-Za-z]))[A-Z][a-z]+(?:[A-Z][a-z]*[a-z/])+(?:#[A-Za-z0-9]+)?(?=\Z|\s|[.,;:!?\)}\]]))", 
    4949              r"(?P<fancylink>!?\[(?P<fancyurl>([a-z]+:[^ ]+)) (?P<linkname>.*?)\])"] 
    5050 
     
    157157 
    158158    def _make_wiki_link(self, page, text): 
     159        anchor = '' 
     160        if page.find('#') != -1: 
     161            anchor = page[page.find('#'):] 
     162            page = page[:page.find('#')] 
    159163        if not self.env._wiki_pages.has_key(page): 
    160164            return '<a class="missing wiki" href="%s" rel="nofollow">%s?</a>' \ 
    161                    % (self._href.wiki(page), text) 
     165                   % (self._href.wiki(page + anchor), text) 
    162166        else: 
    163167            return '<a class="wiki" href="%s">%s</a>' \ 
    164                    % (self._href.wiki(page), text) 
     168                   % (self._href.wiki(page + anchor), text) 
    165169 
    166170    def _make_changeset_link(self, rev, text): 
     
    264268    _compiled_rules = re.compile('(?:' + string.join(_rules, '|') + ')') 
    265269    _processor_re = re.compile('#\!([a-zA-Z0-9/+-]+)') 
     270    _anchor_re = re.compile('[^\w\d]+') 
    266271    mime_type = "" 
     272    anchors = [] 
    267273 
    268274    hdf = None 
     
    369375    def _heading_formatter(self, match, fullmatch): 
    370376        match = match.strip() 
    371         depth = min(len(fullmatch.group('hdepth')), 5) 
    372377        self.close_table() 
    373378        self.close_paragraph() 
    374379        self.close_indentation() 
    375380        self.close_list() 
    376         self.out.write('<h%d>%s</h%d>' % (depth, match[depth + 1:len(match) - depth - 1], depth)) 
     381 
     382        depth = min(len(fullmatch.group('hdepth')), 5) 
     383        heading = match[depth + 1:len(match) - depth - 1] 
     384        anchor = anchor_base = self._anchor_re.sub('', heading) 
     385        if anchor[0].isdigit(): 
     386            anchor = '_' + anchor 
     387        i = 1 
     388        while anchor in self.anchors: 
     389            anchor = anchor_base + str(i) 
     390            i += 1 
     391        self.anchors.append(anchor) 
     392        self.out.write('<h%d id="%s">%s</h%d>' % (depth, anchor, heading, depth)) 
    377393        return '' 
    378394