Convert - an app of SPPAS

Brigitte Bigi

User manual

Description

Annotated speech corpora circulate between tools. A corpus is transcribed in one software, aligned in another, analysed in a third, archived in a fourth. Each of these tools defines its own file format, and each format embodies a particular view of what an annotation is: a label on a point in time, a labelled interval, a hierarchy of tiers, a document carrying metadata. No format is a superset of the others. Moving annotations from one tool to another is therefore not a matter of translation, but of transposition: what the source expresses and the destination cannot hold has to be left behind.

This asymmetry is rarely visible to the people who depend on it. Annotation files are, for most of their users, opaque: opening one in a text editor reveals syntax, not structure. The user knows the corpus — the speakers, the tiers, the annotation scheme — but has no direct way to know whether the format they are exporting to is able to carry it. Conversion tools generally answer this by silence: either the operation succeeds, and the loss goes unnoticed, or it fails, and the reason belongs to the internals of the format rather than to anything the user can act upon.

The application "Convert" takes the opposite stance. Its purpose is not only to produce a file in another format, but to make the transposition itself intelligible. What a format is able to hold is stated before the conversion is launched, not discovered afterwards. What a format is unable to hold is expressed as a choice offered to the user, at the moment where the target format is selected, and applied uniformly to the whole set of files. What cannot be transposed at all is reported explicitly, file by file, with its cause.

This stance has a consequence on the shape of the tool. "Convert" operates on sets of files, heterogeneous in format and unknown in content at the time the user makes their decisions. It does not inspect a file in order to propose a tailored treatment; it lets the user state, once, how the annotations are to be written, and applies that decision to every file. The intelligibility "Convert" aims at is therefore not the intelligibility of a particular file, but of the destination format and of what reaching it costs.

"Convert" belongs to the SPPAS ecosystem and relies on its reading and writing capabilities, which cover a wide range of formats used in speech and multimodal annotation. It is available both as a page of the SPPAS Dashboard and as an online application, addressing the same need in two contexts of use: within a working session on a local corpus, or as an occasional service.

Accessibility is treated here as a functional requirement rather than an added quality: the information "Convert" exposes — supported properties, options, statuses — is of no use if it is not perceivable, and the tool is designed accordingly.

Defining the requirements

Problem statement and objectives

Converting annotation files raises a difficulty that is neither technical nor linguistic, but epistemic: the user must decide, before anything happens, what to do with information that the destination cannot receive. Formats differ in what they are able to express, and those differences are not documented anywhere the user is likely to look. The decision is therefore taken blindly, and its consequences appear only afterwards — as a file that fails to be written, or worse, as a file that is written and silently amputated.

The central problem addressed by "Convert" is thus:

how to let a user convert a set of annotation files to a chosen format, while making the cost of that choice knowable in advance and the outcome verifiable afterwards, without requiring any knowledge of how formats are internally organised.

This problem is sharpened by the conditions of use. Conversion is a batch operation: it applies to a set of files whose contents are not examined at the moment the user decides. It is also a directed operation: users convert because they are moving from one tool to another, with a definite destination in mind. Convert must therefore support decisions taken once, in ignorance of individual file contents, and applied uniformly — while remaining accountable for each file individually.

The objectives follow:

  • to let the user select one destination format among those that can be written, and to expose what that format is able to hold at the moment of the choice;
  • to let the user state, before conversion, how annotations are to be written when the destination cannot hold them as they are, these statements being attached to the format and not to any file;
  • to apply the same decisions to every file of the batch, and to report the outcome of each file separately, an individual failure never interrupting the others;
  • to give the user access to the converted files, in a manner adapted to the context of use;
  • to guarantee accessibility, of the interface and of the information the tool exposes;
  • to remain part of the SPPAS ecosystem, reusing its reading and writing capabilities without exposing them.

"Convert" does not aim to prepare files, to edit annotations, nor to correct a corpus. It aims to make one operation — writing annotations in another format — deliberate rather than accidental.

Expressing the requirements

Choosing a destination in full knowledge

A user selects a destination format because a tool downstream requires it, not because they know what that format can hold. The choice is therefore made under a constraint the user cannot evaluate. Convert answers this by presenting, alongside each writable format, the properties it supports — several tiers or one, metadata, hierarchies, controlled vocabularies, overlapping annotations, typed labels, and so on. This information is not documentation placed beside the tool; it is part of the act of choosing, available at the moment the decision is taken. Its presentation must make a comparison possible at a glance and remain legible to someone who has never opened an annotation file in an editor: the properties of a format are a technical matter, but understanding them must not require technical expertise.

Stating export options before reading anything

When a destination cannot hold what a source expresses, something must be decided. That decision belongs to the user, and it must be expressible without knowing which files will be affected: the batch is heterogeneous and its contents are not examined beforehand. Convert therefore attaches export options to the destination format itself. The options describe how to write, not what any file contains. Chosen once, they apply to the whole batch, and their meaning must be intelligible independently of any particular file.

Delimiting the set of files to convert

The files to be converted come from the working context, not from the tool: in a working session, they are the files currently selected in the workspace; in an occasional use, they are the files the user brings to the tool. The requirement is the same in both cases — the user delimits a set, Convert operates on that set, and the set is not silently altered. The two contexts differ only in their material constraints, an occasional use being bounded by what a service can reasonably receive.

Reporting each file individually

A batch is not an operation, but a series of operations sharing the same decisions. Some will succeed, some will not, for reasons belonging to the individual file rather than to the choices made. The user must be able to see, for every file, what happened to it: written, refused, or left untouched — and why. A refusal is stated in terms the user can act upon, and it never stops the files that follow. Reporting is therefore not a side effect of the conversion; it is what makes the operation verifiable.

Reaching the converted files

A conversion that produces files the user cannot find has not converted anything. In a working session, the produced files join the workspace and remain available to the following operations. In an occasional use, they are handed back to the user. The requirement is that the outcome be reachable without the user having to know where the tool put it.

Accessibility

Everything above rests on information being exposed: supported properties, available options, statuses, causes. This information is useless if it cannot be perceived. Contrast, legibility, text alternatives to any graphical encoding, keyboard operation, consistent terminology between the interface and the concepts it manipulates: these are conditions of the tool working at all, not qualities added to it. Convert exposes a technical subject to a non-technical audience; the burden of intelligibility lies entirely on the interface.

Modelling

Requirements

The previous sections state what users need and why; this section states what the system does to answer it, and what it manipulates in order to do so.

Two markers are used throughout. [API-OK] denotes what is achievable with the current SPPAS API. [API-EXT] denotes what requires an extension of that API. A requirement marked [API-EXT] is part of the model; it remains inactive until the API supports it.

Concepts manipulated by the application

Format
A way of writing annotations on disk, identified by an extension and associated with a piece of software.
Format property
A boolean characteristic of a format, stating what that format is able to hold. Properties belong to formats, never to files.
Destination format
The single format, among those that can be written, into which the batch is converted.
Batch
The set of files delimited by the user, heterogeneous in format, whose contents are unknown at the time decisions are taken.
Export option
A question raised by what the destination format cannot hold, together with the answers available for it. Options are derived from properties, not written per format. An option covers one property where answering alters the annotations, and several where it does not.
Answer
The user's decision for one option, applied to every file of the batch.
General option
A decision independent of the destination format: overriding an existing output, detecting the format of an input whose extension is unknown.
Remediation
A transformation applied to the annotations of one file, after reading and before writing, implementing the answer chosen for an option.
Structural loss
Information not written because the destination format cannot hold it. Determined by the destination alone, identical for the whole batch, announced once.
Contingent loss
Information not written, or content transformed, because of what one particular file contained. Determined at reading, reported for that file.
Status
The outcome of one file: written, written with remarks, refused, or skipped.
Remark
A contingent loss reported on one file.
Cause
The explicit reason a file was refused.

Deriving the options from the destination format

The correspondence between an unsupported property, the question it raises, and the answers available for it is data of the model, not code. Adding a property to the API adds an entry to this table; it does not modify Convert.

The options are of two kinds, and the line between them is whether answering alters the annotations. Some unsupported properties concern what surrounds the annotations — metadata, controlled vocabularies, media declarations. Keeping them changes nothing of what was annotated. Others concern the annotations themselves, or the shape of the result: answering transforms the content, or the number of files produced. The first kind is decided once; the second, property by property.

Preservation: one decision

Where the destination cannot hold metadata, controlled vocabularies or media declarations, the user is not asked where to put them, but whether to keep them:

The preservation option
Question raised Answers Properties covered
keep what the format cannot hold yes / no metadata, ctrl_vocab, media

Answering yes lets SPPAS write that information wherever the destination allows: as comments where the format holds them (a), in a tier otherwise (b). Answering no discards it. Where the destination allows neither, yes has the same effect as no, and the option is not offered.

The answer has a default no user has to look for: the setting of the application, interoperability, true [API-OK]. Maintaining interoperability is the normal state; accepting the loss is a choice.

That setting is a default, not the decision. It is global — it weighs on the annotations as much as on the conversions — while its effect is seen here, on a page a user reaches without ever opening the settings. Convert therefore states the effective answer where it applies, and lets it be changed for this conversion alone. Online, where no setting is kept for a given user, the value of the page is the only one there is.

Where SPPAS writes what it preserves is a mechanism, not a decision. Users divide into those who want their file and care for nothing else, and those who want nothing lost; neither arbitrates between metadata and controlled vocabularies. Offering three answers for each of three properties would ask nine questions no one has.

Structure: one decision per property

The remaining options alter the annotations or the shape of the result. They are decided individually, because answering one says nothing of the others:

Unsupported properties raising a structural option
Unsupported property Question raised Answers
multi_tiers several tiers in the file one file per tier / skip the file
point tiers of points convert into intervals / skip the tier
alt_tag alternative labels keep all / keep the best scored
tag_types typed labels convert into strings / skip the tier
tag_geometry geometric labels convert into strings / skip the tier

alt_tag belongs here and not to preservation: discarding the alternatives of a label, however poorly scored, alters the annotation. What is written is no longer what was annotated, and that is a decision only the user can take.

(a) The property accept_comments states it, read by comments_support() [API-OK]. The API was already writing metadata as comments when the format allows it, and forgetting them otherwise; it now exposes that capability.

(b) Writing metadata, controlled vocabularies and media as a tier is done by create_unsupported_tier(), and read back by parse_unsupported_tier() [API-OK]. The tier is named DoNotEdit; see the annex for what it holds.

Properties raising no question

The remaining unsupported properties raise no question, because nothing can be fabricated and no transformation preserves the content:

  • no_tiers — a file holding no tier at all cannot be written.
  • empty_tier [API-OK] — a tier holding no annotation is removed where the destination refuses it, which empty_tier_support() states beforehand; see 3.3.
  • interval — intervals cannot be reduced to points. A file holding intervals is refused. The converse is remediable, hence the point option above.
  • hierarchy, disjoint, alt_localization, radius, gaps, overlaps — cause a structural loss, announced once for the batch.

Extensions of the API required by this section

None: the three extensions this section was stating are available [API-OK]. They are empty_tier_support(), comments_support(), and the pair create_unsupported_tier() / parse_unsupported_tier(). The annex states what they do and what they cost.

Remediation chaining

Remediations are not independent, and their order is not neutral. Removing empty tiers can leave a file with no tier, which the destination may refuse. Splitting a multi-tier file into one file per tier can produce a file whose single tier is empty. A remediation is therefore never final: it produces a new content, which is verified again against the properties of the destination.

A chain may end in a refusal. This is not a failure of the model: it means the content, once adapted as far as the destination allows, still exceeds what that destination can hold. The cause reported is the one that ended the chain, stated in terms of the user's data.

Conversion of one file

Anticipation comes first; the typed exceptions of the API act as a safety net for what anticipation did not catch.

  1. Read the file, applying the general option on format detection.
  2. Anticipate: compare the content read to the properties of the destination, apply the remediations chosen, chain and re-verify (3.3).
  3. Write.
  4. If writing fails on a typed exception identifying a remediable cause, remediate and write once more. One second pass only.
  5. If it fails again, or on a non-remediable cause, refuse the file and state the cause.

The failure of one file never interrupts the batch.

The typed exceptions of the current API relevant to writing are AioMultiTiersError (1510), AioNoTiersError (1515), AioEmptyTierError (1525) and AioLocationTypeError (1530) [API-OK]. They identify refusals bound to the properties of the destination, and are usable as causes as they stand.

Requirements as specified

[010] Starting a conversion

  • [011] The user can initiate a conversion of a set of annotation files.
  • [012] The system initialises a conversion with no destination and no batch.

[020] Understanding the process

  • [021] The user can identify what is required before a conversion can run.
  • [022] The system states which decisions are missing.

[030] Controlled progression

  • [031] The system allows a conversion to run only if a destination format is selected and the batch is not empty.

[100] Destination format

  • [101] The user can select one destination format.
  • [102] The system restricts the choice to the formats it is able to write.
  • [103] The system presents, for each format, the properties it supports.
  • [104] The system presents this information in a form comparable at a glance and intelligible without knowledge of file internals.
  • [105] The user can select at most one destination format at a time.
  • [106] The user can cancel the current selection.

[200] Batch

  • [201] The user delimits the set of files to convert.
  • [202] The system operates on that set and does not alter it.
  • [203] The system reports when the set is empty.

[300] Export options

  • [301] The system derives the options from the properties of the selected destination format.
  • [302] The system presents an option for each unsupported property for which a remediation exists and answering alters the annotations, and a single option covering those for which it does not.
  • [303] The user can choose one answer per option.
  • [304] The system applies a default answer to any option left unanswered.
  • [305] The answers apply to every file of the batch.
  • [306] The options are stated before any file is read.
  • [307] The system restricts the answers offered to those the destination format allows.
  • [308] The system takes the answer of the preservation option from the settings of the application, states it on the page, and lets the user change it for this conversion without altering the settings.

[400] General options

  • [401] The user can allow or forbid overriding an existing output file.
  • [402] The user can allow or forbid detecting the format of an input file whose extension is unknown.

[500] Announcing structural loss

  • [501] The system announces, once for the batch, what the destination format cannot hold.
  • [502] The system does not report structural loss per file.

[600] Converting

  • [601] The system reads each file of the batch.
  • [602] The system applies the chosen remediations before writing.
  • [603] The system re-verifies the content against the destination after each remediation.
  • [604] The system writes each file in the destination format.
  • [605] The system attempts a second write after remediating a typed failure.
  • [606] The failure of one file never interrupts the batch.

[700] Reporting

  • [701] The system reports a status for every file of the batch.
  • [702] The system reports the remarks attached to a file.
  • [703] The system states the cause of every refusal.
  • [704] The system states the cause in terms of the user's data, not of the internals of the format.

[800] Reaching the results

  • [801] The system makes the converted files reachable to the user.
  • [802] The system makes them reachable without the user knowing where they were written.

[900] Restarting

  • [901] The user can start a new conversion.
  • [902] The system resets the decisions without resetting the batch.

[1000] UX and accessibility

  • [1001] The system provides text alternatives to any graphical encoding of a property.
  • [1002] The system uses consistent terminology between interface and concepts.
  • [1003] The system is operable by keyboard and by screen reader.
  • [1004] The system provides explicit messages at every decision point.

Simplified conceptual model

Convert holds no persistent data. Everything it manipulates belongs to one conversion in progress, and is derived from a small number of user decisions. This section states which data exist, what produces them, and what invalidates them.

Data manipulated

  • destination — one format, among those that can be written.
  • properties — the boolean characteristics of destination, stating what it is able to hold.
  • options — the questions raised by the unsupported properties for which a remediation exists, each with its available answers.
  • answers — one decision per option.
  • general_options — override (boolean), heuristic (boolean).
  • batch — a set of files, possibly empty.
  • structural_loss — what destination cannot hold.
  • results — one result per file of the batch, each holding a status ∈ {written, written with remarks, refused, skipped}, the remarks attached to it, and the cause of a refusal.

Main dependencies

  • destination → properties
  • properties → options
  • properties → structural_loss
  • options → answers
  • (batch ∧ destination ∧ answers ∧ general_options) → results

Treatments

T01 — Set the destination format

  • Purpose: define the format into which the batch is to be converted.
  • Inputs: user choice (one format).
  • Outputs: destination.
  • Preconditions: none.
  • Postconditions: destination is available to T02 and T06.
  • Rules:
    • the format must be one the system is able to write;
    • at most one destination is defined at a time;
    • the destination may be cancelled, leaving it undefined;
    • any change of destination invalidates properties, options, answers, structural_loss and results.

T02 — Derive the options and the structural loss

  • Purpose: state what the destination cannot hold, and which of it can be decided upon.
  • Inputs: destination.
  • Outputs: properties, options, structural_loss.
  • Preconditions: destination defined.
  • Postconditions: options are available to T03; structural_loss is available for announcement.
  • Rules:
    • the correspondence between an unsupported property, the question it raises and the answers available is data of the model, not code;
    • an unsupported property with no remediation produces no option and contributes to structural_loss;
    • the answers offered are restricted to those the destination allows, which may depend on other properties of that same destination;
    • structural_loss depends on the destination alone: it is identical for every file of the batch;
    • this treatment reads no file.

T03 — Answer the options

  • Purpose: decide how annotations are to be written when the destination cannot hold them as they are.
  • Inputs: options, user choices.
  • Outputs: answers.
  • Preconditions: options defined.
  • Postconditions: answers are available to T06.
  • Rules:
    • one answer per option, chosen among the answers that option offers;
    • an option left unanswered takes its default answer;
    • the answers apply to every file of the batch;
    • the answers are decided without any file being read;
    • any change of an answer invalidates results.

T04 — Set the general options

  • Purpose: decide what does not depend on the destination.
  • Inputs: user choices.
  • Outputs: general_options.
  • Preconditions: none.
  • Postconditions: general_options are available to T06.
  • Rules:
    • override states whether an existing output file may be replaced;
    • heuristic states whether the format of an input file whose extension is unknown may be detected;
    • both default to false;
    • any change invalidates results.

T05 — Delimit the batch

  • Purpose: define the set of files to convert.
  • Inputs: the working context.
  • Outputs: batch.
  • Preconditions: none.
  • Postconditions: batch is available to T06.
  • Rules:
    • the batch is delimited by the user, not by the system;
    • the system does not alter the batch;
    • the batch is heterogeneous in format and unknown in content;
    • the batch may be empty, which forbids T06;
    • any change of the batch invalidates results.

T06 — Produce the results

  • Purpose: write the annotations of every file of the batch in the destination format, and state what happened to each.
  • Inputs: batch, destination, answers, general_options.
  • Outputs: results, converted files.
  • Preconditions: destination defined; batch not empty; answers defined for every option.
  • Postconditions: every file of the batch holds a result; the converted files are reachable by the user.
  • Rules:
    • each file of the batch is treated independently; the failure of one never interrupts the others;
    • a file is read first, applying heuristic;
    • the content read is then compared to properties, and the remediations stated by answers are applied before writing;
    • a remediation produces a new content, which is verified again against properties; remediations therefore chain, and a chain may end in a refusal;
    • writing that fails on a typed cause for which a remediation exists is retried once, after that remediation; there is no further pass;
    • a file that cannot be written is refused, with a cause stated in terms of the user's data;
    • a file whose output already exists is skipped, unless override allows it;
    • a remediation that transformed the content of one file produces a remark on that file;
    • what destination cannot hold is not remarked per file: it belongs to structural_loss, announced once;
    • one file may produce several converted files;
    • this treatment does not alter the batch.

Implementation

This section states the principles retained for implementing Convert, in keeping with the requirements and the conceptual model, without prejudging detailed technical choices. Its purpose is to bind every implemented component to the requirement it satisfies.

Convert holds no persistent data of its own. Everything it manipulates belongs to one conversion in progress. The implementation is therefore organised around a chain of treatments, each producing clearly typed derived data, and each answering an identified requirement.

The implementation must keep a strict separation between:

  • the handling of user decisions (destination, answers, general options);
  • the knowledge of formats (properties, options, structural loss);
  • the transformation and writing of annotations (remediation, chaining, writing, retry);
  • the presentation of the interface and of the results.

Convert relies on the SPPAS reading and writing capabilities and never exposes them. It is served identically by the local SPPAS server and by uwsgi: the two deployments are one implementation, not two.

The batch is provided, not constituted

Convert does not select files. It receives a batch from its execution context and does not alter it. In a local session, that context is the SPPAS workspace, whose files are checked elsewhere, before Convert is reached: no file selection belongs to Convert. In an online use, the batch results from files brought by the user to the service.

Convert therefore depends on a provider of files, of which it requires only a contract:

  • it exposes a set of files, possibly empty;
  • Convert reads that set and never modifies it;
  • it exists in both contexts of execution.

No such component exists at the time of writing. It is not designed here: Convert is only its first use case, and designing it on a single use case would be premature. Convert depends on the contract above and on nothing more. Until that component exists, this dependency is satisfied ad hoc; the model is unaffected, since T05 states a provided batch, not a constituted one.

Organisation

Client-side triggers

  • Selecting the destination format
  • Cancelling the selected destination format
  • Answering an export option
  • Setting a general option
  • Requesting the conversion to run (triggers T06)
  • Requesting a new conversion (resets the decisions)

Selecting a destination triggers T02 and produces the options and the structural loss. This is a server request: the correspondence between properties and options is data of the model, and the client holds no knowledge of formats.

Navigation

Convert is a single page. The conversion is not a pathway in the sense TextCueS gives that word: there are no successive steps, but decisions taken in any order, and one operation which requires them. The page shows the formats, the options derived from the selected one, the general options, and the results once the conversion has run.

From the page:

  • one can select and cancel a destination without leaving it;
  • one can run a conversion, which replaces the results shown;
  • one can start a new conversion, which resets the decisions.

Implementation model: MVC

  • Model: knows the formats and performs T02 and T06. It is a façade over the SPPAS reading and writing capabilities.
  • Controller: identifies the task requested, checks its preconditions, chooses the treatment to run, invalidates the derived data, holds the transient state, calls the model, and prepares the data for display.
  • View: renders the state, collects the decisions, triggers the events. No business logic; JavaScript is rendering and interaction support only.

What receives a request is not the controller. The WhakerPy response handles the URL, receives the GET or POST and the events it carries, instantiates the controller, calls it once for that request, and bakes the returned tree — either a full page or an update payload. The controller is called; it does not listen.

The task to run is carried by the request, as an event. The controller reads it and handles it. This holds because Convert has one controller; an application with several would have to dispatch, which is not the case here.

Model

The model is the functional core. It holds the knowledge of formats and the transformation of annotations, and exposes neither to the rest of the application. The façade ConvertModel exposes the single interface the application expects and delegates to three specialised sub-models.

ModelFormats holds the knowledge of formats. It exposes the formats that can be written, their properties, and derives from a destination the options, their available answers, and the structural loss (T02). The correspondence between an unsupported property, the question it raises and the answers available is data it holds, not code it runs: adding a property to the SPPAS API adds an entry, and modifies nothing else. This sub-model reads no file.

ModelRemediation holds the transformations applied to annotations. Given a content and the properties of a destination, it states which remediations the answers require, applies them, and verifies the resulting content against those properties again — a remediation producing a new content, remediations chain, and a chain may end in a refusal. It also states which remediations transformed the content, so that remarks can be attached to the file. This sub-model reads and writes no file: it transforms annotations in memory. It is the place where the business logic of Convert lies, and it is testable on its own.

ModelConversion performs T06. For each file of the batch it reads, calls ModelRemediation, writes, retries once after remediating a typed failure, and produces the result of that file: its status, its remarks, the cause of a refusal. It never interrupts the batch, and one file may produce several converted files.

This structure lets the knowledge of formats, the transformation of annotations and the conversion of files evolve separately, behind one stable façade.

Controller

The controller is called once per request, in a stateless context. It initialises an empty state, then rebuilds the current state exclusively from the data transmitted to it. It identifies the task requested, checks its preconditions, calls the model, and prepares the data for display.

The controller handles invalidation. Any change of an upstream datum invalidates the data derived from it, which are then neither reused nor displayed: a change of destination invalidates the properties, the options, the answers, the structural loss and the results; a change of an answer, of a general option or of the batch invalidates the results. This invalidation is implicit: only the data explicitly transmitted and recomputed during the current request are used.

Tasks:

  • start — transmitted: nothing. Preconditions: none. Triggers: none. Produces: the page in its initial state, with the writable formats and no destination.
  • destination — transmitted: the destination. Preconditions: the format can be written. Triggers: T02. Produces: the options, their answers, the structural loss.
  • convert — transmitted: the destination, the answers, the general options. Preconditions: destination defined; batch not empty; every option answered, defaults applying to those left unanswered. Triggers: T06. Produces: the results.
  • reset — transmitted: nothing. Preconditions: none. Triggers: none. Produces: the page in its initial state. The batch is not reset: it belongs to the context, not to Convert.
Default answers

An option left unanswered takes a default. Two principles apply, in this order: the default reproduces the current behaviour of the SPPAS API where one exists; failing that, it takes no initiative.

Default answer per option
Option Default Reason
preservation yes current behaviour
multi_tiers skip the file no initiative
point skip the tier no initiative
alt_tag keep all current behaviour
tag_types skip the tier no initiative
tag_geometry skip the tier no initiative

Preservation defaults to yes because that is what the API does today: it writes as comments what a format cannot hold, wherever comments are allowed. Where the destination allows neither comments nor a tier, the option is not offered and the information is lost — which is, again, the current behaviour.

Where a precondition is not satisfied, the controller runs no treatment and states which decision is missing.

The controller is implemented by a single class ConvertController, exposing one entry point handle(request_data).

Views

As in TextCueS, the WhakerPy response builds the whole HTML tree and the structural elements common to the application — head, header, nav, footer — are factored there. The Convert views build only the content of body > main, and of body > script where support scripts are required. They create no structural element, handle no navigation, take no functional decision and perform no linguistic treatment.

Convert has one applicative view, ViewConvert, whose content varies with the data the controller transmits. It is built from five fragments, each with a defined scope.

The shape of these fragments follows from an observation about the users: they do not choose a destination format. They know it already — they are moving to Elan, to Praat, to subtitles — and they come to Convert to reach it. The properties of formats are therefore not there to help decide which format to pick; they are there to state what reaching the one already picked costs. The two are not served by the same presentation, and conflating them is what makes a matrix of formats by properties both indispensable and unreadable.

FragmentFormats presents the formats that can be written, and lets one of them be selected or cancelled. It is a list of extensions, grouped where grouping is possible: the extensions of one piece of software together, the subtitle formats together, the rest as they come. The grouping is heterogeneous by nature — Praat holds three extensions, some formats hold no software at all — and it exists only to let the user find what they came for. This fragment carries no property.

FragmentDestination presents what the selected format holds, and is where the export options are answered. It is an aside: consulting it is not leaving the list. It shows every property, always, in the same order, whatever the format selected. What varies from one format to the next is the state of each line, and whether a decision appears on it. A property has three states, and no more: held; not held, with nothing to decide; not held, with a decision to take. Preservation, covering several properties at once, appears as one line among them.

The stability of that list is what makes it usable. Labels that do not move let the user click from one format to another and see what changed, without reading again. It also answers requirement [104] without hiding anything: a scientific application states its data. Some properties are widely understood — several tiers, media, metadata — and others are specificities that exist almost nowhere but in SPPAS. The latter are made discreet, not absent.

FragmentCompare presents the full matrix of formats by properties, as a details element the user unfolds. This is the one place where formats are compared to one another, which is a legitimate thing to want and a poor way to choose a destination. Unfolded in place rather than opened as a dialog, because comparing is consulting, not deciding: the page stays where it is. Given the room a details element affords, the matrix can here be what it never is when it drives the choice — readable.

FragmentGeneral presents the general options.

FragmentResults presents the result of every file of the batch: its status, the remarks attached to it, and the cause of a refusal. It exists only once a conversion has run. One file of the batch may produce several converted files: the report is not a line per input file.

JavaScript is interface support. It handles local interactions — selecting a format, answering an option, refreshing the aside once a destination is known, refreshing the results — and transmits the state to the server. It holds no business logic and takes no decision on the treatments to run: it knows nothing of formats, of properties, or of what a remediation is. Which options a destination raises is derived by the model, server-side; the client displays what it is given.

The view serialises the current state at each user action. In a strictly stateless context, it transmits to the controller everything the requested treatment needs, without relying on any persistence, client-side or server-side.

The view carries the cross-cutting requirements: contrast, legibility, text alternatives to any graphical encoding, keyboard and screen-reader operation, consistent terminology between the interface and the concepts of the model, explicit messages at every decision point. Convert exposes a technical subject to a non-technical audience; the burden of intelligibility lies entirely here.

Annexes

Annex: Extensions of the SPPAS API

The model of Convert stated three requirements the SPPAS API did not cover. All three are available: they were added to sppas.src.anndata, and this annex now states what they are, what they hold, and what they cost. Nothing of the model is left waiting for the API.

E1 — accept_comments [API-OK]

What A boolean property of formats, stating whether a format is able to hold comments.
Why The API already writes metadata as comments where the format allows it, and forgets them otherwise. That capability is internal and not exposed. Convert cannot know whether preserving is possible, and therefore whether the option is worth offering.
Bound to The preservation option — section 3.2. Requirement [307].
Available as comments_support() of any reader-writer. The formats holding comments are txt, ctm, stm, arff and tdf; every other one answers False.

E2 — accept_empty_tier [API-OK]

What A boolean property of formats, stating whether a format is able to hold a tier carrying no annotation.
Why The API raises AioEmptyTierError (1525) when a format refuses an empty tier, but nothing states beforehand which formats do. The refusal is knowable only by attempting to write.
Bound to Anticipation and chaining — sections 3.3, 4.3 (T06). Requirements [602], [603].
Available as empty_tier_support() of any reader-writer. The formats holding an empty tier are the ones declaring their tiers apart from their annotations: xra, eaf, antx, ant, tei, mrk, and TextGrid — which writes such a tier as one interval with no text, adding an empty annotation rather than removing the tier.
Note Not to be confused with no_tiers, which states whether a format accepts a file holding no tier at all. Removing empty tiers can produce such a file: the two properties interact, which is why chaining re-verifies.

E3 — Writing metadata, controlled vocabularies and media as a tier [API-OK]

What The ability to write, into a tier of the output, what a format cannot hold as metadata, as a controlled vocabulary, or as a media declaration.
Why Where a destination holds neither the information nor comments, that information is currently lost. A tier is the one container every format holds by definition.
Bound to The preservation option — section 3.2.
Available as create_unsupported_tier() and parse_unsupported_tier(), with unsupported_entries() and fill_unsupported_entry() underneath — a reader holding the information its own way, as a comment for instance, fills the objects with the latter. Written by TextGrid, csv and mrk: the formats holding several tiers but neither metadata nor comments.
What it holds A tier named DoNotEdit, whose first annotation holds the keyword Metadata, then one annotation per key: the key, the value, the nature — metadata, ctrl_vocab or media — and the name of the tier it belongs to, one in each of its labels. The whole time span of the transcription is shared into intervals of equal duration. Reading it assigns the entries back to their object and removes the tier: it is a way to write, not data.
Decided by The settings of the application give the default: interoperability of sppasAppConfig, true. Each reader-writer takes it when created and holds it as its own, so a caller writing one file decides for that file only, with set_preserve_unsupported() — of the format, or of sppasTrsRW, which passes it on. The settings are left untouched. The tier is written only when there is something to preserve: what SPPAS assigns to any object it creates does not count.
What it costs csv and mrk write the labels of an annotation separated by a whitespace, so the whitespaces of the entries are turned into underscores and stay so when read back: an assumed loss, stated in the docstring of both. The descriptions of a controlled vocabulary and of its tags are not preserved.

What the current API already provides

For contrast, and to bound the extensions above, the following are available and require nothing:

  • the list of formats and, for each, whether it can be read and written;
  • the boolean properties of formats, which Convert derives its options from;
  • typed and numbered exceptions on writing — AioMultiTiersError (1510), AioNoTiersError (1515), AioEmptyTierError (1525), AioLocationTypeError (1530) — usable as causes of a refusal as they stand;
  • overriding an existing output, and detecting the format of an input whose extension is unknown.

Annex: Mockup of the interface

This annex is not a picture of the page. It is the page — the fragment below is HTML, styled by Whakerexa, rendered here by the same stylesheets that will render the application. What is unreadable here will be unreadable there.

It shows one state: the destination TextGrid selected, on a batch of four files, after a conversion has run. Interactions are inert; the structure, the labels and the wording are not.

Convert

Write into

Praat
Elan
SPPAS
Subtitles
Other

… and the remaining writable formats.

Compare the formats

The full matrix of formats by properties. It is here because comparing formats is a legitimate thing to want, and a poor way to choose a destination. Unfolded in place: the page stays where it is.

Formats and the properties each holds (excerpt)
Format Several tiers Metadata Hierarchy Overlaps Ctrl. vocab.
xra yesyesyesyesyes
TextGrid yesnononono
eaf yesyesyesnoyes
srt nonononono

… and the remaining formats and properties.

Options

Replace an output file that already exists

Guess the format of a file whose extension is unknown

Results

One line per file written, refused or skipped — not one per file of the batch
File Status Remarks
interview-01.xra written —
interview-02.xra written, with remarks An empty tier was removed: Comments.
gestures.eaf refused The file holds a tier of geometric labels, and you chose to skip such tiers. Nothing was left to write.
notes.TextGrid skipped The output file already exists.

What the mockup settles, and what it does not

The labels of the aside do not move. Selecting another format changes what is said of each property, never the property said. Clicking from TextGrid to eaf and back shows what differs without anything being read twice.

The properties are a list, not a table. There is one format here: a table would assert a second dimension that does not exist, and would weigh on the page as though every line had to be analysed rather than read. The full matrix, which does have two dimensions, remains a table — in the details element, where it belongs.

Every property is on the same footing. This is a scientific application: it states its data. Some properties exist almost nowhere but in SPPAS, and a user who wants to know what vagueness is has the right to find it — in the same list, in the same order, as the ones everybody knows.

Three things are shown here and are not settled: the wording of the properties in plain language, the wording of the causes of refusal, and whether the results belong in the page or replace it. They are interface questions, and they are decided against this markup rather than in the abstract.

Annex: Legal notices

  • Author: Brigitte Bigi
  • Document License: GNU Free Documentation License (GFDL) 1.3
  • Copyright (C) 2026 Brigitte Bigi, CNRS
  • Creation Date: 2026-07-16
  • Last update: 2026-07-17