Initial commit
[mkdrusampletheme.git] / pz2urlrecipe.js
1 var pz2urlrecipe = (function() {
2   var choose_url = function (data, proxyPattern) {
3     //first try to prepare local_url from recipe
4     var local_url = data["md-url_recipe"] !== undefined
5         ? prepare_url(data["md-url_recipe"][0], data) : null;
6
7     var use_url_proxy = data["md-use_url_proxy"] !== undefined
8         ? data["md-use_url_proxy"] : "0";
9
10     //use the proxyPattern
11     if (proxyPattern && use_url_proxy == "1") {        
12         if (local_url) {
13             data["md-local-url"] = [];
14             data["md-local-url"].push(local_url);
15         }
16         var ref_local_url = prepare_url(proxyPattern, data);
17         if (ref_local_url) return ref_local_url;
18     }
19
20     // proxyPattern failed, go for local
21     if (local_url)
22         return local_url;
23
24     //local failed, go for resource
25     return data["md-electronic-url"] !== undefined
26         ? data["md-electronic-url"][0] : null;
27   }
28
29   var XRef = function (url, text) {  
30     this.url = url;
31     this.text = text;  
32   };
33
34   var has_recipe = function (data) {
35     var has = false;
36     if (data["md-url_recipe"] !== undefined) {
37        var recipe = data["md-url_recipe"][0];
38        if (typeof recipe == "string" && recipe.length>0) {
39          has = true;
40        }
41     }
42     return has;
43   }
44
45   var getUrlFromRecipe = function (data) {
46     if (has_recipe(data)) {
47       return prepare_url(data["md-url_recipe"][0],data);
48     } else {
49       return null;
50     }  
51   }
52
53   var getElectronicUrls = function (data) {
54     var urls = [];
55     if (data["md-electronic-url"] !== undefined) {
56       for (var i=0; i<data["md-electronic-url"].length; i++) {
57         var linkUrl = data["md-electronic-url"][i];
58         var linkText = (data["md-electronic-text"]) ? data["md-electronic-text"][i] : "Web Link";
59         var ref = new XRef(linkUrl, (linkText.length==0 ? "Web Link" : linkText));
60         urls.push(ref);
61       }
62     }
63     return urls;
64   }
65
66
67   // Prepares urls from recipes with expressions in the form:
68   // ${variable-name[pattern/replacement/mode]}, [regex] is optional
69   // eg. http://sever.com?title=${md-title[\s+//]} will strip all whitespaces 
70   var prepare_url = function (url_recipe, meta_data) {
71     if (typeof url_recipe != "string" || url_recipe.length == 0)
72         return null;
73     if (typeof meta_data != "object")
74         return null;
75     try {
76         var result =  url_recipe.replace(/\${[^}]*}/g, function (match) { 
77           return get_var_value(match, meta_data);
78           }
79         );
80         //url encoding for %{} vars
81         result =  result.replace(/\%{[^}]*}/g, function (match) { 
82           return encodeURIComponent(get_var_value(match, meta_data));
83           }
84         );
85         return result;
86     } catch (e) {
87         return "Malformed URL recipe: " + e.message;
88     }
89   }
90
91   var get_var_value = function (expr_in, meta_data) {
92     //strip ${ and }
93     var expr = expr_in.substring(2, expr_in.length-1)
94     if (expr == "") return "";
95     //extract name
96     var var_name = expr.match(/^[^\[]+/)[0];
97     if (typeof meta_data[var_name] == "undefined") return "";
98     else var var_value = meta_data[var_name][0];
99     if (var_name.length < expr.length) { //possibly a regex
100        var_value = exec_sregex(
101           expr.substring(var_name.length+1, expr.length-1),
102           var_value);
103     }
104     return var_value;
105   }
106
107   // exec perl-like substitution regexes in the form: pattern/replacement/mode
108   var exec_sregex = function (regex_str, input_str) {   
109     var regex_parts = ["", "", ""];
110     var i = 0;
111     for (var j=0; j<regex_str.length && i<3; j++) {
112       if (j>0 && regex_str.charAt(j) == '/' && regex_str.charAt(j-1) != '\\')
113         i++;
114       else
115         regex_parts[i] += regex_str.charAt(j);
116     }
117     var regex_obj = new RegExp(regex_parts[0], regex_parts[2]);
118     return input_str.replace(regex_obj, regex_parts[1]);    
119   }
120
121   var test_url_recipe = function () {
122     var url_recipe = "http://www.indexdata.com/?title=${md-title[\\s+/+/g]}&author=${md-author}";
123     var meta_data = { "md-title" : ["Art of Computer Programming"], "md-author" : ["Knuth"]}
124     var final_url = prepare_url(url_recipe, meta_data);
125     alert(final_url);
126   }
127
128   // expose public methods
129   return {
130     getUrlFromRecipe: getUrlFromRecipe,
131     getElectronicUrls: getElectronicUrls,
132   };
133 })();