//
// This code is part of Document Solutions for PDF demos.
// Copyright (c) MESCIUS inc. All rights reserved.
//
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Pdf.AI;
using DsPdfWeb.Demos.Common;
using System.Threading.Tasks;
namespace DsPdfWeb.Demos
{
// This sample generates a PDF with random content and uses the PDF AI Assistant (DsPdfAI)
// to analyze the document content and generate an outline tree (bookmarks) based on inferred headings,
// which is then added to the PDF.
//
// See PaginatedText for an example of using TextLayout for generating a multi-page PDF document.
//
// To run this sample locally, set your OpenAI credentials
// using Util.OpenAIToken.
public class AiLoremOutlines
{
public int CreatePDF(Stream stream)
{
var doc = GeneratePDF();
try
{
// Use the PDF AI Assistant to analyze the document content and generate outlines:
var a = new OpenAIDocumentAssistant(Util.OpenAIToken);
var task = a.BuildOutlines(doc);
task.Wait();
// Set the page mode so that a viewer shows the outlines (bookmarks) on PDF open:
doc.PageMode = PageMode.UseOutlines;
}
catch (Exception ex)
{
// Make sure you have assigned your OpenAI API key to Util.OpenAIToken:
Util.CreatePdfError(doc, ex.Message);
}
doc.Save(stream);
return doc.Pages.Count;
}
// Generate a PDF with random hierarchical content and return it:
GcPdfDocument GeneratePDF()
{
var doc = new GcPdfDocument();
var rnd = Util.NewRandom();
var tl = new TextLayout(72)
{
MaxWidth = doc.PageSize.Width,
MaxHeight = doc.PageSize.Height,
MarginAll = 72,
FirstLineIndent = 36,
};
tl.DefaultFormat.Font = StandardFonts.Times;
tl.DefaultFormat.FontSize = 12;
var fmtChapter = new TextFormat(tl.DefaultFormat) { FontSize = 18, FontBold = true };
var fmtSection = new TextFormat(tl.DefaultFormat) { FontSize = 16, FontBold = true };
var fmtSubSection = new TextFormat(tl.DefaultFormat) { FontSize = 14, FontBold = true };
var fmtNormal = new TextFormat(tl.DefaultFormat) { FontSize = 12 };
for (int i = 0; i < rnd.Next(2, 5); i++)
{
tl.Append($"Chapter {i + 1}: {Util.LoremIpsum(1, 1, 1, 1, 4).TrimEnd()}", fmtChapter);
tl.AppendParagraphBreak(fmtChapter);
for (int j = 0; j < rnd.Next(2, 4); j++)
{
tl.Append($"Section {i + 1}.{j + 1}: {Util.LoremIpsum(1, 1, 1, 1, 4).TrimEnd()}", fmtSection);
tl.AppendParagraphBreak(fmtSection);
for (int k = 0; k < rnd.Next(2, 3); k++)
{
tl.Append($"Sub-section {i + 1}.{j + 1}.{k + 1}: {Util.LoremIpsum(1, 1, 1, 1, 4).TrimEnd()}", fmtSubSection);
tl.AppendParagraphBreak(fmtSubSection);
tl.AppendLine(Util.LoremIpsum(1), fmtNormal);
}
}
}
// Split and render TextLayout as shown in the PaginatedText sample:
var tso = new TextSplitOptions(tl)
{
MinLinesInFirstParagraph = 2,
MinLinesInLastParagraph = 2,
};
tl.PerformLayout(true);
var tls = new TextLayoutSplitter(tl);
for (var tlPage = tls.Split(tso); tlPage != null; tlPage = tls.Split(tso))
doc.NewPage().Graphics.DrawTextLayout(tlPage, PointF.Empty);
return doc;
}
}
}