PageRenderTime 81ms CodeModel.GetById 17ms app.highlight 41ms RepoModel.GetById 1ms app.codeStats 2ms

/MarkDownSharpEditor/Form1.cs

https://github.com/asanoesw/MarkDownSharpEditor
C# | 3551 lines | 2262 code | 325 blank | 964 comment | 525 complexity | c88aa535553c02d781cd86a947e9b9dd MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1using System;
   2using System.Collections.Generic;
   3using System.ComponentModel;
   4using System.Data;
   5using System.Drawing;
   6using System.Linq;
   7using System.Text;
   8using System.Windows.Forms;
   9using System.IO;
  10using System.Collections;
  11using System.Security.Cryptography;
  12using System.Text.RegularExpressions;
  13using System.Diagnostics;
  14using System.Runtime.InteropServices;
  15using System.Windows.Documents;
  16using MarkDownSharpEditor.Properties;
  17using mshtml;
  18
  19namespace MarkDownSharpEditor
  20{
  21
  22	public partial class Form1 : Form
  23	{
  24		//-----------------------------------
  25		// WebBrowserコンポーネントプレビューの更新音(クリック音)をOFFにする
  26		// Click sound off when webBrowser component preview
  27		const int FEATURE_DISABLE_NAVIGATION_SOUNDS = 21;
  28		const int SET_FEATURE_ON_PROCESS = 0x00000002;
  29		[DllImport("urlmon.dll")]
  30		[PreserveSig]
  31		[return: MarshalAs(UnmanagedType.Error)]
  32		static extern int CoInternetSetFeatureEnabled(int FeatureEntry, [MarshalAs(UnmanagedType.U4)] int dwFlags, bool fEnable);
  33
  34		//-----------------------------------
  35		int undoCounter = 0;                                              // Undo buffer counter
  36		List<string> UndoBuffer = new List<string>();
  37		private bool _fSearchStart = false;                                //検索を開始したか ( Start search flag )
  38		private int _richEditBoxInternalHeight;                            //richTextBox1の内部的な高さ ( internal height of richTextBox1 component )
  39		private int _WebBrowserInternalHeight;                             //webBrowser1の内部的な高さ(body)( internal height of webBrowser1 component )
  40
  41		private Point _preFormPos;                                         //フォームサイズ変更前の位置を一時保存 ( Temporary form position before resizing form )
  42		private Size _preFormSize;                                         //フォームサイズ変更前のサイズを一時保存 ( Temporay form size before resizing form )
  43
  44		private bool _fNoTitle = true;                                     //無題のまま編集中かどうか ( no name of file flag )
  45		private string _MarkDownTextFilePath = "";                         //編集中のMDファイルパス ( Editing .MD file path )
  46		private string _TemporaryHtmlFilePath = "";                        //プレビュー用のテンポラリHTMLファイルパス ( Temporary HTML file path for preview )
  47		private string _SelectedCssFilePath = "";                          //選択中のCSSファイルパス ( Applying CSS file path )
  48		private Encoding _EditingFileEncoding = Encoding.UTF8;             //編集中MDファイルの文字エンコーディング ( Character encoding of MD file editing )
  49
  50		private bool _fConstraintChange = true;	                           //更新状態の抑制 ( Constraint changing flag )
  51		private List<MarkdownSyntaxKeyword> _MarkdownSyntaxKeywordAarray = new List<MarkdownSyntaxKeyword>();  // Array of MarkdownSyntaxKeyword Class
  52		private ArrayList _SyntaxArrayList = new ArrayList();
  53
  54		//-----------------------------------
  55		// コンストラクタ ( Constructor )
  56		//-----------------------------------
  57		public Form1()
  58		{
  59			InitializeComponent();
  60
  61			//IME Handler On/Off
  62			if (MarkDownSharpEditor.AppSettings.Instance.Lang == "ja")
  63			{
  64				richTextBox1.IMEWorkaroundEnabled = true;
  65			}
  66			else
  67			{
  68				richTextBox1.IMEWorkaroundEnabled = false;
  69			}
  70
  71			this.richTextBox1.DragEnter += new System.Windows.Forms.DragEventHandler(this.richTextBox1_DragEnter);
  72			this.richTextBox1.DragDrop += new System.Windows.Forms.DragEventHandler(this.richTextBox1_DragDrop);
  73			richTextBox1.AllowDrop = true;
  74
  75			//設定を読み込む ( Read options )
  76			//Program.csで読み込むようにした ( Load in "Program.cs" )
  77			//MarkDownSharpEditor.AppSettings.Instance.ReadFromXMLFile();
  78
  79			//WebBrowserClickSoundOFF();
  80			CoInternetSetFeatureEnabled(FEATURE_DISABLE_NAVIGATION_SOUNDS, SET_FEATURE_ON_PROCESS, true);
  81
  82		}
  83
  84		//----------------------------------------------------------------------
  85		// フォームをロード ( Load main form )
  86		//----------------------------------------------------------------------
  87		private void Form1_Load(object sender, EventArgs e)
  88		{
  89
  90			var obj = MarkDownSharpEditor.AppSettings.Instance;
  91
  92			//-----------------------------------
  93			//フォーム位置・サイズ ( Form position & size )
  94			//-----------------------------------
  95
  96			this.Location = obj.FormPos;
  97			this.Size = obj.FormSize;
  98			this.richTextBox1.Width = obj.richEditWidth;
  99
 100			//ウィンドウ位置の調整(へんなところに行かないように戻す)
 101			// Ajust window position ( Set position into Desktop range )
 102			if (this.Left < 0 || this.Left > Screen.PrimaryScreen.Bounds.Width)
 103			{
 104				this.Left = 0;
 105			}
 106			if (this.Top < 0 || this.Top > Screen.PrimaryScreen.Bounds.Height)
 107			{
 108				this.Top = 0;
 109			}
 110
 111			if (obj.FormState == 1)
 112			{	//最小化 ( Minimize )
 113				this.WindowState = FormWindowState.Minimized;
 114			}
 115			else if (obj.FormState == 2)
 116			{	//最大化 ( Maximize )
 117				this.WindowState = FormWindowState.Maximized;
 118			}
 119
 120			//メインメニュー表示
 121			//View main menu
 122			this.menuViewToolBar.Checked = obj.fViewToolBar;
 123			this.toolStrip1.Visible = obj.fViewToolBar;
 124			this.menuViewStatusBar.Checked = obj.fViewStatusBar;
 125			this.statusStrip1.Visible = obj.fViewStatusBar;
 126			this.menuViewWidthEvenly.Checked = obj.fSplitBarWidthEvenly;
 127
 128			//言語 ( Language )
 129			if (obj.Lang == "ja")
 130			{
 131				menuViewJapanese.Checked = true;
 132				menuViewEnglish.Checked = false;
 133			}
 134			else
 135			{
 136				menuViewJapanese.Checked = false;
 137				menuViewEnglish.Checked = true;
 138			}
 139
 140			//ブラウザープレビューまでの間隔
 141			//Interval time of browser preview
 142			if (obj.AutoBrowserPreviewInterval > 0)
 143			{
 144				timer1.Interval = obj.AutoBrowserPreviewInterval;
 145			}
 146
 147			//-----------------------------------
 148			//RichEditBox font
 149			FontConverter fc = new FontConverter();
 150			try { richTextBox1.Font = (Font)fc.ConvertFromString(obj.FontFormat); }
 151			catch { }
 152			//RichEditBox font color
 153			richTextBox1.ForeColor = Color.FromArgb(obj.richEditForeColor);
 154			//ステータスバーに表示
 155			//View in statusbar
 156			toolStripStatusLabelFontInfo.Text =
 157				richTextBox1.Font.Name + "," + richTextBox1.Font.Size.ToString() + "pt";
 158
 159			//エディターのシンタックスハイライター設定の反映
 160			//Syntax highlighter of editor window is enabled 
 161			_MarkdownSyntaxKeywordAarray = MarkdownSyntaxKeyword.CreateKeywordList();
 162
 163			//-----------------------------------
 164			//選択中のエンコーディングを表示
 165			//View selected character encoding name
 166			foreach (EncodingInfo ei in Encoding.GetEncodings())
 167			{
 168				if (ei.GetEncoding().IsBrowserDisplay == true)
 169				{
 170					if (ei.CodePage == obj.CodePageNumber)
 171					{
 172						toolStripStatusLabelHtmlEncoding.Text = ei.DisplayName;
 173						break;
 174					}
 175				}
 176			}
 177
 178			//-----------------------------------
 179			//指定されたCSSファイル名を表示
 180			//View selected CSS file name
 181			toolStripStatusLabelCssFileName.Text = Resources.toolTipCssFileName; //"CSSファイル指定なし"; ( No CSS file )
 182
 183			if (obj.ArrayCssFileList.Count > 0)
 184			{
 185				string FilePath = (string)obj.ArrayCssFileList[0];
 186				if (File.Exists(FilePath) == true)
 187				{
 188					toolStripStatusLabelCssFileName.Text = Path.GetFileName(FilePath);
 189					_SelectedCssFilePath = FilePath;
 190				}
 191			}
 192
 193			//-----------------------------------
 194			//出力するHTMLエンコーディング表示
 195			//View HTML charcter encoding name for output
 196			if (obj.HtmlEncodingOption == 0)
 197			{
 198				// 編集中(RichEditBox側)のエンコーディング
 199				// 基本的にはテキストファイルが読み込まれたときに表示する
 200				// View encoding name of editor window
 201				toolStripStatusLabelHtmlEncoding.Text = _EditingFileEncoding.EncodingName;
 202			}
 203			else
 204			{
 205				//エンコーディングを指定する(&C)
 206				//Select encoding
 207				Encoding enc = Encoding.GetEncoding(obj.CodePageNumber);
 208				toolStripStatusLabelHtmlEncoding.Text = enc.EncodingName;
 209			}
 210
 211			//-----------------------------------
 212			//検索フォーム・オプション
 213			//Search form options
 214			chkOptionCase.Checked = obj.fSearchOptionIgnoreCase ? false : true;
 215
 216		}
 217
 218		//----------------------------------------------------------------------
 219		// フォームを表示
 220		// View Main form
 221		//----------------------------------------------------------------------
 222		private void Form1_Shown(object sender, EventArgs e)
 223		{
 224
 225			string DirPath = MarkDownSharpEditor.AppSettings.GetAppDataLocalPath();
 226
 227			ArrayList FileArray = new ArrayList();
 228
 229			//TODO: 「新しいウィンドウで開く」="/new"などの引数も含まれるので、
 230			//       その辺りの処理も将来的に入れる。
 231
 232			//コマンドラインでファイルが投げ込まれてきている
 233			//Launch with arguments
 234			string[] cmds = System.Environment.GetCommandLineArgs();
 235			for (int i = 1; i < cmds.Count(); i++)
 236			{
 237				if (File.Exists(cmds[i]) == true)
 238				{
 239					FileArray.Add(cmds[i]);
 240				}
 241			}
 242
 243			try
 244			{
 245				if (FileArray.Count > 1)
 246				{	//"問い合わせ"
 247					//"複数のファイルが読み込まれました。\n現在の設定内容でHTMLファイルへの一括変換を行いますか?
 248					//「いいえ」を選択するとそのまますべてのファイル開きます。"
 249					//"Question"
 250					//"More than one were read.\nDo you wish to convert all files to HTML files on this options?\n
 251					// if you select 'No', all files will be opend without converting."
 252					DialogResult ret = MessageBox.Show(Resources.MsgConvertAllFilesToHTML,
 253					Resources.DialogTitleQuestion, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information);
 254
 255					if (ret == DialogResult.Yes)
 256					{ //一括でHTMLファイル出力
 257						//Output HTML files in batch process
 258						BatchOutputToHtmlFiles((String[])FileArray.ToArray(typeof(string)));
 259						return;
 260
 261					}
 262					else if (ret == DialogResult.Cancel)
 263					{	//キャンセル
 264						//Cancel
 265						return;
 266					}
 267					else
 268					{	//「いいえ」
 269						// "NO" button
 270						bool fOpen = false;
 271						foreach (string FilePath in FileArray)
 272						{	//最初のファイルだけ、このウィンドウだけ開く
 273							//First file open in this window 
 274							if (fOpen == false)
 275							{
 276								richTextBox1.Modified = false;
 277								OpenFile(FilePath);
 278								fOpen = true;
 279							}
 280							else
 281							{	//他の複数ファイルは順次新しいウィンドウで開く
 282								//Other files open in new windows
 283								System.Diagnostics.Process.Start(
 284									Application.ExecutablePath, string.Format("{0}", FilePath));
 285							}
 286						}
 287					}
 288				}
 289				else if (FileArray.Count == 1)
 290				{
 291					richTextBox1.Modified = false;
 292					OpenFile((string)FileArray[0]);
 293				}
 294				else
 295				{ //前に編集していたファイルがあればそれを開く
 296					//Open it if there is editing file before
 297					if (MarkDownSharpEditor.AppSettings.Instance.fOpenEditFileBefore == true)
 298					{
 299						if (MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles.Count > 0)
 300						{
 301							AppHistory EditedFilePath = new AppHistory();
 302							EditedFilePath = (AppHistory)MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles[0];
 303							if (File.Exists(EditedFilePath.md) == true)
 304							{
 305								_TemporaryHtmlFilePath = "";
 306								richTextBox1.Modified = false;
 307								OpenFile(EditedFilePath.md);
 308								return;
 309							}
 310						}
 311					}
 312					if (_MarkDownTextFilePath == "")
 313					{	//無ければ「無題」ファイル
 314						// "No title" if no file exists
 315						richTextBox1.Modified = false;
 316						OpenFile("");
 317					}
 318				}
 319			}
 320			finally
 321			{
 322				_fConstraintChange = false;
 323				//SyntaxHighlighter
 324				if (backgroundWorker2.IsBusy == false)
 325				{
 326					//backgroundWorker2.WorkerReportsProgress = true;
 327					backgroundWorker2.RunWorkerAsync(richTextBox1.Text);
 328				}
 329				richTextBox1.Modified = false;
 330				//フォームタイトル更新 / Refresh form caption
 331				FormTextChange();
 332			}
 333		}
 334
 335		//----------------------------------------------------------------------
 336		// フォームタイトルの表示(更新)
 337		// Refresh form caption
 338		//----------------------------------------------------------------------
 339		private void FormTextChange()
 340		{
 341			string FileName;
 342			if (_fNoTitle == true)
 343			{
 344				FileName = Resources.NoFileName; //"(無題)" "(No title)"
 345			}
 346			else
 347			{
 348				//FileName = System.IO.Path.GetFileName(_MarkDownTextFilePath);
 349				FileName = _MarkDownTextFilePath;
 350			}
 351
 352			if (richTextBox1.Modified == true)
 353			{
 354				FileName = FileName + Resources.FlagChanged; //"(更新)"; "(Changed)"
 355			}
 356			this.Text = FileName + " - " + Application.ProductName;
 357		}
 358
 359		//----------------------------------------------------------------------
 360		// 見出しリストメニューの表示
 361		//----------------------------------------------------------------------
 362		private void mnuShowHeaderListMenu_Click(object sender, EventArgs e)
 363		{
 364			ShowHeaderListContextMenu();
 365		}
 366
 367		//----------------------------------------------------------------------
 368		// 見出しリストメニューの表示
 369		//----------------------------------------------------------------------
 370
 371		void ShowHeaderListContextMenu()
 372		{
 373
 374			int retCode;
 375
 376			//Markdown
 377			object[][] mkObject = {
 378				new object[2] { 1, @"^#[^#]*?$" },     //見出し1 (headline1)
 379				new object[2] { 1, @"^.*\n=+$" },      //見出し1 (headline1)
 380				new object[2] { 2, @"^##[^#]*?$" },    //見出し2 (headline2)
 381				new object[2] { 2, @"^.+\n-+$" },      //見出し2 (headline2)
 382				new object[2] { 3, @"^###[^#]*?$" },   //見出し3 (headline3)
 383				new object[2] { 4, @"^####[^#]*?$" },  //見出し4 (headline4)
 384				new object[2] { 5, @"^#####[^#]*?$" }, //見出し5 (headline5)
 385				new object[2] { 6, @"^######[^#]*?$"}  //見出し6 (headline6)
 386			};
 387
 388			//コンテキストメニュー項目を初期化(クリア)
 389			//Clear context menus
 390			contextMenu2.Items.Clear();
 391
 392			bool fModify = richTextBox1.Modified;
 393			_fConstraintChange = true;
 394
 395			//現在のカーソル位置
 396			//Current cursor position
 397			int selectStart = this.richTextBox1.SelectionStart;
 398			int selectEnd = richTextBox1.SelectionLength;
 399			Point CurrentOffset = richTextBox1.AutoScrollOffset;
 400
 401			//現在のスクロール位置
 402			//Current scroll position
 403			int CurrentScrollPos = richTextBox1.VerticalPosition;
 404			//描画停止
 405			//Stop to update
 406			richTextBox1.BeginUpdate();
 407
 408			for (int i = 0; i < mkObject.Length; i++)
 409			{
 410
 411				Regex r = new Regex((string)mkObject[i][1], RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Compiled);
 412				MatchCollection col = r.Matches(richTextBox1.Text, 0);
 413
 414				if (col.Count > 0)
 415				{
 416					foreach (Match m in col)
 417					{
 418						int IndexNum = m.Groups[0].Index;
 419						string title = new String(' ', (int)mkObject[i][0]) + richTextBox1.Text.Substring(m.Groups[0].Index, m.Groups[0].Length);
 420
 421						if ((retCode = title.LastIndexOf("\n")) > -1)
 422						{
 423							title = title.Substring(0, title.LastIndexOf("\n"));
 424						}
 425
 426						//コンテキストメニューに登録
 427						//Regist item to context menus
 428						bool fAdd = false;
 429						ToolStripMenuItem item = new ToolStripMenuItem();
 430						for (int c = 0; c < contextMenu2.Items.Count; c++)
 431						{
 432							//登録されている項目よりも前の項目のときは挿入する
 433							//Insert item to registed items
 434							if (IndexNum < (int)contextMenu2.Items[c].Tag)
 435							{
 436								item.Text = title;
 437								item.Tag = IndexNum;
 438								contextMenu2.Items.Insert(c, item);
 439								fAdd = true;
 440								break;
 441							}
 442						}
 443						if (fAdd == false)
 444						{
 445							item.Text = title;
 446							item.Tag = IndexNum;
 447							contextMenu2.Items.Add(item);
 448						}
 449					}
 450				}
 451			}
 452
 453			//カーソル位置を戻す
 454			//Restore cursor position
 455			richTextBox1.Select(selectStart, selectEnd);
 456			richTextBox1.AutoScrollOffset = CurrentOffset;
 457
 458			//描画再開
 459			//Resume to update
 460			richTextBox1.EndUpdate();
 461			richTextBox1.Modified = fModify;
 462
 463			_fConstraintChange = false;
 464
 465			//richTextBox1のキャレット位置
 466			//Curret position in richTextBox1
 467			Point pt = richTextBox1.GetPositionFromCharIndex(richTextBox1.SelectionStart);
 468			//スクリーン座標に変換
 469			//Convert the position to screen position
 470			pt = richTextBox1.PointToScreen(pt);
 471			//コンテキストメニューを表示
 472			//View context menus
 473			contextMenu2.Show(pt);
 474
 475		}
 476
 477		//----------------------------------------------------------------------
 478		// 見出しメニュークリックイベント
 479		// Click event in context menus
 480		//----------------------------------------------------------------------
 481		private void contextMenu2_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
 482		{
 483
 484			if ((int)e.ClickedItem.Tag > 0)
 485			{
 486				richTextBox1.SelectionStart = (int)e.ClickedItem.Tag;
 487				richTextBox1.ScrollToCaret();
 488			}
 489
 490		}
 491
 492		//----------------------------------------------------------------------
 493		// HACK: RichTextBox内容変更 [ シンタックス・ハイライター表示)]
 494		//       Apply richTextBox1 to syntax highlight with changing
 495		//----------------------------------------------------------------------
 496		private void richTextBox1_TextChanged(object sender, EventArgs e)
 497		{
 498
 499			if (_fConstraintChange == true)
 500			{
 501				return;
 502			}
 503
 504			if (backgroundWorker2.IsBusy == false)
 505			{
 506				//バックグラウンドワーカーへパースを投げる / SyntaxHightlighter on BackgroundWorker
 507				backgroundWorker2.RunWorkerAsync(richTextBox1.Text);
 508			}
 509
 510			//-----------------------------------
 511			//Formキャプション変更 / Change form caption
 512			FormTextChange();
 513
 514			//-----------------------------------
 515			//ブラウザプレビュー制御 / Preview webBrowser component
 516			if (MarkDownSharpEditor.AppSettings.Instance.fAutoBrowserPreview == true)
 517			{
 518				timer1.Enabled = true;
 519			}
 520
 521		}
 522
 523		//----------------------------------------------------------------------
 524		// RichTextBox Key Press
 525		//----------------------------------------------------------------------
 526		private void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
 527		{
 528			//-----------------------------------
 529			// Add undo buffer
 530			//-----------------------------------
 531
 532			//現在のUndoCounterから先を削除
 533			//Remove first item of undo counter
 534			if (undoCounter < UndoBuffer.Count)
 535			{
 536				UndoBuffer.RemoveRange(undoCounter, UndoBuffer.Count - undoCounter);
 537			}
 538
 539			UndoBuffer.Add(richTextBox1.Rtf);
 540			undoCounter = UndoBuffer.Count;
 541
 542			//EnterやEscapeキーでビープ音が鳴らないようにする
 543			//Stop to beep in Enter & Escape key
 544			if (e.KeyChar == (char)Keys.Enter || e.KeyChar == (char)Keys.Escape)
 545			{
 546				e.Handled = true;
 547			}
 548
 549			timer2.Enabled = true;
 550
 551		}
 552		
 553		//----------------------------------------------------------------------
 554		// RichTextBox VScroll event
 555		//----------------------------------------------------------------------
 556		private void richTextBox1_VScroll(object sender, EventArgs e)
 557		{
 558			if (_fConstraintChange == false)
 559			{
 560				WebBrowserMoveCursor();
 561			}
 562		}
 563
 564		//----------------------------------------------------------------------
 565		// RichTextBox Enter event
 566		//----------------------------------------------------------------------
 567		private void richTextBox1_Enter(object sender, EventArgs e)
 568		{
 569			//ブラウザプレビュー制御 / Preview webBrowser component
 570			if (MarkDownSharpEditor.AppSettings.Instance.fAutoBrowserPreview == true)
 571			{
 572				timer1.Enabled = true;
 573			}
 574		}
 575
 576		//----------------------------------------------------------------------
 577		// RichTextBox Mouse click
 578		//----------------------------------------------------------------------
 579		private void richTextBox1_MouseClick(object sender, MouseEventArgs e)
 580		{
 581
 582			//timer1.Enabled = true;
 583
 584		}
 585
 586		//----------------------------------------------------------------------
 587		// Form Closing event
 588		//----------------------------------------------------------------------
 589		private void Form1_FormClosing(object sender, FormClosingEventArgs e)
 590		{
 591			if (richTextBox1.Modified == true)
 592			{
 593				//"問い合わせ"
 594				//"編集中のファイルがあります。保存してから終了しますか?"
 595				//"Question"
 596				//"This file being edited. Do you wish to save before exiting?"
 597				DialogResult ret = MessageBox.Show(Resources.MsgSaveFileToEnd,
 598				Resources.DialogTitleQuestion, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
 599
 600				if (ret == DialogResult.Yes)
 601				{
 602					if (SaveToEditingFile() == true)
 603					{
 604						_fNoTitle = false;
 605					}
 606					else
 607					{
 608						//キャンセルで抜けてきた
 609						//user cancel
 610						e.Cancel = true;
 611						return;
 612					}
 613				}
 614				else if (ret == DialogResult.Cancel)
 615				{
 616					e.Cancel = true;
 617					return;
 618				}
 619			}
 620
 621			_fConstraintChange = true;
 622
 623			//無題ファイルのまま編集しているのなら削除
 624			//Delete file if the file is no title
 625			if (_fNoTitle == true)
 626			{
 627				if (File.Exists(_MarkDownTextFilePath) == true)
 628				{
 629					try
 630					{
 631						File.Delete(_MarkDownTextFilePath);
 632					}
 633					catch
 634					{
 635					}
 636				}
 637			}
 638
 639			//データバージョン
 640			//Data version
 641			System.Reflection.Assembly asmbly = System.Reflection.Assembly.GetExecutingAssembly();
 642			System.Version ver = asmbly.GetName().Version;
 643			MarkDownSharpEditor.AppSettings.Instance.Version = ver.Major * 1000 + ver.Minor * 100 + ver.Build * 10 + ver.Revision;
 644
 645			//フォーム位置・サイズ ( Form position & size )
 646			if (this.WindowState == FormWindowState.Minimized)
 647			{	//最小化 ( Minimize )
 648				MarkDownSharpEditor.AppSettings.Instance.FormState = 1;
 649				//一時記憶していた位置・サイズを保存 ( Save temporary position & size value )
 650				MarkDownSharpEditor.AppSettings.Instance.FormPos = new Point(_preFormPos.X, _preFormPos.Y);
 651				MarkDownSharpEditor.AppSettings.Instance.FormSize = new Size(_preFormSize.Width, _preFormSize.Height);
 652			}
 653			else if (this.WindowState == FormWindowState.Maximized)
 654			{	//最大化 ( Maximize )
 655				MarkDownSharpEditor.AppSettings.Instance.FormState = 2;
 656				//一時記憶していた位置・サイズを保存 ( Save temporary position & size value )
 657				MarkDownSharpEditor.AppSettings.Instance.FormPos = new Point(_preFormPos.X, _preFormPos.Y);
 658				MarkDownSharpEditor.AppSettings.Instance.FormSize = new Size(_preFormSize.Width, _preFormSize.Height);
 659			}
 660			else
 661			{	//通常 ( Normal window )
 662				MarkDownSharpEditor.AppSettings.Instance.FormState = 0;
 663				MarkDownSharpEditor.AppSettings.Instance.FormPos = new Point(this.Left, this.Top);
 664				MarkDownSharpEditor.AppSettings.Instance.FormSize = new Size(this.Width, this.Height);
 665			}
 666
 667			MarkDownSharpEditor.AppSettings.Instance.richEditWidth = this.richTextBox1.Width;
 668			FontConverter fc = new FontConverter();
 669			MarkDownSharpEditor.AppSettings.Instance.FontFormat = fc.ConvertToString(richTextBox1.Font);
 670			MarkDownSharpEditor.AppSettings.Instance.richEditForeColor = richTextBox1.ForeColor.ToArgb();
 671
 672			//表示オプションなど
 673			//Save view options etc
 674			MarkDownSharpEditor.AppSettings.Instance.fViewToolBar = this.menuViewToolBar.Checked;
 675			MarkDownSharpEditor.AppSettings.Instance.fViewStatusBar = this.menuViewStatusBar.Checked;
 676			MarkDownSharpEditor.AppSettings.Instance.fSplitBarWidthEvenly = this.menuViewWidthEvenly.Checked;
 677
 678			//検索オプション
 679			//Save search options
 680			MarkDownSharpEditor.AppSettings.Instance.fSearchOptionIgnoreCase = chkOptionCase.Checked ? false : true;
 681
 682			if (File.Exists(_MarkDownTextFilePath) == true)
 683			{
 684				//編集中のファイルパス
 685				//Save editing file path
 686				foreach (AppHistory data in MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles)
 687				{
 688					if (data.md == _MarkDownTextFilePath)
 689					{ //いったん削除して ( delete once ... )
 690						MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles.Remove(data);
 691						break;
 692					}
 693				}
 694				AppHistory HistroyData = new AppHistory();
 695				HistroyData.md = _MarkDownTextFilePath;
 696				HistroyData.css = _SelectedCssFilePath;
 697				MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles.Insert(0, HistroyData);	//先頭に挿入 ( Insert at the top )
 698			}
 699
 700			//設定の保存
 701			//Save settings
 702			MarkDownSharpEditor.AppSettings.Instance.SaveToXMLFile();
 703			//MarkDownSharpEditor.AppSettings.Instance.SaveToJsonFile();
 704
 705			timer1.Enabled = false;
 706
 707			//webBrowser1.Navigate("about:blank");
 708			//クリック音対策
 709			//Constraint click sounds
 710			if (webBrowser1.Document != null)
 711			{
 712				webBrowser1.Document.OpenNew(true);
 713				webBrowser1.Document.Write("");
 714			}
 715		}
 716
 717		//-----------------------------------
 718		// Form closed event
 719		//-----------------------------------
 720		private void Form1_FormClosed(object sender, FormClosedEventArgs e)
 721		{
 722			//テンポラリファイルの削除
 723			//Delete temporary files
 724			Delete_TemporaryHtmlFilePath();
 725		}
 726
 727		//-----------------------------------
 728		// Form resize begin event
 729		//-----------------------------------
 730		private void Form1_ResizeBegin(object sender, EventArgs e)
 731		{
 732			//リサイズ前の位置・サイズを一時記憶
 733			_preFormPos.X = this.Left;
 734			_preFormPos.Y = this.Top;
 735			_preFormSize.Width = this.Width;
 736			_preFormSize.Height = this.Height;
 737		}
 738
 739		//-----------------------------------
 740		// Form resize end event
 741		//-----------------------------------
 742		private void Form1_ResizeEnd(object sender, EventArgs e)
 743		{
 744			//ソースウィンドウとビューウィンドウを均等にするか
 745			//Equalize width of source window and view window
 746			if (menuViewWidthEvenly.Checked == true)
 747			{
 748				this.richTextBox1.Width =
 749					(splitContainer1.Width - splitContainer1.SplitterWidth) / 2;
 750			}
 751		}
 752
 753		//-----------------------------------
 754		// richTextBox1 DragEnter event
 755		//-----------------------------------
 756		private void richTextBox1_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
 757		{
 758			if (e.Data.GetDataPresent(DataFormats.FileDrop) == true)
 759			{
 760				e.Effect = DragDropEffects.Copy;
 761			}
 762			else
 763			{
 764				e.Effect = DragDropEffects.None;
 765			}
 766		}
 767
 768		//-----------------------------------
 769		// richTextBox1 Drag and Drop event
 770		//-----------------------------------
 771		private void richTextBox1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
 772		{
 773			string[] FileArray = (string[])e.Data.GetData(DataFormats.FileDrop, false);
 774			if (FileArray.Length > 1)
 775			{
 776				if (FileArray.Length > 0)
 777				{
 778					//"問い合わせ"
 779					//"複数のファイルが読み込まれました。\n現在の設定内容でHTMLファイルへの一括変換を行いますか?
 780					//「いいえ」を選択するとそのまますべてのファイル開きます。"
 781					//"Question"
 782					//"More than one were read.\nDo you wish to convert all files to HTML files on this options?\n
 783					// if you select 'No', all files will be opend without converting."
 784					DialogResult ret = MessageBox.Show("MsgConvertAllFilesToHTML",
 785					Resources.DialogTitleQuestion, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information);
 786
 787					if (ret == DialogResult.Yes)
 788					{
 789						//一括でHTMLファイル出力
 790						//Output HTML files in batch process
 791						BatchOutputToHtmlFiles(FileArray);
 792						return;
 793
 794					}
 795					else if (ret == DialogResult.Cancel)
 796					{
 797						//キャンセル
 798						//Cancel
 799						return;
 800					}
 801					else
 802					{	//「いいえ」
 803						// "No" button
 804						bool fOpen = false;
 805						foreach (string FilePath in FileArray)
 806						{
 807							//最初のファイルだけ、このウィンドウだけ開く
 808							//First file open in this window 
 809							if (fOpen == false)
 810							{
 811								OpenFile(FilePath);
 812								fOpen = true;
 813							}
 814							else
 815							{
 816								//他の複数ファイルは順次新しいウィンドウで開く
 817								//Other files open in new windows
 818								System.Diagnostics.Process.Start(
 819									Application.ExecutablePath, string.Format("{0}", FilePath));
 820							}
 821						}
 822					}
 823				}
 824				else
 825				{
 826					//前に編集していたファイルがあればそれを開く
 827					//Open it if there is editing file before
 828					if (MarkDownSharpEditor.AppSettings.Instance.fOpenEditFileBefore == true)
 829					{
 830						if (MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles.Count > 0)
 831						{
 832							AppHistory EditedFilePath = new AppHistory();
 833							EditedFilePath = (AppHistory)MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles[0];
 834
 835							if (File.Exists(EditedFilePath.md) == true)
 836							{
 837								OpenFile(EditedFilePath.md);
 838							}
 839						}
 840					}
 841				}
 842				_fConstraintChange = false;
 843				//フォームタイトル更新
 844				//Refresh form caption
 845				FormTextChange();
 846
 847				ArrayList ArrayFileList = new ArrayList();
 848				foreach (string FilePath in FileArray)
 849				{
 850					ArrayFileList.Add(FilePath);
 851				}
 852
 853				BatchOutputToHtmlFiles((String[])ArrayFileList.ToArray(typeof(string)));
 854
 855			}
 856			else if (FileArray.Count() == 1)
 857			{
 858				//ファイルが一個の場合は編集中のウィンドウで開く
 859				//Open it in this window if file is one 
 860				OpenFile(FileArray[0]);
 861			}
 862		}
 863
 864		//----------------------------------------------------------------------
 865		// OpenFile [ .mdファイルを開く ]
 866		//----------------------------------------------------------------------
 867		private bool OpenFile(string FilePath, bool fOpenDialog = false)
 868		{
 869			//引数 FilePath = "" の場合は「無題」編集で開始する
 870			// Argument "FilePath" = "" => Start editing in 'no title'
 871
 872			if (FilePath == "")
 873			{
 874				_fNoTitle = true;  // No title flag
 875			}
 876			else
 877			{
 878				_fNoTitle = false;
 879			}
 880
 881			//-----------------------------------
 882			//編集中のファイルがある
 883			if (richTextBox1.Modified == true)
 884			{
 885				//"問い合わせ"
 886				//"編集中のファイルがあります。保存してから終了しますか?"
 887				//"Question"
 888				//"This file being edited. Do you wish to save before exiting?"
 889				DialogResult ret = MessageBox.Show(Resources.MsgSaveFileToEnd,
 890				Resources.DialogTitleQuestion, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
 891				if (ret == DialogResult.Yes)
 892				{
 893					if (SaveToEditingFile() == false)
 894					{
 895						//キャンセルで抜けてきた
 896						//Cancel
 897						return (false);
 898					}
 899				}
 900				else if (ret == DialogResult.Cancel)
 901				{
 902					return (false);
 903				}
 904
 905				//編集履歴に残す
 906				//Save file path to editing history
 907				foreach (AppHistory data in MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles)
 908				{
 909					if (data.md == _MarkDownTextFilePath)
 910					{   //いったん削除して ( delete once ... )
 911						MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles.Remove(data);
 912						break;
 913					}
 914				}
 915				AppHistory HistroyData = new AppHistory();
 916				HistroyData.md = _MarkDownTextFilePath;
 917				HistroyData.css = _SelectedCssFilePath;
 918				MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles.Insert(0, HistroyData);	//先頭に挿入 ( Insert at the top )
 919			}
 920
 921			//-----------------------------------
 922			//オープンダイアログ表示
 923			//View open file dialog
 924			if (fOpenDialog == true)
 925			{
 926				if (File.Exists(_MarkDownTextFilePath) == true)
 927				{	//編集中のファイルがあればそのディレクトリを初期フォルダーに
 928					//Set parent directory of editing file to initial folder 
 929					openFileDialog1.InitialDirectory = Path.GetDirectoryName(_MarkDownTextFilePath);
 930					//テンポラリファイルがあればここで削除
 931					//Delete it if temporary file exists
 932					Delete_TemporaryHtmlFilePath();
 933				}
 934				openFileDialog1.FileName = "";
 935				if (openFileDialog1.ShowDialog() == DialogResult.OK)
 936				{
 937					FilePath = openFileDialog1.FileName;
 938					_fNoTitle = false;
 939				}
 940				else
 941				{
 942					return (false);
 943				}
 944			}
 945
 946			//編集中のファイルパスとする
 947			//Set this file to 'editing file' path
 948			_MarkDownTextFilePath = FilePath;
 949
 950			//-----------------------------------
 951			//文字コードを調査するためにテキストファイルを開く
 952			//Detect encoding
 953			if (_fNoTitle == false)
 954			{
 955				byte[] bs;
 956				using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read))
 957				{
 958					bs = new byte[fs.Length];
 959					fs.Read(bs, 0, bs.Length);
 960				}
 961				//文字コードを取得する
 962				//Get charcter encoding
 963				_EditingFileEncoding = GetCode(bs);
 964			}
 965			else
 966			{
 967				//「無題」はデフォルトのエンコーディング
 968				// Set this file to default encoding in 'No title'
 969				_EditingFileEncoding = Encoding.UTF8;
 970			}
 971
 972			//ステータスバーに表示
 973			//View in statusbar
 974			toolStripStatusLabelTextEncoding.Text = _EditingFileEncoding.EncodingName;
 975			//編集中のエンコーディングを使用する(&D)か
 976			//Use encoding of editing file
 977			if (MarkDownSharpEditor.AppSettings.Instance.HtmlEncodingOption == 0)
 978			{
 979				toolStripStatusLabelHtmlEncoding.Text = _EditingFileEncoding.EncodingName;
 980			}
 981
 982			//-----------------------------------
 983			//ペアとなるCSSファイルがあるか探索してあれば適用する
 984			//Apply that the pair CSS file to this file exists
 985			foreach (AppHistory data in MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles)
 986			{
 987				if (data.md == _MarkDownTextFilePath)
 988				{
 989					if (File.Exists(data.css) == true)
 990					{
 991						_SelectedCssFilePath = data.css;
 992						break;
 993					}
 994				}
 995			}
 996
 997			//選択中のCSSファイル名をステータスバーに表示
 998			//View selected CSS file name to stausbar
 999			if (File.Exists(_SelectedCssFilePath) == true)
1000			{
1001				toolStripStatusLabelCssFileName.Text = Path.GetFileName(_SelectedCssFilePath);
1002			}
1003			else
1004			{
1005				toolStripStatusLabelCssFileName.Text = Resources.toolTipCssFileName; //"CSSファイル指定なし"; ( not selected CSS file)
1006			}
1007
1008			_fConstraintChange = true;
1009			richTextBox1.Clear();
1010
1011			//RichEditBoxの「フォント」設定
1012			// richTextBox1 font name setting
1013			var obj = MarkDownSharpEditor.AppSettings.Instance;
1014			FontConverter fc = new FontConverter();
1015			try { richTextBox1.Font = (Font)fc.ConvertFromString(obj.FontFormat); }
1016			catch { }
1017			//RichEditBoxの「フォントカラー」設定
1018			// richTextBox1 font color setting
1019			richTextBox1.ForeColor = Color.FromArgb(obj.richEditForeColor);
1020			//View them in statusbar
1021			toolStripStatusLabelFontInfo.Text = richTextBox1.Font.Name + "," + richTextBox1.Font.Size.ToString() + "pt";
1022
1023			//-----------------------------------
1024			//テキストファイルの読み込み
1025			//Read text file
1026			if (File.Exists(FilePath) == true)
1027			{
1028				richTextBox1.Text = File.ReadAllText(FilePath, _EditingFileEncoding);
1029			}
1030			richTextBox1.BeginUpdate();
1031			richTextBox1.SelectionStart = richTextBox1.Text.Length;
1032			richTextBox1.ScrollToCaret();
1033			//richTextBox1の全高さを求める
1034			//Get height of richTextBox1 ( for webBrowser sync )
1035			_richEditBoxInternalHeight = richTextBox1.VerticalPosition;
1036			//カーソル位置を戻す
1037			//Restore cursor position
1038			richTextBox1.SelectionStart = 0;
1039			richTextBox1.EndUpdate();
1040
1041			//変更フラグOFF
1042			richTextBox1.Modified = false;
1043
1044			//Undoバッファに追加
1045			//Add all text to undo buffer
1046			UndoBuffer.Clear();
1047			UndoBuffer.Add(richTextBox1.Rtf);
1048			undoCounter = UndoBuffer.Count;
1049			
1050			//プレビュー更新
1051			PreviewToBrowser();
1052
1053			_fConstraintChange = false;
1054			FormTextChange();
1055
1056			return (true);
1057
1058		}
1059
1060		//----------------------------------------------------------------------
1061		// 表示するHTMLのテンポラリファイルパスを取得する
1062		// Get temporary HTML file path
1063		//----------------------------------------------------------------------
1064		private string Get_TemporaryHtmlFilePath(string FilePath)
1065		{
1066			string DirPath = Path.GetDirectoryName(FilePath);
1067			string FileName = Path.GetFileNameWithoutExtension(FilePath);
1068
1069			MD5 md5Hash = MD5.Create();
1070			byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(FileName));
1071			StringBuilder sBuilder = new StringBuilder();
1072			for (int i = 0; i < data.Length; i++)
1073			{
1074				sBuilder.Append(data[i].ToString("x2"));
1075			}
1076			return (Path.Combine(DirPath, FileName + "_" + sBuilder.ToString() + ".html"));
1077		}
1078
1079		//----------------------------------------------------------------------
1080		// 表示しているHTMLのテンポラリファイルを削除する
1081		// Delete temporary HTML file
1082		//----------------------------------------------------------------------
1083		private void Delete_TemporaryHtmlFilePath()
1084		{
1085			string TempHtmlFilePath;
1086
1087			if (_MarkDownTextFilePath == "")
1088			{
1089				return;
1090			}
1091
1092			TempHtmlFilePath = Get_TemporaryHtmlFilePath(_MarkDownTextFilePath);
1093			//見つかったときだけ削除
1094			//Delete it if the file exists
1095			if (File.Exists(TempHtmlFilePath) == true)
1096			{
1097				try
1098				{
1099					File.Delete(TempHtmlFilePath);
1100				}
1101				catch
1102				{
1103					//"エラー"
1104					//"テンポラリファイルの削除に失敗しました。編集中の場所に残った可能性があります。
1105					//"このファイルは手動で削除していただいても問題ありません。
1106					//"Error"
1107					//"Error during deleting temporary file!\na temporary file may be left in the folder the file is edited.\n"
1108					// This file is not a problem even if you delete it manually.
1109					MessageBox.Show(Resources.MsgErrorDeleteTemporaryFile + TempHtmlFilePath,
1110						Resources.DialogTitleError, MessageBoxButtons.OK, MessageBoxIcon.Error);
1111				}
1112			}
1113		}
1114
1115		//----------------------------------------------------------------------
1116		// ブラウザープレビューの間隔を調整
1117		// Ajust browser preview interval 
1118		//----------------------------------------------------------------------
1119		private void timer1_Tick(object sender, EventArgs e)
1120		{
1121			PreviewToBrowser();
1122			timer1.Enabled = false;
1123		}
1124
1125		private void timer2_Tick(object sender, EventArgs e)
1126		{
1127			timer2.Enabled = false;
1128		}
1129
1130		//----------------------------------------------------------------------
1131		// HACK: PreviewToBrowser [ ブラウザプレビュー ]
1132		//----------------------------------------------------------------------
1133		private void PreviewToBrowser()
1134		{
1135			//更新抑制中のときはプレビューしない
1136			//Do not preview in constraint to change
1137			if (_fConstraintChange == true)
1138			{
1139				return;
1140			}
1141			if (backgroundWorker1.IsBusy == true)
1142			{
1143				return;
1144			}
1145
1146			string ResultText = "";
1147			backgroundWorker1.WorkerReportsProgress = true;
1148			//編集箇所にマーカーを挿入する
1149			//Insert marker in editing
1150			if (richTextBox1.SelectionStart > 0)
1151			{
1152				//int NextLineNum = richTextBox1.GetLineFromCharIndex(richTextBox1.SelectionStart) + 1;
1153				int ParagraphStart = richTextBox1.GetFirstCharIndexOfCurrentLine();
1154				//if (ParagraphStart == 0)
1155				//{
1156				//	ParagraphStart = 1;
1157				//}
1158				ResultText =
1159					richTextBox1.Text.Substring(0, ParagraphStart) + "<!-- edit -->" +
1160					richTextBox1.Text.Substring(ParagraphStart);
1161			}
1162			else
1163			{
1164				ResultText = richTextBox1.Text;
1165			}
1166			backgroundWorker1.RunWorkerAsync(ResultText);
1167
1168		}
1169
1170		//----------------------------------------------------------------------
1171		// BackgroundWorker ProgressChanged
1172		//----------------------------------------------------------------------
1173		private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
1174		{
1175			//ProgressBar1.Value = e.ProgressPercentage;
1176			//Label1.Text = e.ProgressPercentage.ToString();
1177		}
1178
1179		//----------------------------------------------------------------------
1180		// BackgroundWorker browser preview
1181		//----------------------------------------------------------------------
1182		private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
1183		{
1184			string ResultText = (string)e.Argument;
1185			string MkResultText = "";
1186
1187			string BackgroundColorString;
1188			string EncodingName;
1189
1190			//編集中のファイル名
1191			//Editing file name
1192			string FileName = (_MarkDownTextFilePath == "" ? "" : Path.GetFileName(_MarkDownTextFilePath));
1193			//DOCTYPE
1194			HtmlHeader htmlHeader = new HtmlHeader();
1195			string DocType = htmlHeader.GetHtmlHeader(MarkDownSharpEditor.AppSettings.Instance.HtmlDocType);
1196
1197			//マーキングの色づけ
1198			//Marker's color
1199			if (MarkDownSharpEditor.AppSettings.Instance.fHtmlHighLightColor == true)
1200			{
1201				Color ColorBackground = Color.FromArgb(MarkDownSharpEditor.AppSettings.Instance.HtmlHighLightColor);
1202				BackgroundColorString = ColorTranslator.ToHtml(ColorBackground);
1203			}
1204			else
1205			{
1206				BackgroundColorString = "none";
1207			}
1208
1209			//指定のエンコーディング
1210			//Codepage
1211			int CodePageNum = MarkDownSharpEditor.AppSettings.Instance.CodePageNumber;
1212			try
1213			{
1214				Encoding enc = Encoding.GetEncoding(CodePageNum);
1215				//ブラウザ表示に対応したエンコーディングか
1216				//Is the encoding supported browser?
1217				if (enc.IsBrowserDisplay == true)
1218				{
1219					EncodingName = enc.WebName;
1220				}
1221				else
1222				{
1223					EncodingName = "utf-8";
1224				}
1225			}
1226			catch
1227			{
1228				//エンコーディングの取得に失敗した場合
1229				//Default encoding if failing to get encoding
1230				EncodingName = "utf-8";
1231			}
1232			//Header
1233			string header = string.Format(
1234@"{0}
1235<html>
1236<head>
1237<meta http-equiv='Content-Type' content='text/html; charset={1}' />
1238<link rel='stylesheet' href='{2}' type='text/css' />
1239<style type='text/css'>
1240	 ._mk {{background-color:{3}}}
1241</style>
1242<title>{4}</title>
1243</head>
1244<body>
1245",
1246			DocType,               //DOCTYPE
1247			EncodingName,          //エンコーディング ( encoding )
1248			_SelectedCssFilePath,   //適用中のCSSファイル ( Selected CSS file )
1249			BackgroundColorString, //編集箇所の背景色 ( background color in Editing )
1250			FileName);             //タイトル(=ファイル名) ( title = file name )
1251
1252			//Footer
1253			string footer = "</body>\n</html>";
1254
1255			//-----------------------------------
1256			//Markdown parse ( default )
1257			//Markdown mkdwn = new Markdown();
1258			//-----------------------------------
1259
1260			//-----------------------------------
1261			// MarkdownDeep
1262			// Create an instance of Markdown
1263			//-----------------------------------
1264			var mkdwn = new MarkdownDeep.Markdown();
1265			// Set options
1266			mkdwn.ExtraMode = MarkDownSharpEditor.AppSettings.Instance.fMarkdownExtraMode;
1267			mkdwn.SafeMode = false;
1268			//-----------------------------------
1269
1270			ResultText = mkdwn.Transform(ResultText);
1271			//表示するHTMLデータを作成
1272			//Creat HTML data
1273			ResultText = header + ResultText + footer;
1274
1275			//パースされた内容から編集行を探す
1276			//Search editing line in parsed data
1277			string OneLine;
1278			StringReader sr = new StringReader(ResultText);
1279			StringWriter sw = new StringWriter();
1280			while ((OneLine = sr.ReadLine()) != null)
1281			{
1282				if (OneLine.IndexOf("<!-- edit -->") >= 0)
1283				{
1284					MkResultText += ("<div class='_mk'>" + OneLine + "</div>\n");
1285				}
1286				else
1287				{
1288					MkResultText += (OneLine + "\n");
1289				}
1290			}
1291
1292			//エンコーディングしつつbyte値に変換する(richEditBoxは基本的にutf-8 = 65001)
1293			//Encode and convert it to 'byte' value ( richEditBox default encoding is utf-8 = 65001 )
1294			byte[] bytesData = Encoding.GetEncoding(CodePageNum).GetBytes(MkResultText);
1295
1296			//-----------------------------------
1297			// Write to temporay file
1298			if (_fNoTitle == false)
1299			{
1300				//テンポラリファイルパスを取得する
1301				//Get temporary file path
1302				if (_TemporaryHtmlFilePath == "")
1303				{
1304					_TemporaryHtmlFilePath = Get_TemporaryHtmlFilePath(_MarkDownTextFilePath);
1305				}
1306				//他のプロセスからのテンポラリファイルの参照と削除を許可して開く(でないと飛ぶ)
1307				//Open temporary file to allow references from other processes
1308				using (FileStream fs = new FileStream(
1309					_TemporaryHtmlFilePath,
1310					FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read | FileShare.Delete))
1311				{
1312					fs.Write(bytesData, 0, bytesData.Length);
1313					e.Result = _TemporaryHtmlFilePath;
1314				}
1315			}
1316			//-----------------------------------
1317			// Navigate and view in browser
1318			else
1319			{
1320				//Write data as it is, if the editing data is no title  
1321				ResultText = Encoding.GetEncoding(CodePageNum).GetString(bytesData);
1322				e.Result = ResultText;
1323			}
1324
1325		}
1326
1327		private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
1328		{
1329			if (e.Error != null)
1330			{
1331				//Error!
1332			}
1333			else
1334			{
1335				if ((string)e.Result != "")
1336				{
1337					//-----------------------------------
1338					//スクロールバーの位置を退避しておく
1339					//Memorize scroll positions
1340					HtmlDocument doc = webBrowser1.Document;
1341					Point scrollpos = new Point(0, 0);
1342					if (doc == null)
1343					{
1344						webBrowser1.Navigate("about:blank");
1345					}
1346					else
1347					{
1348						IHTMLDocument3 doc3 = (IHTMLDocument3)webBrowser1.Document.DomDocument;
1349						IHTMLElement2 elm = (IHTMLElement2)doc3.documentElement;
1350						scrollpos = new Point(elm.scrollLeft, elm.scrollTop);
1351					}
1352					//-----------------------------------
1353					System.Threading.Tasks.Task waitTask;
1354					if (_fNoTitle == false)
1355					{
1356						//ナビゲート
1357						//Browser navigate
1358						//webBrowser1.Navigate(@"file://" + (string)e.Result);
1359						waitTask = WebBrowserNavigate(@"file://" + (string)e.Result);
1360						richTextBox1.Focus();
1361						toolStripButtonBrowserPreview.Enabled = true;
1362					}
1363					else
1364					{
1365						webBrowser1.Document.OpenNew(true);
1366						//webBrowser1.Document.Write((string)e.Result);
1367						waitTask = WebBrowserDocumentWrite((string)e.Result);
1368						//ツールバーの「関連付けられたブラウザーを起動」を無効に
1369						//"Associated web browser" in toolbar is invalid
1370						toolStripButtonBrowserPreview.Enabled = false;
1371					}
1372					//-----------------------------------
1373					//スクロールバーの位置を復帰する
1374					//Restore scroll bar position
1375					if (doc != null)
1376					{
1377						waitTask.ContinueWith((arg1) =>
1378						{
1379							this.BeginInvoke(new Action(() =>
1380							{
1381								doc.Window.ScrollTo(scrollpos);
1382
1383								this.webBrowser1.Document.Body.AttachEventHandler("onscroll", OnScrollEventHandler);
1384
1385							}));
1386						});
1387					}
1388				}
1389			}
1390		}
1391		/// <summary>
1392		/// webBrowser コンポーネントにHTMLを出力して 
1393		/// DocumentComplate になるのを非同期で待ち合わせる
1394		/// </summary>
1395		/// <param name="html"></param>
1396		/// <returns></returns>
1397		System.Threading.Tasks.Task WebBrowserDocumentWrite(string html)
1398		{
1399			if (browserWaitTimer == null)
1400			{
1401				browserWaitTimer = new Timer();
1402				browserWaitTimer.Tick += browserWaitTimer_Tick;
1403				browserWaitTimer.Enabled = true;
1404			}
1405			var obj = waitObject;
1406			if (obj != null)
1407			{
1408				obj.SetCanceled();
1409			}
1410			waitObject = new System.Threading.Tasks.TaskCompletionSource<string>();
1411
1412			timerCount = 0;
1413
1414			this.webBrowser1.DocumentText = html;
1415
1416			browserWaitTimer.Enabled = true;
1417
1418			return waitObject.Task;
1419		}
1420
1421		/// <summary>
1422		/// webBrowser コンポーネントにHTMLを出力して 
1423		/// DocumentComplate になるのを非同期で待ち合わせる
1424		/// </summary>
1425		/// <param name="html"></param>
1426		/// <returns></returns>
1427		System.Threading.Tasks.Task WebBrowserNavigate(string url)
1428		{
1429			if (browserWaitTimer == null)
1430			{
1431				browserWaitTimer = new Timer();
1432				browserWaitTimer.Tick += browserWaitTimer_Tick;
1433				browserWaitTimer.Enabled = true;
1434			}
1435			var obj = waitObject;
1436			if (obj != null)
1437			{
1438				obj.SetCanceled();
1439			}
1440			waitObject = new System.Threading.Tasks.TaskCompletionSource<string>();
1441
1442			timerCount = 0;
1443
1444			this.webBrowser1.Navigate(url);
1445
1446			browserWaitTimer.Enabled = true;
1447
1448			return waitObject.Task;
1449		}
1450
1451		void browserWaitTimer_Tick(object sender, EventArgs e)
1452		{
1453			if (waitObject == null)
1454			{
1455				browserWaitTimer.Enabled = false;
1456				return;
1457			}
1458
1459			timerCount++;
1460
1461			if (this.webBrowser1.ReadyState == WebBrowserReadyState.Complete)
1462			{
1463				waitObject.SetResult("OK");
1464				waitObject = null;
1465				browserWaitTimer.Enabled = false;
1466			}
1467			else if (timerCount > 20)
1468			{
1469				// 反応ないので終わりにする
1470				waitObject.SetResult("OK");
1471				waitObject = null;
1472				browserWaitTimer.Enabled = false;
1473			}
1474		}
1475
1476		System.Threading.Tasks.TaskCompletionSource<string> waitObject = null;
1477		int timerCount = 0;
1478		Timer browserWaitTimer;
1479
1480		//----------------------------------------------------------------------
1481		// BackgroundWorker Syntax hightlighter work
1482		//----------------------------------------------------------------------
1483		private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
1484		{
1485			var text = e.Argument as string;
1486			if (string.IsNullOrEmpty(text))
1487			{
1488				e.Result = null;
1489				return;
1490			}
1491			if (timer2.Enabled == true)
1492			{
1493				e.Result = null;
1494				return;
1495			}
1496
1497			var result = new List<SyntaxColorScheme>();
1498			foreach (MarkdownSyntaxKeyword mk in _MarkdownSyntaxKeywordAarray)
1499			{
1500				MatchCollection col = mk.Regex.Matches(text, 0);
1501				
1502				if (col.Count > 0)
1503				{
1504					foreach (Match m in col)
1505					{
1506						SyntaxColorScheme sytx = new SyntaxColorScheme();
1507						sytx.SelectionStartIndex = m.Groups[0].Index;
1508						sytx.SelectionLength = m.Groups[0].Length;
1509						sytx.ForeColor = mk.ForeColor;
1510						sytx.BackColor = mk.BackColor;
1511						result.Add(sytx);
1512					}
1513				}
1514			}
1515			e.Result = result;
1516		}
1517		//----------------------------------------------------------------------
1518		// BackgroundWorker Editor Syntax hightlighter progress changed
1519		//----------------------------------------------------------------------
1520		private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
1521		{
1522
1523		}
1524		//-------------------------------------------------------…

Large files files are truncated, but you can click here to view the full file