| 1 | """ |
|---|
| 2 | Inserts a link for the parent-tree of the current page. |
|---|
| 3 | |
|---|
| 4 | This only applies to pages with a forward-slash (/) in their name. |
|---|
| 5 | If there is no forward-slash present, the macro defaults to displaying |
|---|
| 6 | the name of the current page (with no href tag). |
|---|
| 7 | |
|---|
| 8 | e.g.: an entry named Top/Middle/Bottom would result in the following |
|---|
| 9 | psuedo-HTML output: |
|---|
| 10 | |
|---|
| 11 | <a href='site/wiki/Top'>Top</a> - |
|---|
| 12 | <a href='site/wiki/Top/Middle'>Middle</a> - |
|---|
| 13 | Bottom |
|---|
| 14 | |
|---|
| 15 | Only one argument is allowd. The argument is a string of equal signs |
|---|
| 16 | indicating the value of the wiki header to simulate. For instance, |
|---|
| 17 | given [[ParentLinkage(=)]], the entire linkage output would be wrapped |
|---|
| 18 | in an <h1> heading tag with the appropriate ID attribute set. Thus, |
|---|
| 19 | given the above page name of Top/Middle/Bottom, the result would be |
|---|
| 20 | something like this: |
|---|
| 21 | |
|---|
| 22 | <h1 id='Top-Middle-Bottom'> |
|---|
| 23 | <a href='site/wiki/Top'>Top</a> - |
|---|
| 24 | <a href='site/wiki/Top/Middle'>Middle</a> - |
|---|
| 25 | Bottom |
|---|
| 26 | </h1> |
|---|
| 27 | |
|---|
| 28 | Up to four equal signs may be present. |
|---|
| 29 | |
|---|
| 30 | Written by: Kevin C. Krinke <kevin@krinke.ca> |
|---|
| 31 | Inspired by (and based on) the ParentLink macro. |
|---|
| 32 | """ |
|---|
| 33 | |
|---|
| 34 | import re |
|---|
| 35 | from StringIO import StringIO |
|---|
| 36 | |
|---|
| 37 | def split_camel_case(string): |
|---|
| 38 | result = string |
|---|
| 39 | #: let's break up "ThisThat" into "This That" |
|---|
| 40 | while re.search( '([A-Z]+[a-z]+)([A-Z]+)', result ): |
|---|
| 41 | result = re.sub( r'([A-Z]+[a-z]+)([A-Z]+)', r'\1 \2', result ) |
|---|
| 42 | #: let's break up "UIExamples" into "UI Examples" |
|---|
| 43 | while re.search( '([A-Z]+[A-Z][a-z]+)', result ): |
|---|
| 44 | result = re.sub( r'([A-Z]+)([A-Z][a-z]+)', r'\1 \2', result ) |
|---|
| 45 | #: let's fix "And" to read "and" |
|---|
| 46 | while re.search( ' And ', result ): |
|---|
| 47 | result = re.sub( ' And ', ' and ', result ) |
|---|
| 48 | #: let's fix "Of" to read "of" |
|---|
| 49 | while re.search( ' Of ', result ): |
|---|
| 50 | result = re.sub( ' Of ', ' of ', result ) |
|---|
| 51 | return result |
|---|
| 52 | |
|---|
| 53 | def execute(hdf, args, env): |
|---|
| 54 | db = env.get_db_cnx() |
|---|
| 55 | cursor = db.cursor() |
|---|
| 56 | |
|---|
| 57 | buf = StringIO() |
|---|
| 58 | |
|---|
| 59 | pg_name = hdf.getValue('wiki.page_name', '') |
|---|
| 60 | |
|---|
| 61 | h_id = '' |
|---|
| 62 | h_num = 0 |
|---|
| 63 | if args: |
|---|
| 64 | eqs = re.search( '^(\=+)$', args[0] ).group( 1 ) |
|---|
| 65 | if eqs: |
|---|
| 66 | h_id = re.sub( '/', '-', pg_name ) |
|---|
| 67 | h_num = len( eqs ) |
|---|
| 68 | if h_num > 4: |
|---|
| 69 | h_num = 4 #: cap at <h4> |
|---|
| 70 | buf.write( '<h%d id="%s">' % ( h_num, h_id ) ) |
|---|
| 71 | |
|---|
| 72 | match = re.findall( "([^/]+)/", pg_name ) |
|---|
| 73 | if len( match ): |
|---|
| 74 | build = "" |
|---|
| 75 | for i in range( len( match ) ): |
|---|
| 76 | s = match[i] |
|---|
| 77 | if len( build ): |
|---|
| 78 | build = build + "/" + s |
|---|
| 79 | else: |
|---|
| 80 | build = s |
|---|
| 81 | buf.write( '<a class="wiki" href="%s">' % env.href.wiki( build ) ) |
|---|
| 82 | buf.write( split_camel_case( s ) ) |
|---|
| 83 | buf.write( "</a> - " ) |
|---|
| 84 | |
|---|
| 85 | last = re.search( "/([^/]+)$", pg_name ).group( 1 ) |
|---|
| 86 | last = split_camel_case( last ) |
|---|
| 87 | buf.write( last ) |
|---|
| 88 | else: |
|---|
| 89 | buf.write( split_camel_case( pg_name ) ) |
|---|
| 90 | |
|---|
| 91 | if h_num: |
|---|
| 92 | buf.write( '</h%d>' % h_num ) |
|---|
| 93 | |
|---|
| 94 | return buf.getvalue() |
|---|