Index: tdiary.rb
===================================================================
--- tdiary.rb	(Revision 29308)
+++ tdiary.rb	(Revision 29346)
@@ -24,6 +24,7 @@
 	require 'erb'
 end
 require 'compatible'
+require 'digest/md5'
 
 =begin
 == String class
@@ -583,6 +584,14 @@
 			end
 		end
 
+		def self.calc_section_id(section, section_index)
+			"#{section_index.to_i}:" + Digest::MD5.hexdigest( section.to_src )
+			# section_id.to_i will return the section index.
+		end
+		def calc_section_id(section, section_index)
+			self.class.calc_section_id(section, section_index)
+		end
+
 	private
 		# loading tdiary.conf in current directory
 		def load
@@ -1444,6 +1453,39 @@
 				end
 				DIRTY_NONE
 			end
+
+			# Seek the section to edit.
+			# If fail, query param(section_id or section) is simply ignored.
+			@section = @section_id = nil
+			if @cgi.valid? 'section_id'
+				section_id = @cgi.params['section_id'][0].force_encoding("US-ASCII")
+				sidx = 0
+				@diary.each_section do |section| sidx += 1
+					sid = conf.calc_section_id( section, sidx )
+					if sid == section_id
+						@section = section
+						@section_id = sid
+						break
+					end
+				end
+			end
+			unless @section
+				section_index = if @cgi.valid? 'section_id' and @cgi.params['old'][0] == @date.strftime('%Y%m%d')
+						@cgi.params['section_id'][0].force_encoding("US-ASCII").to_i
+					elsif @cgi.valid? 'section'
+						@cgi.params['section'][0].to_i
+					else
+						nil
+				end
+				sidx = 0
+				@diary.each_section do |section| sidx += 1
+					if sidx == section_index
+						@section = section
+						@section_id = conf.calc_section_id( section, sidx )
+						break
+					end
+				end
+			end
 		end
 	end
 
@@ -1468,6 +1510,27 @@
 				@diary.show( ! @hide )
 				DIRTY_NONE
 			end
+
+			# Seek the section to update.
+			# If fail, show error message (see skel/preview.rhtml).
+			@section = @section_id = nil
+			if @cgi.valid? 'section_id' and @old_date == @date.strftime( '%Y%m%d' )
+				section_id = @cgi.params['section_id'][0].force_encoding("US-ASCII")
+				diary = nil
+				@io.transaction( Time.local( @old_date[0,4].to_i, @old_date[4,2].to_i, @old_date[6,2].to_i ) ) do |diaries|
+					diary = diaries[@old_date]
+					DIRTY_NONE
+				end
+				sidx = 0
+				diary.each_section do |section| sidx += 1
+					sid = conf.calc_section_id( section, sidx )
+					if sid == section_id
+						@section = section
+						@section_id = sid
+						break
+					end
+				end
+			end
 		end
 
 		def eval_rhtml( prefix = '' )
@@ -1492,6 +1555,7 @@
 			@title = conf.to_native( cgi.params['title'][0] )
 			@body = conf.to_native( cgi.params['body'][0] )
 			@hide = cgi.params['hide'][0] == 'true' ? true : false
+			@author = conf.multi_user ? cgi.remote_user : nil
 			super
 		end
 
@@ -1516,7 +1580,6 @@
 			rescue TDiaryError
 				@date = newdate
 			end
-			@author = @conf.multi_user ? @cgi.remote_user : nil
 
 			@io.transaction( @date ) do |diaries|
 				@diaries = diaries
@@ -1542,14 +1605,43 @@
 		def initialize( cgi, rhtm, conf )
 			super
 			old_date = @cgi.params['old'][0]
+			section_id = @cgi.valid?('section_id') ? @cgi.params['section_id'][0] : nil
 
 			@io.transaction( @date ) do |diaries|
 				@diaries = diaries
 				@diary = self[@date]
 				if @diary then
 					if @date.strftime( '%Y%m%d' ) != old_date then
-						@diary.append( @body, @append )
+						@diary.append( @body, @author )
 						@diary.set_title( @title ) if @title.length > 0
+					elsif section_id
+						section_to_update = nil
+						sections = []
+						sidx = 0
+						@diary.each_section do |section| sidx += 1
+							sid = conf.calc_section_id( section, sidx )
+							if sid == section_id
+								section_to_update = section
+								sections.push [@body, @author]
+							else
+								sections.push [section.to_src, section.author]
+							end
+						end
+						if section_to_update
+							@diary.replace( @date, @title, '' )
+							sections.each do |body, author|
+								@diary.append( body, author )
+								# No Good if the style of diary needs something
+								# like a section-separator and which does not
+								# appear in the source of each section.
+							end
+						else
+							raise <<-"ERRMSG".gsub(/^\t{8}/, '').chomp!
+								The section to update was not found.
+								It might be updated after you had started to edit.
+								Go back and confirm the latest content, then retry.
+							ERRMSG
+						end
 					else
 						@diary.replace( @date, @title, @body )
 					end
Index: skel/preview.rhtml
===================================================================
--- skel/preview.rhtml	(Revision 29308)
+++ skel/preview.rhtml	(Revision 29346)
@@ -66,8 +66,19 @@
 		<div class="field title">
 			タイトル: <input class="field" name="title" tabindex="5"<%= accesskeys['title'] %> size="40" value="<%=h @diary.title %>">
 		</div>
+			<% if @cgi.valid? 'section_id' %>
+		<div class="field subtitle">
+			<input type="hidden" name="section_id" value="<%=h @cgi.params['section_id'][0] %>">
+			<span class="field subtitle">更新されるセクション: <% if @section %><%=h @section.subtitle.to_s.chomp %><% else %><strong>更新するセクションが見つかりません。既に変更されている可能性があります。最新の状態を確認してから再度編集してください。</strong><% end %></span>
+				<% unless @section %>
+			<span class="button edit">
+				<input type="submit" name="edit" tabindex="7" value="セクションを読み直す (注意! 現在の「本文」は消えます)">
+			</span>
+				<% end %>
+		</div>
+			<% end %>
 		<div class="textarea">
-			本文(<%=h @conf.style %>スタイル<%%= style_howto %>):<textarea name="body" tabindex="6"<%= accesskeys['body'] %> cols="70" rows="15"><%=h @diary.to_src %></textarea>
+			本文(<%=h @conf.style %>スタイル<%%= style_howto %>):<textarea name="body" tabindex="8"<%= accesskeys['body'] %> cols="70" rows="15"><%=h @diary.to_src %></textarea>
 		</div>
 		<%%=edit_proc( @date )%>
 		<span class="button preview">
Index: skel/update.rhtml
===================================================================
--- skel/update.rhtml	(Revision 29308)
+++ skel/update.rhtml	(Revision 29346)
@@ -42,10 +42,18 @@
 			<input type="submit" tabindex="4"<%= accesskeys['edit'] %> name="edit" value="この日付の日記を編集">
 		</span>
 		<div class="field title">
-			タイトル: <input class="field" name="title" tabindex="5"<%= accesskeys['title'] %> size="40" value="<%=h @diary.title %>">
+			<label>タイトル: <input class="field" name="title" tabindex="5"<%= accesskeys['title'] %> size="40" value="<%=h @diary.title %>"></label>
 		</div>
+			<% unless mode == 'form' %>
+		<div class="field subtitle">
+			<label>サブタイトル: <select class="field" name="section_id" tabindex="6"><option value=""<%=' selected="selected"' unless @section_id %>>-- 全てのセクション --</option><% sidx=0; @diary.each_section do |section| sidx += 1; section_id = @conf.calc_section_id( section, sidx )%><option value="<%=h section_id %>"<%=' selected="selected"' if section_id==@section_id %>><%='【編集中】 ' if section_id==@section_id %><%=h section.subtitle.to_s.chomp %></option><% end %></select></label>
+			<span class="button edit">
+				<input type="submit" name="edit" tabindex="7" value="このセクションだけを編集">
+			</span>
+		</div>
+			<% end %>
 		<div class="textarea">
-			本文(<%=h @conf.style %>スタイル<%%= style_howto %>):<textarea name="body" tabindex="6"<%= accesskeys['body'] %> cols="70" rows="15"><%=h @diary.to_src %></textarea>
+			本文(<%=h @conf.style %>スタイル<%%= style_howto %>):<textarea name="body" tabindex="8"<%= accesskeys['body'] %> cols="70" rows="15"><%=h @section ? @section.to_src : @diary.to_src %></textarea>
 		</div>
 		<%%=edit_proc( @date )%>
 		<span class="button preview">
Index: skel/preview.rhtml.en
===================================================================
--- skel/preview.rhtml.en	(Revision 29308)
+++ skel/preview.rhtml.en	(Revision 29346)
@@ -53,6 +53,17 @@
 		<div class="field title">
 			Title: <input class="field" name="title" tabindex="5" accesskey="T" size="40" value="<%=h @diary.title %>">
 		</div>
+			<% if @cgi.valid? 'section_id' %>
+		<div class="field subtitle">
+			<input type="hidden" name="section_id" value="<%=h @cgi.params['section_id'][0] %>">
+			<span class="field subtitle">Editing Section: <% if @section %><%=h @section.subtitle.to_s.chomp %><% else %><strong>The section to update was not found. It might be updated after you had started to edit. Check the latest version and retry.</strong><% end %></span>
+				<% unless @section %>
+			<span class="button edit">
+				<input type="submit" name="edit" tabindex="7" value="Reload the section (Warning! Do not forget to copy your "Article".)">
+			</span>
+				<% end %>
+		</div>
+			<% end %>
 		<div class="textarea">
 			Article(<%=h @conf.style %> style<%%= style_howto %>):<textarea name="body" tabindex="6" accesskey="C" cols="70" rows="15"><%=h @diary.to_src %></textarea>
 		</div>
Index: skel/update.rhtml.en
===================================================================
--- skel/update.rhtml.en	(Revision 29308)
+++ skel/update.rhtml.en	(Revision 29346)
@@ -27,8 +27,16 @@
 		<div class="field title">
 			Title: <input class="field" name="title" tabindex="5" accesskey="T" size="40" value="<%=h @diary.title %>">
 		</div>
+			<% unless mode == 'form' %>
+		<div class="field subtitle">
+			<label>Subtitle: <select class="field" name="section_id" tabindex="6"><option value=""<%=' selected="selected"' unless @section_id %>>-- ALL --</option><% sidx=0; @diary.each_section do |section| sidx += 1; section_id = @conf.calc_section_id( section, sidx )%><option value="<%=h section_id %>"<%=' selected="selected"' if section_id==@section_id %>><%='【EDIT】 ' if section_id==@section_id %><%=h section.subtitle.to_s.chomp %></option><% end %></select></label>
+			<span class="button edit">
+				<input type="submit" tabindex="7" name="edit" value="Edit this section only">
+			</span>
+		</div>
+			<% end %>
 		<div class="textarea">
-			Article(<%=h @conf.style %> style<%%= style_howto %>):<textarea name="body" tabindex="6" accesskey="C" cols="70" rows="15"><%=h @diary.to_src %></textarea>
+			Article(<%=h @conf.style %> style<%%= style_howto %>):<textarea name="body" tabindex="6" accesskey="C" cols="70" rows="15"><%=h @section ? @section.to_src : @diary.to_src %></textarea>
 		</div>
 		<%%=edit_proc( @date )%>
 		<span class="button preview">
