/// <summary> /// Texts the list. /// </summary> /// <param name="items">The items.</param> /// <param name="options">The options.</param> /// <returns>System.String.</returns> public static string TextList(IEnumerable items, TextDumpOptions options) { options ??= new TextDumpOptions(); if (items is IDictionary <string, object> single) { items = new[] { single } } ; var depth = options.Depth; options.Depth += 1; try { var headerStyle = options.HeaderStyle; List <string> keys = null; var table = new MarkdownTable { IncludeRowNumbers = options.IncludeRowNumbers }; foreach (var item in items) { if (item is IDictionary <string, object> d) { if (keys == null) { keys = d.Keys.ToList(); foreach (var key in keys) { table.Headers.Add(ViewUtils.StyleText(key, headerStyle)); } } var row = new List <string>(); foreach (var key in keys) { var value = d[key]; if (ReferenceEquals(value, items)) { break; // Prevent cyclical deps like 'it' binding } if (!isComplexType(value)) { row.Add(GetScalarText(value, options.Defaults)); } else { var cellValue = TextDump(value, options); row.Add(cellValue); } } table.Rows.Add(row); } } var isEmpty = table.Rows.Count == 0; if (isEmpty) { return(options.CaptionIfEmpty ?? string.Empty); } var caption = options.Caption; if (caption != null && !options.HasCaption) { table.Caption = caption; options.HasCaption = true; } var txt = table.Render(); return(txt); } finally { options.Depth = depth; } }