(more relevant links, marked as wishlist item)
[ikiwiki] / doc / todo / mdwn_preview.mdwn
1 The [StackOverflow](http://stackoverflow.com/) site uses markdown for markup.
2 It has a fancy javascript thing for showing a real-time preview of what the user
3 is editing. It would be nice if ikiwiki could support this, too. The thing they
4 use on StackOverflow is supposed to be free software, so it should be easy to
5 add to ikiwiki.
6
7 > See [[wikiwyg]]. Note that I do not have a copy of the code for that, or
8 > it'd be in ikiwiki already. --[[Joey]] 
9
10 >> I just had a brief look at the [[wikiwyg]] page and the link to the plugin was
11 >> broken.  The StackOverflow site uses the [WMD](http://wmd-editor.com/) editor,
12 >> which seems to be related to the [ShowDown](http://attacklab.net/showdown/)
13 >> javascript port of Markdown.  Interestingly, [WMD source](http://wmd.googlecode.com/)
14 >> is now available under an MIT license, though it is supposedly undergoing heavy
15 >> refactoring.  It looks like there was previous discussion ( [[todo/Add_showdown_GUI_input__47__edit]] )
16 >> about a showdown plugin.  Maybe a WMD plugin would be worthwhile.  I might
17 >> look into it if I have time on the weekend. -- [[Will]]
18
19 [[!tag wishlist]]
20
21 >>> Below is a simple plugin/[[patch]] to make use of the WMD editor.
22
23 >>>> Now added to ikiwiki, thanks! --[[Joey]] 
24
25 >>> Turns out it isn't hard at all to
26 >>> get a basic version going (which doesn't handle directives at all, nor does it swtich itself off when you're
27 >>> editing something other than Markdown source).  I've
28 >>> removed the done tag so this is visible as a patch. -- [[Will]]
29
30 >>>> Hmm, it would be good if it turned off for !mdwn. Although this could
31 >>>> be difficult for a new page, since there is a dropdown selector to
32 >>>> choose the markup language then. But it should be doable for editing an
33 >>>> existing page.
34
35 >>>>> I agree.  I'm working on this for for both new pages and existing pages.
36 >>>>> It shouldn't be hard once I get WMD going through the javascript API.
37 >>>>> At the moment that is inexplicably failing, and I haven't had time to have a good look at why.
38 >>>>> I may not get a chance to look at this again for a few weeks.
39
40 >>>> Can I get a license statement (ie, GPL-2+) ffrom you for the plugin?
41 >>>> --[[Joey]] 
42
43 >>>>> Certainly.  You're free to use the code I posted below under the GPL-2+ license.  You'll note
44 >>>>> however that I haven't said anything about the WMD code itself.  The WMD web page says:
45
46 >>>>>> "I'm refactoring the code, and will be releasing WMD under the MIT license soon. For now you can download the most recent release (wmd-1.0.1.zip) and use it freely."
47
48 >>>>> It might be best to contact <support@attacklab.net> to for an explicit license on that if you want to include it.
49 >>>>> -- [[Will]]
50
51 > So, I wonder if I should add a copy of the WMD source to ikiwiki, or rely
52 > on the user or distribution providing it. It does not seem to be packaged
53 > for Debian yet. Hmm, I also can't find any copyright or license info in
54 > the zip file. --[[Joey]] 
55
56 >> This is a good question.  My thought is that it will probably not be packaged any time soon,
57 >> so you're better off adding it to IkiWiki.  I'd contact the author of WMD and ask them.  They
58 >> may have more insight.  -- [[Will]]
59
60 Note that the WMD plugin does **not** handle directives.  For this reason the normal `preview` button
61 remains.  Some CSS to clean up the display of the live WMD preview would be good.
62
63 > Can you elucidate the CSS comment -- or will it be obvious what you mean
64 > when I try it? Is it what's needed for the live preview? --[[Joey]]
65
66 >> In the version of the plugin below, a new `div` is added just below the form.  WMD
67 >> populates this div with the HTML it generates from the Markdown source.  This is not very
68 >> pretty at the moment - it appears in the same place as the preview used to, but with no
69 >> header or anything.  Any standard IkiWiki preview will appear below the WMD live preview.
70 >> I recommend having a look at <http://wmd-editor.com/examples/splitscreen>
71 >> for what a little CSS could achieve.  -- [[Will]]
72
73 > Hmm, now that I've tried it, I notice that it does live preview by
74 > default, below the edit window. Which is nice, but then if I hit the
75 > preview button, I get two previews.. which is confusing. (Also, minor,
76 > but: the live preview is missing the "Page Preview:" header.) --[[Joey]] 
77
78 > I wonder how annoying it would be to add some kind of simplistic wikilink
79 > support to wmd's preview? And/or a wikilink button? While not supporting
80 > directies is fine, not supporting wikilinks in a wiki seems a bit
81 > lacking. It may also entice novide users to not use wikilinks and instead
82 > use the hyperlinks that wmd does support. --[[Joey]] 
83
84 > Bug: When I preview, all the text in the edit field seems to be
85 > converted from mdwn to html. I think that wmd is converting the mdwn
86 > into html when the form is posted, so it would also save like that.
87 > I assume that is designed for websites that do not use markdown
88 > internally. Doesn't it have a setting to leave it as markdown?
89 >> Found setting, fixed. --[[Joey]] 
90
91 >>> As I noted above, I've been working on the non-markdown page issue.
92 >>> Below is my a new javascript file that I'm using, and below that a patch
93 >>> to enable it.  This patch makes the normal usage prettier - you get
94 >>> a side panel with the live preview in it.  It also adds a new config
95 >>> option, `wmd_use101api`, which turns on code that tries to use the
96 >>> wmd api.  At the moment this code doesn't seem to work - moreover the
97 >>> code that uses the new API dies early, so any code after that point is
98 >>> completely untested.  I will not
99 >>> get a chance to look at this again soon though, so I thought I'd post
100 >>> my progress so far.  -- [[Will]]
101
102
103 Place the following file in `underlays/wmd/wmd-ikiwiki.js`.
104
105 ----
106
107     // This is some code to interface the WMD interface 1.0.1 with IkiWiki
108     // The WMD interface is planned to change, so this file will likely need
109     // updating in future.
110     
111     if (useWMDinterface) {
112         wmd_options = { autostart: false, output: "Markdown" };
113         var instance = null;
114     
115         hook("onload", initwmd);
116     } else {
117         var typeSelector = document.getElementById("type");
118         
119         var currentType = getType(typeSelector);
120         
121         if (currentType == "mdwn") {
122                 wmd_options = { output: "Markdown" };
123                 document.getElementById("wmd-preview-container").style.display = 'none';
124         } else {
125                 wmd_options = { autostart: false };
126                 document.getElementById("wmd-preview-container").style.display = 'block';
127         }
128     }
129     
130     function initwmd() {
131         if (!Attacklab || !Attacklab.wmd) {
132                 alert("WMD hasn't finished loading!");
133                 return;
134         }
135         
136         var typeSelector = document.getElementById("type");
137         
138         var currentType = getType(typeSelector);
139         
140         if (currentType == "mdwn") {
141                 window.setTimeout(enableWMD,10);
142         }
143         
144         typeSelector.onchange=function() {
145                 var docType=getType(this);
146                 
147                 if (docType=="mdwn") {
148                         enableWMD();
149                 } else {
150                         disableWMD();
151                 }
152         }
153     }
154     
155     function getType(typeSelector)
156     {
157         if (typeSelector.nodeName.toLowerCase() == 'input') {
158                 return typeSelector.getAttribute('value');
159         } else if (typeSelector.nodeName.toLowerCase() == 'select') {
160                 return typeSelector.value;
161                 // return typeSelector.options[typeSelector.selectedIndex].innerText;
162         }
163         return "";
164     }
165     
166     function enableWMD()
167     {
168         var editContent = document.getElementById("editcontent");
169         var previewDiv = document.getElementById("wmd-preview");
170         var previewDivContainer = document.getElementById("wmd-preview-container");
171         
172         previewDivContainer.style.display = 'block';
173         // editContent.style.width = previewDivContainer.style.width;
174         
175         /***** build the preview manager *****/
176         var panes = {input:editContent, preview:previewDiv, output:null};
177         var previewManager = new Attacklab.wmd.previewManager(panes);
178     
179         /***** build the editor and tell it to refresh the preview after commands *****/
180         var editor = new Attacklab.wmd.editor(editContent,previewManager.refresh);
181     
182         // save everything so we can destroy it all later
183         instance = {ta:editContent, div:previewDiv, ed:editor, pm:previewManager};
184     }
185     
186     function disableWMD()
187     {
188         document.getElementById("wmd-preview-container").style.display = 'none';
189     
190         if (instance != null) {
191                 instance.pm.destroy();
192                 instance.ed.destroy();
193                 // inst.ta.style.width='100%'
194         }
195         instance = null;
196     }
197
198
199 ----
200
201     diff --git a/IkiWiki/Plugin/wmd.pm b/IkiWiki/Plugin/wmd.pm
202     index 9ddd237..743a0b8 100644
203     --- a/IkiWiki/Plugin/wmd.pm
204     +++ b/IkiWiki/Plugin/wmd.pm
205     @@ -17,6 +17,13 @@ sub getsetup () {
206         return
207                 plugin => {
208                         safe => 1,
209     +                   rebuild => 1,
210     +           },
211     +           wmd_use101api => {
212     +                   type => "boolean",
213     +                   description => "Use the advanced, but unstable, WMD api for markdown preview.",
214     +                   safe => 0,
215     +                   rebuild => 0,
216                 },
217      }
218      
219     @@ -24,29 +31,25 @@ sub formbuilder_setup (@) {
220         my %params=@_;
221         my $form=$params{form};
222      
223     -   return if ! defined $form->field("do");
224     +   return unless defined $form->field("do");
225         
226         return unless $form->field("do") eq "edit" ||
227     -                   $form->field("do") eq "create" ||
228     -                   $form->field("do") eq "comment";
229     -
230     -   $form->tmpl_param("wmd_preview", "<div class=\"wmd-preview\"></div>\n".
231     -           include_javascript(undef, 1));
232     -}
233     -
234     -sub include_javascript ($;$) {
235     -   my $page=shift;
236     -   my $absolute=shift;
237     -
238     -   my $wmdjs=urlto("wmd/wmd.js", $page, $absolute);
239     -   return <<"EOF"
240     -<script type="text/javascript">
241     -wmd_options = {
242     -   output: "Markdown"
243     -};
244     -</script>
245     -<script src="$wmdjs" type="text/javascript"></script>
246     -EOF
247     +                           $form->field("do") eq "create" ||
248     +                           $form->field("do") eq "comment";
249     +
250     +   my $useAPI = $config{wmd_use101api}?'true':'false';
251     +   my $ikiwikijs = urlto("ikiwiki.js", undef, 1);
252     +   my $wmdIkiwikijs = urlto("wmd-ikiwiki.js", undef, 1);
253     +   my $wmdjs = urlto("wmd.js", undef, 1);
254     +
255     +   my $previewScripts = <<"EOS";
256     +           <script type="text/javascript">useWMDinterface=$useAPI;</script>
257     +           <script src="$ikiwikijs" type="text/javascript"></script>
258     +           <script src="$wmdIkiwikijs" type="text/javascript"></script>
259     +           <script src="$wmdjs" type="text/javascript"></script>
260     +EOS
261     +
262     +   $form->tmpl_param("wmd_preview", $previewScripts);
263      }
264      
265      1
266     diff --git a/doc/style.css b/doc/style.css
267     index a6e6734..36c2b13
268     --- a/doc/style.css
269     +++ b/doc/style.css
270     @@ -76,9 +76,16 @@ div.tags {
271         float: right;
272      }
273      
274     +/*
275      #editcontent {
276         width: 100%;
277      }
278     +*/
279     +
280     +#wmd-preview-container {
281     +   width: 49%;
282     +   float: right;
283     +}
284      
285      img {
286         border-style: none;
287     diff --git a/templates/editpage.tmpl b/templates/editpage.tmpl
288     index b1cf015..1d2f080 100644
289     --- a/templates/editpage.tmpl
290     +++ b/templates/editpage.tmpl
291     @@ -15,6 +15,14 @@ Page type: <TMPL_VAR FIELD-TYPE>
292      <TMPL_VAR FIELD-PAGE>
293      <TMPL_VAR FIELD-TYPE>
294      </TMPL_IF>
295     +<TMPL_IF NAME="WMD_PREVIEW">
296     +<div id="wmd-preview-container">
297     +<div  class="header">
298     +<span>Live preview:</span>
299     +</div>
300     +<div class="wmd-preview" id="wmd-preview"></div>
301     +</div>
302     +</TMPL_IF>
303      <TMPL_VAR FIELD-EDITCONTENT><br />
304      <TMPL_IF NAME="CAN_COMMIT">
305      Optional comment about this change:<br />