diff -ur 1.35/Include.py modified/Include.py --- 1.35/Include.py 2005-06-27 00:43:06.000000000 +0900 +++ modified/Include.py 2005-11-29 17:44:47.015625000 +0900 @@ -216,7 +216,7 @@ request.redirect(strfile) try: cid = request.makeUniqueID("Include_%s" % wikiutil.quoteWikinameFS(inc_page.page_name)) - inc_page.send_page(request, content_only=1, content_id=cid) + inc_page.send_page(request, content_only=1, content_id=cid, do_cache=False) result.append(strfile.getvalue()) finally: request.redirect() diff -ur 1.35/multiconfig.py modified/multiconfig.py --- 1.35/multiconfig.py 2005-07-31 00:58:52.000000000 +0900 +++ modified/multiconfig.py 2005-11-29 17:40:11.609375000 +0900 @@ -247,6 +252,7 @@ shared_intermap = None # can be string or list of strings (filenames) show_hosts = 1 show_section_numbers = 1 + allow_section_edit = 1 show_timings = 0 show_version = 0 siteid = 'default' diff -ur 1.35/PageEditor.py modified/PageEditor.py --- 1.35/PageEditor.py 2005-07-28 00:51:40.000000000 +0900 +++ modified/PageEditor.py 2005-11-29 17:43:39.000000000 +0900 @@ -176,6 +176,27 @@ preview = kw.get('preview', None) emit_anchor = not kw.get('staytop', 0) + # for section editing + issectionedit = kw.get('issectionedit', 1) + pagetext = kw.get('pagetext', None) + startline = int(form.get('startline', ['0'])[0]) + endline = int(form.get('endline', ['0'])[0]) + srev = int(form.get('srev', ['0'])[0]) + + if startline or endline: + if not startline: + startline = 1 + + if not endline: + endline = -1 + else: + issectionedit = 0 + + if issectionedit: + # need to add config + self._allow_section_edit = self.cfg.allow_section_edit + # self._allow_section_edit = 1 + from MoinMoin.formatter.text_html import Formatter self.request.formatter = Formatter(self.request, store_pagelinks=1) @@ -214,7 +235,11 @@ title = _('Edit "%(pagename)s"') else: title = _('Preview of "%(pagename)s"') - self.set_raw_body(preview, modified=1) + + if issectionedit and pagetext is not None: + self.set_raw_body(pagetext, modified=1) + else: + self.set_raw_body(preview, modified=1) # send header stuff lock_timeout = self.lock.timeout / 60 @@ -254,9 +279,19 @@ # We don't show preview when in conflict preview = None + # no section-editing any more + if issectionedit: + conflict_msg = u'%s %s' % (conflict_msg, _('Section editing is canceled.')) + issectionedit = 0 + elif self.exists(): # revision of existing page rev = self.current_rev() + if issectionedit and preview is None: + if not (srev and srev == rev): + conflict_msg = u'%s %s' % (_('Section editing is canceled.'), _('Someone else updated this page. You are editing the updated revision.')) + issectionedit = 0 + else: # page creation rev = 0 @@ -341,10 +392,21 @@ # Generate default content for new pages if not raw_body: raw_body = _('Describe %s here.') % (self.page_name,) - + elif issectionedit: + # for section editing + if pagetext is not None: + raw_body = preview + else: + raw_body = self.fetchsection(raw_body, startline, endline) + # Send revision of the page our edit is based on self.request.write('' % (rev,)) - + + # Send section startline and endline for section-editing + if issectionedit: + self.request.write('' % startline) + self.request.write('' % endline) + # Add textarea with page text # TODO: currently self.language is None at this point. We have @@ -425,6 +512,8 @@ badwords_re = None if preview is not None: + if issectionedit: + self.set_raw_body(preview) if SpellCheck and ( form.has_key('button_spellcheck') or form.has_key('button_newwords')): @@ -442,7 +531,11 @@ + '') if preview is not None: - self.send_page(self.request, content_id='preview', content_only=1, + if issectionedit: + self.send_page(self.request, content_id='preview', content_only=1, + hilite_re=badwords_re, do_cache=False) + else: + self.send_page(self.request, content_id='preview', content_only=1, hilite_re=badwords_re) self.request.write(self.request.formatter.endContent()) @@ -936,6 +1029,16 @@ self.lock.release(force=not msg) # XXX does "not msg" make any sense? return msg + + def fetchsection(self, pagetext, startline, endline): + + pagetext = pagetext.split('\n') + if endline == -1: + sectiontext = u'\n'.join(pagetext[startline-1:]) + else: + sectiontext = u'\n'.join(pagetext[startline-1:endline]) + + return sectiontext class PageLock: diff -ur 1.35/text_html.py modified/text_html.py --- 1.35/text_html.py 2005-07-27 03:46:52.000000000 +0900 +++ modified/text_html.py 2005-11-29 17:47:00.718750000 +0900 @@ -38,7 +38,16 @@ self._is_included = kw.get('is_included',False) self.request = request self.cfg = request.cfg - + + # for section editing + self._allow_section_edit = None + if not hasattr(request, 'sectionindex'): + request.sectionindex = 0 + + self.sectionstack = [] + self.sectionpool = {} + self.sectionlastdepth = 0 + if not hasattr(request, '_fmt_hd_counters'): request._fmt_hd_counters = [] @@ -584,7 +593,22 @@ # remember depth of first heading, and adapt counting depth accordingly if not self._base_depth: self._base_depth = depth - + + # section editing configuration + if self._allow_section_edit is None: + # need to add config + self._allow_section_edit = self.cfg.allow_section_edit + # self._allow_section_edit = 1 + sectionediting = self.request.getPragma('section-edit', '').lower() + if sectionediting in ['off']: + self._allow_section_edit = 0 + elif sectionediting in ['on']: + self._allow_section_edit = 1 + + if self._allow_section_edit: + if not self.request.user.may.write(self.page.page_name): + self._allow_section_edit = 0 + count_depth = max(depth - (self._base_depth - 1), 1) # check numbering, possibly changing the default @@ -603,7 +627,34 @@ # closing tag, with empty line after, to make source more readable if not on: - return self.close('h%d' % heading_depth) + '\n' + result = self.close('h%d' % heading_depth) + '\n' + + lineno = kw.get('lineno', 0) + + sectionscript = '' + if self._allow_section_edit and lineno: + + self.request.sectionindex += 1 + sectionindex = self.request.sectionindex + sectionscript = self.savesectioninfor(sectionindex, depth, lineno) + + attr = 'id="sectionedit%d"' % sectionindex + + backto = u'' + if self._is_included and hasattr(self.request, "_Include_backto"): + backto = u'&backto=%s' % wikiutil.quoteWikinameURL(self.request._Include_backto) + + sectioneditpage = u'%s/%s' % (self.request.getScriptname(), wikiutil.quoteWikinameURL(self.page.page_name)) + srev = self.page.current_rev() + querystring = u'%s?action=edit%s&srev=%d&startline=%d' % (sectioneditpage, backto, srev, lineno) + + result = ('%s%s%s%s' % + (self.url(1, querystring, unescaped=1, title='Edit this section', attrs=attr), + self.icon('edit'), + self.url(0), + result)) + + return ' %s%s' % (result, sectionscript) # create section number number = '' @@ -734,6 +785,51 @@ return self.open(tag, newline=1, attr=attrs) return self.close(tag) + def savesectioninfor(self, index, depth, lineno, save=1): + # store section information + section = {} + sectionscriptlist = [] + sectionscript = u'document.getElementById("sectionedit%d").href += "&endline=%d";' + scriptresult = '' + + lastdepth = self.sectionlastdepth + sectionindex = index + + if lastdepth >= depth: + while 1: + if len(self.sectionstack): + lastsection = self.sectionstack.pop() + lastdepth = lastsection['depth'] + if lastdepth >= depth: + self.sectionpool[lastsection['index']]['endlineno'] = lineno - 1 + sectionscriptlist.append(sectionscript % (lastsection['index'], lineno - 1)) + else: + self.sectionstack.append(lastsection) + break + else: + break + + if save: + section['index'] = sectionindex + section['startlineno'] = lineno + section['depth'] = depth + section['endlineno'] = -1 + self.sectionlastdepth = depth + self.sectionpool[sectionindex] = section + self.sectionstack.append(section) + + if len(sectionscriptlist) > 0: + + scriptresult = u""" + +""" % u'\n'.join(sectionscriptlist) + + return scriptresult + def escapedText(self, text): return wikiutil.escape(text) diff -ur 1.35/wiki.py modified/wiki.py --- 1.35/wiki.py 2005-07-30 21:51:12.000000000 +0900 +++ modified/wiki.py 2005-11-29 17:45:17.546875000 +0900 @@ -798,7 +798,7 @@ result += self.formatter.heading(1, depth, id="head-"+sha.new(pntt.encode(config.charset)).hexdigest()+unique_id) return (result + self.formatter.text(title_text) + - self.formatter.heading(0, depth)) + self.formatter.heading(0, depth, lineno=self.lineno)) def _processor_repl(self, word): """Handle processed code displays.""" diff -ur 1.35/wikiaction.py modified/wikiaction.py --- 1.35/wikiaction.py 2005-06-27 00:43:06.000000000 +0900 +++ modified/wikiaction.py 2005-11-29 17:48:42.875000000 +0900 @@ -541,10 +541,32 @@ category = request.form.get('category', [None])[0] rstrip = int(request.form.get('rstrip', ['0'])[0]) trivial = int(request.form.get('trivial', ['0'])[0]) + + # section editing + startline = int(request.form.get('startline', ['0'])[0]) + endline = int(request.form.get('endline', ['0'])[0]) + + if startline or endline: + issectionedit = 1 + + if not startline: + startline = 1 + + if not endline: + endline = -1 + else: + issectionedit = 0 + + if issectionedit: + savetext = pg.normalizeText(savetext, stripspaces=rstrip) + sectiontext = savetext + savetext = mergesection(pg.get_raw_body(), savetext, startline, endline) + # IMPORTANT: normalize text from the form. This should be done in # one place before we manipulate the text. - savetext = pg.normalizeText(savetext, stripspaces=rstrip) + if not issectionedit: + savetext = pg.normalizeText(savetext, stripspaces=rstrip) # Add category @@ -594,7 +616,10 @@ if (request.form.has_key('button_preview') or request.form.has_key('button_spellcheck') or request.form.has_key('button_newwords')): - pg.sendEditor(preview=savetext, comment=comment) + if issectionedit: + pg.sendEditor(preview=sectiontext, comment=comment, pagetext=savetext) + else: + pg.sendEditor(preview=savetext, comment=comment) # Edit was canceled elif request.form.has_key('button_cancel'): @@ -620,7 +645,10 @@ querystr='action=diff&rev=%d' % rev) } # We don't send preview when we do merge conflict - pg.sendEditor(msg=conflict_msg, comment=comment) + if issectionedit: + conflict_msg = u'%s %s' % (conflict_msg, _('Section editing is canceled.')) + + pg.sendEditor(msg=conflict_msg, comment=comment, issectionedit=0) return else: savemsg = conflict_msg @@ -871,5 +899,16 @@ return handler - +def mergesection(pagetext, newsectiontext, startline, endline): + + pagetext = pagetext.split('\n') + + prevtext = u'%s\n' % u'\n'.join(pagetext[:startline-1]) + if endline == -1: + nexttext = '' + else: + nexttext = u'\n%s' % u'\n'.join(pagetext[endline:]) + + return u'%s%s%s' % (prevtext, newsectiontext, nexttext) +