public void ParseText(string text, List <ProjectAsset> assets) { text = PreProcLine(text); // preprocessor to make linewraping more convenient text = text.Replace(@"\wrap", @"\\\wrap\\") .Replace(@"\break", @"\\\break\\") //.Replace(@"\reading", @"\\\reading") //.Replace(@"\sermon", @"\\\sermon") //.Replace(@"\image", @"\\\image") //.Replace(@"\fullimage", @"\\\fullimage") //.Replace(@"\fitimage", @"\\\fitimage") .Replace(@"\apostlescreed", @"\\\apostlescreed\\") .Replace(@"\nicenecreed", @"\\\nicenecreed") .Replace(@"\lordsprayer", @"\\\lordsprayer\\") .Replace(@"\morningprayer", @"\\\morningprayer") .Replace(@"\copyright", @"\\\copyright\\") .Replace(@"\viewseries", @"\\\viewseries\\") .Replace(@"\viewservices", @"\\\viewservices\\") .Replace(@"\hymn", @"\\\hymn"); // replace functions text = Regex.Replace(text, @"(?<funct>\\\w+\(.*\))", @"\\\\${funct}\\\\", RegexOptions.Multiline); var lines = text.Split(new[] { @"\\" }, StringSplitOptions.RemoveEmptyEntries).ToList(); // try to intelligently split lines by newlines after punctuation // remove 'empty' lines (new lines) //lines = lines.Where(s => s != "\n") //.Where(s => s != "\r\n") //.Where(s => s != Environment.NewLine).ToList(); lines = lines.Where(s => !Regex.Match(s, @"^\s$", RegexOptions.None).Success).ToList(); lines = lines.Where(s => s.Trim() != string.Empty).Select(s => s.Trim()).ToList(); foreach (var line in lines) { string tl = line.Trim().Replace(Environment.NewLine, " ").Replace("\n", " ").Replace("\r", " ").Replace("\r\n", " "); if (tl.StartsWith(@"\break")) { TypesetCommand cmd = new TypesetCommand() { Command = Command.NewSlide }; LineData.Add(cmd); continue; } if (tl.StartsWith(@"\wrap")) { TypesetCommand cmd = new TypesetCommand() { Command = Command.WrapSpeakerText }; LineData.Add(cmd); continue; } if (tl.StartsWith(@"\video")) { try { // add a non-rendered slide to copy video output to slides var matches = Regex.Match(tl, @"\\video\((?<name>.*)\)"); RenderVideo rc = new RenderVideo(); rc.Asset = assets.First(s => s.Name == matches.Groups["name"].Value); LineData.Add(rc); } catch (Exception) { } continue; } // typeset the reading on a new slide // expected params are comma delimited // eg. \reading(<Title>,<Reference>) if (tl.StartsWith(@"\reading")) { //var contents = tl.Split(new char[] { '(', ',', ')' }, 4, StringSplitOptions.RemoveEmptyEntries); var a = tl.Split('(')[1]; var b = a.Split(')')[0]; var contents = b.Split(new char[] { ',' }, 2, StringSplitOptions.RemoveEmptyEntries); ReadingLine rl = new ReadingLine() { Title = contents[0].Trim(), Reference = contents[1].Trim() }; LineData.Add(rl); continue; } if (tl.StartsWith(@"\sermon")) { var matches = Regex.Match(tl, @"\\sermon\((?<title>.*),(?<source>.*)\)"); SermonTitle sermonTitle = new SermonTitle() { Title = "Sermon", SermonName = matches.Groups["title"].Value, SermonText = matches.Groups["source"].Value }; LineData.Add(sermonTitle); continue; } if (tl.StartsWith(@"\image")) { var args = tl.Split('(', ',', ')'); InlineImage inlineImage = new InlineImage(); inlineImage.ImageAsset = assets.Find(a => a.Name == args[1]); inlineImage.AutoScale = args[2] == "fill"; LineData.Add(inlineImage); continue; } if (tl.StartsWith(@"\fullimage")) { var args = tl.Split('(', ')'); Fullimage img = new Fullimage(); img.ImageAsset = assets.Find(a => a.Name == args[1]); LineData.Add(img); continue; } if (tl.StartsWith(@"\fitimage")) { var args = tl.Split('(', ')'); Fullimage img = new Fullimage(); img.ImageAsset = assets.Find(a => a.Name == args[1]); img.Streach = false; LineData.Add(img); continue; } if (tl.StartsWith(@"\apostlescreed")) { Fullimage ac = new Fullimage(); ac.ImageAsset = new ProjectAsset(); ac.ImageAsset.Image = Properties.Resources.apostlescreed; ac.ImageAsset.Name = "Apostle Creed - Prerendered"; ac.Streach = true; LineData.Add(ac); continue; } if (tl.StartsWith(@"\nicenecreed")) { TypesetCommand cmd = new TypesetCommand() { Command = Command.NewSlide }; LineData.Add(cmd); continue; } if (tl.StartsWith(@"\lordsprayer")) { Fullimage ac = new Fullimage(); ac.ImageAsset = new ProjectAsset(); ac.ImageAsset.Image = Properties.Resources.lordsprayer; ac.ImageAsset.Name = "Lords Prayer - Prerendered"; ac.Streach = true; LineData.Add(ac); continue; } if (tl.StartsWith(@"\viewseries")) { Fullimage ac = new Fullimage(); ac.ImageAsset = new ProjectAsset(); ac.ImageAsset.Image = Properties.Resources.sessions; ac.ImageAsset.Name = "View Series - Prerendered"; ac.Streach = true; LineData.Add(ac); continue; } if (tl.StartsWith(@"\viewservices")) { Fullimage ac = new Fullimage(); ac.ImageAsset = new ProjectAsset(); ac.ImageAsset.Image = Properties.Resources.services; ac.ImageAsset.Name = "View Services - Prerendered"; ac.Streach = true; LineData.Add(ac); continue; } if (tl.StartsWith(@"\copyright")) { Fullimage ac = new Fullimage(); ac.ImageAsset = new ProjectAsset(); ac.ImageAsset.Image = Properties.Resources.copyright; ac.ImageAsset.Name = "Copyright1 - Prerendered"; ac.Streach = true; LineData.Add(ac); continue; } if (tl.StartsWith(@"\morningprayer")) { TypesetCommand cmd = new TypesetCommand() { Command = Command.NewSlide }; LineData.Add(cmd); continue; } if (tl.StartsWith(@"\hymn")) { TypesetCommand cmd = new TypesetCommand() { Command = Command.NewSlide }; LineData.Add(cmd); continue; } LiturgyLine l = new LiturgyLine(); if (tl.StartsWith("P")) { l.Text = tl.Replace(" T ", " + ").Substring(1).Trim(); l.Speaker = Speaker.Pastor; } else if (tl.StartsWith("L")) { l.Text = tl.Replace(" T ", " + ").Substring(1).Trim(); l.Speaker = Speaker.Leader; } else if (tl.StartsWith("C")) { l.Text = tl.Replace(" T ", " + ").Substring(1).Trim(); l.Speaker = Speaker.Congregation; } else if (tl.StartsWith("A")) { l.Text = tl.Replace(" T ", " + ").Substring(1).Trim(); l.Speaker = Speaker.Assistant; } else { l.Text = tl.Trim(); l.Speaker = Speaker.None; } l.IsSubsplit = false; LineData.Add(l); } }
public RenderSlide TypesetSlide(RenderSlide slide, TextRenderer r) { LiturgyLine line = this; // update state if not in wrapmode if (!r.LLState.SpeakerWrap) { r.LLState.LastSpeaker = line.Speaker; } else { line.Speaker = r.LLState.LastSpeaker; } // try to fit to current slide int lineheight = (int)Math.Ceiling(slide.gfx.MeasureString("CPALTgy", r.SpeakerFonts.TryGetVal(line.Speaker, r.Font)).Height); // check if whole line will fit SizeF s = slide.gfx.MeasureString(line.Text, r.SpeakerFonts.TryGetVal(line.Speaker, r.Font), r.TextboxRect.Width); if (slide.YOffset + s.Height <= r.TextboxRect.Height) { // it fits, add this line at position and compute RenderLine rl = new RenderLine() { Height = (int)s.Height, Width = (int)s.Width, ShowSpeaker = line.SubSplit == 0 || slide.Lines == 0, Speaker = line.Speaker, Text = line.Text, RenderX = 0, RenderY = 0, RenderLayoutMode = LayoutMode.Auto, LineNum = slide.Lines++, Font = r.SpeakerFonts.TryGetVal(line.Speaker, r.Font) }; slide.RenderLines.Add(rl); slide.YOffset += (int)s.Height; // wrap only works for one line r.LLState.SpeakerWrap = false; return(slide); } // if slide isn't blank, then try it on a blank slide if (!slide.Blank) { r.Slides.Add(r.FinalizeSlide(slide)); // wrap only works for one line r.LLState.SpeakerWrap = false; return(line.TypesetSlide(new RenderSlide() { Order = slide.Order + 1 }, r)); } // if doesn't fit on a blank slide // try to split into sentences. put as many sentences as fit on one slide until done // If have already split into sentences... split into chunks of words? if (line.IsSubsplit) { RenderSlide errorslide; if (!slide.Blank) { r.Slides.Add(r.FinalizeSlide(slide)); errorslide = new RenderSlide() { Order = slide.Order + 1 }; } else { errorslide = slide; } // for now abandon string emsg = "ERROR"; Size esize = slide.gfx.MeasureString(emsg, r.Font).ToSize(); RenderLine errorline = new RenderLine() { Height = esize.Height, Width = esize.Width, ShowSpeaker = r.LLState.SpeakerWrap, Speaker = Speaker.None, Text = emsg, RenderX = 0, RenderY = 0, RenderLayoutMode = LayoutMode.Auto, LineNum = 0, Font = r.Font, TextBrush = Brushes.Red }; errorslide.RenderLines.Add(errorline); r.Slides.Add(r.FinalizeSlide(errorslide)); // wrap only works for one line r.LLState.SpeakerWrap = false; return(new RenderSlide() { Order = errorslide.Order + 1 }); } // split line text into sentences var sentences = line.Text.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries); var tmp = Regex.Matches(line.Text, @"((?<sentence>[^\.;!?]+)(?<delimiter>[\.;!?])+)"); // keep trying to stuff a sentence List <LiturgyLine> sublines = new List <LiturgyLine>(); int splitnum = 0; foreach (var sentence in tmp) { // create a bunch of sub-liturgy-lines and try to typeset them all string t = sentence.ToString(); sublines.Add(new LiturgyLine() { Speaker = line.Speaker, Text = t.Trim(), SubSplit = splitnum++, IsSubsplit = true }); } foreach (var sl in sublines) { slide = sl.TypesetSlide(slide, r); } // wrap only works for one line r.LLState.SpeakerWrap = false; return(slide); }