Inline annotation of content
In the following we try to figure how we could associate manual annotations to any kind of "line oriented" text content.
Editing use cases
Whole file annotation mode
One could imagine a general way of annotating original text-based
content in a way similar to the one we handle "citations" (e.g. in the Reply to feature of tickets, with the >
line prefixes).
This would take any original input and prefix each line (e.g. with |
) and the author of the review could then "split" that content at any point and add some comment in the form of wiki text.
E.g. for the original two lines:
Code reviews should support configurable workflows (like tickets).
Annotateing it would give you a textarea with this content:
| Code reviews should support configurable workflows | (like tickets).
You could then change this to:
| Code reviews should support configurable workflows So this implies that a review is an entity by itself (i.e. a kind Trac resource), as opposed to only metadata for another resource. | (like tickets). One wonders however if this justifies an entire new class of resources or if using a specific "ticket type" wouldn't be enough, assuming one could have a dedicated workflow per type, specific fields per type, as often discussed.
Such "annotated content" would then be processed line by line:
- accumulate the lines of "original" content (which may or may not be 100% identical to the real original content; this may provide the basis of "diff" based annotations useful for suggesting changes in wording, for example)
- when there are comment lines, group them and associate them to the line number of original content placed above (or below if there's more vertical whitespace at the top than on the bottom); this creates an "annotation"
The rendering would proceed nearly as usual, but in addition to the "unicode content" given as input to the renderers (note to self, finish #3332 one day ;-) ), we would also provide a map {linenum: annotation}
, where an annotation dict would contain several fields like the comment lines themselves (to be wiki-rendered in the RenderingContext
of the codereview object, itself parented in the rendering context of the original resource), the author of the comment, and the created time (after flag set to True
if the comment follows the anchored content line)
A possible rendering could be:
Code reviews should support configurable workflows So this implies that a review is an entity by itself (i.e. a kind Trac resource), as opposed to only metadata for another resource. (like tickets). One wonders however if this justifies an entire new class of resources or if using a specific "ticket type" couldn't be enough, assuming one could have a dedicated workflow per type, specific fields per type, as often discussed.
Most existing mimetype renderers ones are line oriented and could therefore be easily extended to support rendering these annotations (e.g. our own patch renderer, the plaintext renderer, the Pygments renderer, and of course the wiki formatter)
Annotation editing
The "whole file annotation" approach isn't necessarily the only approach. We can imagine finer grained user interfaces, e.g. a la GitHub, clicking on a line in the source browser and adding a paragraph below.
In some situations (for source code, even for patches perhaps) this can be even more attractive than the whole page approach. The latter is perhaps only suited to wiki page annotation, after all.
Likewise, clicking on an annotation and editing it alone (or perhaps even "replying to" it) should be easy, both from the p.o.v. of the user and to implement, as no modification of the main content is involved here and the anchoring of the annotation remains the same.
Combined content and annotations changes (review processing?)
For wiki pages reviews, we could imagine an edit mode in which the page content and its annotations are edited at the same time (responding to a review). In this situation, having a line prefix for the content would be annoying and it would be much better to have the annotations wrapped in {{{#!review ...}}}
blocks. After parsing, those blocks would be removed from the content and the annotation would be updated separately (based on some id=...
tagging).
Editing our previous example, this would give:
Code reviews should support configurable workflows {{{#!review id=1 author="cboos" created="...." So this implies that a review is an entity by itself (i.e. a kind Trac resource), as opposed to only metadata for another resource. }}} (like tickets). {{{#!review id=2 author="cboos" created="...." One wonders however if this justifies an entire new class of resources or if using a specific "ticket type" wouldn't be enough, assuming one could have a dedicated workflow per type, specific fields per type, as often discussed. }}}
After modification:
Code reviews should support configurable workflows. {{{#!review id=1 author="cboos" created="...." So this implies that a review is an entity by itself (i.e. a kind Trac resource), as opposed to only metadata for another resource. Note the possible ambiguity: - in a "post-review", the code review is clearly a review of something (typically a changeset, or a branch) - in a "pre-review", the change is part of the review proposal and possibly doesn't exist elsewhere }}} This could be achieved either by generalizing state and workflows to a `codereview` resources, or by using a dedicated type of ticket and have per-worflow type, specific fields per type, etc.
After parsing:
- the review block id=1 has been modified; it's still associated to the same line of content (here 1+)
- review block id=2 disappeared, meaning this comment has been addressed (here by incorporating some of it in the main text)
The review blocks are removed and the content which gets stored is simply:
Code reviews should support configurable workflows. This could be achieved either by generalizing state and workflows to a `codereview` resources, or by using a dedicated type of ticket and have per-worflow type, specific fields per type, etc.
Annotation id=1 gets a new version with its new content and new anchor if needed. Note that this mechanism should be very robust, as when the author moves sections around, the annotations will move alongside with the content.
Annotation id=2 gets a new "deleted" version.
Content changes only, in presence of annotations
If instead of the previous combined mode, the author chooses to edit the content alone (or if there's simply no other choice, if the annotated resource is a source file), then we risk to lose the associations between the annotations and the annotated lines.
In some cases, it should be possible to update the line numbers by processing the diffs, but in general if the annotated lines are deleted, the annotations become "orphaned" or floating. Maybe they're not relevant anymore, maybe the anchor line has moved, we have no way to know for sure.
We can imagine that those annotations become simple "resource" level comments, not anchored anymore to some specific line number. It should even be possible to provide an UI to "reconnect" those comments to a line number in the new version. At least, there should be a link to the last version of the resource where the annotation could be seen in context.