changed git call from https to git readonly
[atutor.git] / mods / wiki / plugins / linking / autolinking.php
1 <?php
2
3 /*
4    Activating this plugin will lead to automagical linking of words in a
5    page, if a corresponding wiki page exists. Tilde or exclamation mark
6    escaping of autolinked words won't be possible.
7
8    This functionality is not fully automatic and requires manuual activation
9    of the helper code in "spages/Admin/PrepareAutolinking" occasionally
10    (which will generate an internal database cache entry). There is commented
11    out code herein, which you could enable to go without the cache thing (but
12    beware that this is slower!).
13    You could also just add an array() listing of words, which you would like
14    to get automatically linked.
15
16    Also you could choose to use the second word replacement code fragment
17    instead of the regex stuff.
18 */
19
20 define("EWIKI_AUTOLINKING_CACHE", "system/tmp/autolinking");
21
22 $ewiki_plugins["format_source"][] = "ewiki_autolinking";
23
24
25 function ewiki_autolinking(&$wiki) {
26
27    #-- get cached list of auto-link pages
28    $cache = ewiki_db::GET(EWIKI_AUTOLINKING_CACHE);
29    if ($cache) {
30       $words = explode("\n", trim($cache["refs"]));
31    }
32
33 /*
34    #-- enable this to go without the cache thingi (much slower this way!)
35    if (empty($words)) {
36       $words = array();
37       $result = ewiki_db::GETALL(array("id", "flags"));
38       while ($row = $result->get()) {
39          if ((EWIKI_DB_F_TEXT == ($row["flags"] && EWIKI_DB_F_TYPE))
40          && !strpos($row["id"], " ") && preg_match('/^.['.EWIKI_CHARS_L.']+$/', $row["id"]) )
41          {
42             $words[] = $row["id"];
43          }
44       }
45    }
46 */
47
48
49 /*
50    #-- or add your list of words which should automatically get linked as pages
51    $words = array_merge((array)$words, array(
52       "start",
53       "office",
54       "...", 
55    ));
56 */
57
58
59 /*
60    #-- actually replace these words with square brackets around them
61    if ($words) {
62
63       if (count($words) >= 50) {
64          $find_regex = "/\b(\w{3,})\b/e";
65          $regex_replace = "(in_array('\\1', \$words) ? '[\\1]' : '\\1')";
66       }
67       else {
68          $find_regex = "/\b(" . (implode("|", $words)) . ")\b/";
69          $regex_replace = "[\\1]";
70       }
71
72       $wiki = preg_replace($find_regex, $regex_replace, $wiki);
73    }
74 */ 
75
76
77    #-- faster(???) simple string functions based replacing;
78    #   (this is not exactly matching, but still better than the above
79    #   regex approach)
80    if ($words) {
81       foreach ($words as $word) {
82
83          $max = strlen($wiki);
84          $l = 0;
85          while ((($l = strpos($wiki, $word, $l)) !== false) && ($l < $max) ) {
86
87             #-- check if the word stands alone (no letters before or after)
88             $r = $l + strlen($word);
89             if (  ($l >= 1) && ($c = ord($wiki[$l-1])) && ($c >= 64) && ($c <= 122)
90               || ($max>=$r) && ($c = ord($wiki[$r])) && ($c >= 64) && ($c <= 122) )
91             {
92                $l = $r + 3;
93                continue;
94             }
95
96             #-- guess if the word is enclosed in square brackets
97             if ( (($close_sq = strpos($wiki, "]", $l)) === false) 
98             || (($open_sq = strpos($wiki, "[", $l)) !== false) && ($open_sq <= $close_sq)
99             || (($line_end = strpos($wiki, "\n", $l)) !== false) && ($line_end <= $close_sq))
100             {
101                $wiki = substr($wiki, 0, $l)
102                      . "[$word]"
103                      . substr($wiki, $l + strlen($word));
104             }
105
106             $l = $r + 3;  // skip, so we won't end up in a loop
107          }
108       }
109    }
110
111
112 }
113
114
115 ?>