]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blobdiff - doc/todo/mdwn_preview.mdwn
Merge branch 'master' of ssh://git.ikiwiki.info
[git.ikiwiki.info.git] / doc / todo / mdwn_preview.mdwn
index 3008eb52983060c7b29ef38ad9dec744d1f55805..fa69bad47d77836337394e2484557aa15fad71f3 100644 (file)
@@ -1,3 +1,37 @@
+ikiwiki needs a wysiwyg markdown editor. While there have been tries using
+WMD etc, they are not fully satisfactory, and also the license of
+everything around WMD is [[unclear|plugins/wmd/discussion]].
+
+[Hallo](https://github.com/bergie/hallo) is the closest to a solution
+I've seen.
+The user can edit the page by clicking on the html part they want to change
+and typing. Selecting text pops up a toolbar to modify it.
+
+[Demo of Hallo with live WYSIWYG markdown editing](http://bergie.github.com/hallo/markdown.html)
+This demo uses showdown, and I still don't know what the license of
+showdown is. However, the showdown part seems to only be to handle the live
+conversion from the markdown source in the edit field to the html. The 
+(edited) html to markdown conversion is accomplished by Hallo.
+
+So, ikiwiki could use this in a page edit UI that does not show the
+markdown at all. The user would edit the live page, entirely in wysiwyg
+mode, and on saving hallo's generated markdown would be saved. Probably
+there would need to be a button to bring up the current markdown editor
+too, but without showdown, changes in it would not immediatly preview, so
+it'd make sense to disable hallo when the editor is visible.
+
+Issue: Ikiwiki directives can generate html. We would not want that html to
+be editable by halo and converted back to markdown. Also, the directives
+need to appear in the html so users can edit them. This seems to call for a
+special page rendering mode for editing, in which directives are either not
+expanded, or are expanded but the generated html wrapped in some tag that
+makes hallo refuse to edit it (which would probably require that feature be
+added to hallo, currently it acts on all blocks with `class=editable`),
+or otherwise allows it to be stripped out at save time. --[[Joey]]
+
+### old discussion
+
+
 The [StackOverflow](http://stackoverflow.com/) site uses markdown for markup.
 It has a fancy javascript thing for showing a real-time preview of what the user
 is editing. It would be nice if ikiwiki could support this, too. The thing they
@@ -87,3 +121,219 @@ remains.  Some CSS to clean up the display of the live WMD preview would be good
 > I assume that is designed for websites that do not use markdown
 > internally. Doesn't it have a setting to leave it as markdown?
 >> Found setting, fixed. --[[Joey]] 
+
+>>> As I noted above, I've been working on the non-markdown page issue.
+>>> Below is my a new javascript file that I'm using, and below that a patch
+>>> to enable it.  This patch makes the normal usage prettier - you get
+>>> a side panel with the live preview in it.  It also adds a new config
+>>> option, `wmd_use101api`, which turns on code that tries to use the
+>>> wmd api.  At the moment this code doesn't seem to work - moreover the
+>>> code that uses the new API dies early, so any code after that point is
+>>> completely untested.  I will not
+>>> get a chance to look at this again soon though, so I thought I'd post
+>>> my progress so far.  -- [[Will]]
+
+
+Place the following file in `underlays/wmd/wmd-ikiwiki.js`.
+
+----
+
+    // This is some code to interface the WMD interface 1.0.1 with IkiWiki
+    // The WMD interface is planned to change, so this file will likely need
+    // updating in future.
+    
+    if (useWMDinterface) {
+       wmd_options = { autostart: false, output: "Markdown" };
+       var instance = null;
+    
+       hook("onload", initwmd);
+    } else {
+       var typeSelector = document.getElementById("type");
+       
+       var currentType = getType(typeSelector);
+       
+       if (currentType == "mdwn") {
+               wmd_options = { output: "Markdown" };
+               document.getElementById("wmd-preview-container").style.display = 'none';
+       } else {
+               wmd_options = { autostart: false };
+               document.getElementById("wmd-preview-container").style.display = 'block';
+       }
+    }
+    
+    function initwmd() {
+       if (!Attacklab || !Attacklab.wmd) {
+               alert("WMD hasn't finished loading!");
+               return;
+       }
+       
+       var typeSelector = document.getElementById("type");
+       
+       var currentType = getType(typeSelector);
+       
+       if (currentType == "mdwn") {
+               window.setTimeout(enableWMD,10);
+       }
+       
+       typeSelector.onchange=function() {
+               var docType=getType(this);
+               
+               if (docType=="mdwn") {
+                       enableWMD();
+               } else {
+                       disableWMD();
+               }
+       }
+    }
+    
+    function getType(typeSelector)
+    {
+       if (typeSelector.nodeName.toLowerCase() == 'input') {
+               return typeSelector.getAttribute('value');
+       } else if (typeSelector.nodeName.toLowerCase() == 'select') {
+               return typeSelector.value;
+               // return typeSelector.options[typeSelector.selectedIndex].innerText;
+       }
+       return "";
+    }
+    
+    function enableWMD()
+    {
+       var editContent = document.getElementById("editcontent");
+       var previewDiv = document.getElementById("wmd-preview");
+       var previewDivContainer = document.getElementById("wmd-preview-container");
+       
+       previewDivContainer.style.display = 'block';
+       // editContent.style.width = previewDivContainer.style.width;
+       
+       /***** build the preview manager *****/
+       var panes = {input:editContent, preview:previewDiv, output:null};
+       var previewManager = new Attacklab.wmd.previewManager(panes);
+    
+       /***** build the editor and tell it to refresh the preview after commands *****/
+       var editor = new Attacklab.wmd.editor(editContent,previewManager.refresh);
+    
+       // save everything so we can destroy it all later
+       instance = {ta:editContent, div:previewDiv, ed:editor, pm:previewManager};
+    }
+    
+    function disableWMD()
+    {
+       document.getElementById("wmd-preview-container").style.display = 'none';
+    
+       if (instance != null) {
+               instance.pm.destroy();
+               instance.ed.destroy();
+               // inst.ta.style.width='100%'
+       }
+       instance = null;
+    }
+
+
+----
+
+    diff --git a/IkiWiki/Plugin/wmd.pm b/IkiWiki/Plugin/wmd.pm
+    index 9ddd237..743a0b8 100644
+    --- a/IkiWiki/Plugin/wmd.pm
+    +++ b/IkiWiki/Plugin/wmd.pm
+    @@ -17,6 +17,13 @@ sub getsetup () {
+       return
+               plugin => {
+                       safe => 1,
+    +                  rebuild => 1,
+    +          },
+    +          wmd_use101api => {
+    +                  type => "boolean",
+    +                  description => "Use the advanced, but unstable, WMD api for markdown preview.",
+    +                  safe => 0,
+    +                  rebuild => 0,
+               },
+     }
+     
+    @@ -24,29 +31,25 @@ sub formbuilder_setup (@) {
+       my %params=@_;
+       my $form=$params{form};
+     
+    -  return if ! defined $form->field("do");
+    +  return unless defined $form->field("do");
+       
+       return unless $form->field("do") eq "edit" ||
+    -                  $form->field("do") eq "create" ||
+    -                  $form->field("do") eq "comment";
+    -
+    -  $form->tmpl_param("wmd_preview", "<div class=\"wmd-preview\"></div>\n".
+    -          include_javascript(undef, 1));
+    -}
+    -
+    -sub include_javascript ($;$) {
+    -  my $page=shift;
+    -  my $absolute=shift;
+    -
+    -  my $wmdjs=urlto("wmd/wmd.js", $page, $absolute);
+    -  return <<"EOF"
+    -<script type="text/javascript">
+    -wmd_options = {
+    -  output: "Markdown"
+    -};
+    -</script>
+    -<script src="$wmdjs" type="text/javascript"></script>
+    -EOF
+    +                          $form->field("do") eq "create" ||
+    +                          $form->field("do") eq "comment";
+    +
+    +  my $useAPI = $config{wmd_use101api}?'true':'false';
+    +  my $ikiwikijs = urlto("ikiwiki.js", undef, 1);
+    +  my $wmdIkiwikijs = urlto("wmd-ikiwiki.js", undef, 1);
+    +  my $wmdjs = urlto("wmd.js", undef, 1);
+    +
+    +  my $previewScripts = <<"EOS";
+    +          <script type="text/javascript">useWMDinterface=$useAPI;</script>
+    +          <script src="$ikiwikijs" type="text/javascript"></script>
+    +          <script src="$wmdIkiwikijs" type="text/javascript"></script>
+    +          <script src="$wmdjs" type="text/javascript"></script>
+    +EOS
+    +
+    +  $form->tmpl_param("wmd_preview", $previewScripts);
+     }
+     
+     1
+    diff --git a/doc/style.css b/doc/style.css
+    index a6e6734..36c2b13
+    --- a/doc/style.css
+    +++ b/doc/style.css
+    @@ -76,9 +76,16 @@ div.tags {
+       float: right;
+     }
+     
+    +/*
+     #editcontent {
+       width: 100%;
+     }
+    +*/
+    +
+    +#wmd-preview-container {
+    +  width: 49%;
+    +  float: right;
+    +}
+     
+     img {
+       border-style: none;
+    diff --git a/templates/editpage.tmpl b/templates/editpage.tmpl
+    index b1cf015..1d2f080 100644
+    --- a/templates/editpage.tmpl
+    +++ b/templates/editpage.tmpl
+    @@ -15,6 +15,14 @@ Page type: <TMPL_VAR FIELD-TYPE>
+     <TMPL_VAR FIELD-PAGE>
+     <TMPL_VAR FIELD-TYPE>
+     </TMPL_IF>
+    +<TMPL_IF NAME="WMD_PREVIEW">
+    +<div id="wmd-preview-container">
+    +<div  class="header">
+    +<span>Live preview:</span>
+    +</div>
+    +<div class="wmd-preview" id="wmd-preview"></div>
+    +</div>
+    +</TMPL_IF>
+     <TMPL_VAR FIELD-EDITCONTENT><br />
+     <TMPL_IF NAME="CAN_COMMIT">
+     Optional comment about this change:<br />