1using System.Collections.ObjectModel;
47 internal const string DefaultCss =
".card { font-family: Arial; font-size: 20px; text-align: center; color: black; background: white; }";
49 private readonly List<AnkiField> fields = [];
50 private readonly List<AnkiCardTemplate> templates = [];
51 private readonly ReadOnlyCollection<AnkiField> fieldsView;
52 private readonly ReadOnlyCollection<AnkiCardTemplate> templatesView;
53 private string css = DefaultCss;
54 private bool isFrozen;
73 ArgumentException.ThrowIfNullOrWhiteSpace(name);
77 fieldsView = fields.AsReadOnly();
78 templatesView = templates.AsReadOnly();
88 public long Id {
get; }
92 public string Name {
get; }
112 ArgumentNullException.ThrowIfNull(value);
135 public IReadOnlyList<AnkiField>
Fields => fieldsView;
143 public IReadOnlyList<AnkiCardTemplate>
Templates => templatesView;
158 ArgumentException.ThrowIfNullOrWhiteSpace(name);
159 if (fields.Any(field =>
string.Equals(field.Name, name, StringComparison.OrdinalIgnoreCase)))
161 throw new ArgumentException($
"Field '{name}' already exists.", nameof(name));
185 ArgumentNullException.ThrowIfNull(field);
186 ArgumentException.ThrowIfNullOrWhiteSpace(field.
Name);
187 ArgumentException.ThrowIfNullOrWhiteSpace(field.
Font);
188 ArgumentOutOfRangeException.ThrowIfLessThan(field.
FontSize, 1);
189 if (fields.Any(existing =>
string.Equals(existing.Name, field.
Name, StringComparison.OrdinalIgnoreCase)))
191 throw new ArgumentException($
"Field '{field.Name}' already exists.", nameof(field));
213 ArgumentException.ThrowIfNullOrWhiteSpace(name);
214 ArgumentNullException.ThrowIfNull(questionFormat);
215 ArgumentNullException.ThrowIfNull(answerFormat);
216 if (templates.Any(
template =>
string.Equals(
template.Name, name, StringComparison.OrdinalIgnoreCase)))
218 throw new ArgumentException($
"Template '{name}' already exists.", nameof(name));
245 ArgumentNullException.ThrowIfNull(
template);
246 ArgumentException.ThrowIfNullOrWhiteSpace(
template.
Name);
247 ArgumentNullException.ThrowIfNull(
template.QuestionFormat);
248 ArgumentNullException.ThrowIfNull(
template.AnswerFormat);
249 if (templates.Any(existing =>
string.Equals(existing.Name,
template.Name, StringComparison.OrdinalIgnoreCase)))
251 throw new ArgumentException($
"Template '{template.Name}' already exists.", nameof(
template));
254 templates.Add(
template);
258 internal bool HasEquivalentDefinition(
AnkiNoteType other) =>
259 string.Equals(
Name, other.
Name, StringComparison.Ordinal)
260 &&
Kind == other.Kind
261 &&
string.Equals(
Css, other.
Css, StringComparison.Ordinal)
262 && fields.SequenceEqual(other.fields)
263 && templates.SequenceEqual(other.templates);
265 internal void Freeze() => isFrozen =
true;
267 private void EnsureMutable()
271 throw new InvalidOperationException($
"Note type '{Name}' is frozen because it is already used by a note.");
Defines one study direction by mapping note fields to a card front and back.
Configures one named input field in an AnkiNoteType.
int FontSize
Gets the note-editor font-size preference in pixels, not the rendered card size.
string Font
Gets the note-editor font-family preference, not the rendered card font.
string Name
Gets the exact field name used by note values and template references.
Creates positive 64-bit identifiers for new objects or repeatable external imports.
static long New()
Creates a positive, process-unique identifier for a new deck, note type, note, or card.
Defines the reusable schema and rendering rules shared by a family of Anki notes.
AnkiNoteTypeKind Kind
Gets the immutable strategy used to turn one note into cards.
AnkiNoteType AddConfiguredTemplate(AnkiCardTemplate template)
Adds a configured card template at the next card ordinal.
AnkiNoteType AddTemplate(string name, string questionFormat, string answerFormat)
Adds a card template at the next ordinal.
bool IsFrozen
Gets whether fields, templates, and CSS can no longer be changed.
AnkiNoteType(string name, AnkiNoteTypeKind kind=AnkiNoteTypeKind.Standard, long? id=null)
Initializes an unfrozen note type with no fields or templates and default card CSS.
IReadOnlyList< AnkiCardTemplate > Templates
Gets templates in zero-based card-ordinal order.
string Css
Gets or sets CSS shared by every card rendered from this note type.
long Id
Gets the persisted identity by which notes and package metadata refer to this definition.
AnkiNoteType AddField(string name)
Adds a uniquely named field at the end of the field order.
IReadOnlyList< AnkiField > Fields
Gets fields in positional storage and Anki-editor order.
AnkiNoteType AddConfiguredField(AnkiField field)
Adds a configured field at the end of the field order.
string Name
Gets the user-visible note-type name.
AnkiNoteTypeKind
Specifies how an AnkiNoteType turns one note into study cards.