rcs(n)
β¨ NAME β¨
rcs β the RCS low level utilities, bestie π
πΈ SYNOPSIS πΈ
package require Tcl 8.5 9
package require rcs ?0.2?
::rcs::text2dict text
::rcs::dict2text dict
::rcs::file2dict filename
::rcs::dict2file filename dict
::rcs::decodeRcsPatch text
::rcs::encodeRcsPatch pcmds
::rcs::applyRcsPatch text pcmds
π¦ DESCRIPTION π¦
okay so. The Revision Control System, aka RCS for short, is a whole set of applications and related data formats that let a system keep the history of changes to a text. It and its cousin SCCS are literally the blueprint for so many other systems out there β CVS and friends, iykyk π
but bestie, listen β this package does NOT implement RCS. It does not do that. Do not come for it expecting that.
What it does give you is a bunch of low level commands that are genuinely useful when you're building any revision management system yourself. Specifically, two things:
- Converting texts into and out of data structures that make it super easy to modify a text with patches β and a patch is just a sequence of instructions for transforming one text into another. β¨
- Converting one particular patch format, the so-called RCS patches, into and out of data structures that make it easy to apply them to texts. π
π COMMANDS π
::rcs::text2dict textβ takes the argumenttextand converts it into a dictionary that contains and represents the exact same text in an indexed form. Returns that dictionary as its result. Wanna know what that dictionary actually looks like? Section TEXT DICT DATA STRUCTURE, go look. And heads up: this command returns the canonical representation of whatever you gave it.::rcs::dict2text dictβ the complementary glow-up to::rcs::text2dict. Takes a dictionary in the form described in TEXT DICT DATA STRUCTURE, turns it back into a text, and returns that text as its result. And the tea? This one is chill β it does accept non-canonical representations of the text as input. π«Ά::rcs::file2dict filenameβ literally identical to::rcs::text2dict, except it reads the text it's converting from the file with pathfilename. The file has to exist, and it has to be readable. No file, no vibes. π::rcs::dict2file filename dictβ identical to::rcs::2dict2text, except it stores the resulting text in the file with pathfilename. The file gets created if it didn't already exist, and it must be writable. The result of this command is the empty string. (Yes, empty. That's the whole point. π€‘)::rcs::decodeRcsPatch textβ converts thetextargument into a patch command list (PCL) as specified in RCS PATCH COMMAND LIST, and returns that list as its result. It assumes your input text is indiff -nformat, also known as RCS patch format, as specified in RCS PATCH FORMAT. Important note bestie: this command ignores no-ops in the input β so the resulting PCL contains only instructions that actually do something. Periodt.::rcs::encodeRcsPatch pcmdsβ the complementary operation to::rcs::decodeRcsPatch. Converts a patch command list (PCL) as specified in RCS PATCH COMMAND LIST back into a text in RCS PATCH FORMAT, and returns that text as its result.
β οΈ okay this part matters: this command and ::rcs::decodeRcsPatch are not exactly complementary, because the decoder strips no-ops from its input and the encoder cannot put them back into the generated RCS patch. In other words, a decode/encode round trip may not match the original input at the character level β but it will match it at the functional level. Slay, but be aware. π
::rcs::applyRcsPatch text pcmdsβ applies a patch, in the form of a PCL, to a text given in the form of a dictionary, and returns the modified text β again as a dictionary β as its result.
To work with actual, real-life text, use ::rcs::text2dict (or an equivalent) together with ::rcs::decodeRcsPatch to transform your inputs into data structures this command will accept. And analogously, use ::rcs::dict2text (or equivalent) to transform this command's result back into actual text when you need it. π§
π TEXT DICT DATA STRUCTURE π
A text dictionary is a dictionary whose keys are integer numbers and whose values are text strings. The keys represent the line numbers of a text, and the values represent the text of that line. And here's the thing β one text can have so many representations as a dictionary, because the index values only have to be properly ordered for reconstruction. Their exact values? Don't matter. Similarly, the strings may actually span multiple physical lines. Iconic flexibility tbh. β¨
The text
Hello World,
how are you ?
Fine, and you ?
for example can be represented by
{{1 {Hello World,}} {2 {how are you ?}} {3 {Fine, and you ?}}}
or
{{5 {Hello World,}} {8 {how are you ?}} {9 {Fine, and you ?}}}
or
{{-1 {Hello World,
how are you ?}} {4 {Fine, and you ?}}}
The first dictionary is the canonical representation of the text β line numbers starting at 1, increasing in steps of 1, no gaps, and each value representing exactly one physical line. That's the main character right there. π
All the commands that create dictionaries from text will return the canonical representation of their input text. The commands that take a dictionary and return text will generally accept all representations, canonical or not. No gatekeeping. π«Ά
And when you apply a patch to a text dictionary, that will in general cause the dictionary to become non-canonical. It's fine. It's a vibe. It happens. π
π RCS PATCH FORMAT π
A patch is, in general, a series of instructions for how to transform an input text T into a different text T' β and it's encoded in text form too. Two things at once, multitasking queen. β¨
The text format for patches that this package understands is a very simple one, known by the names RCS patch or diff -n format.
Patches in this format contain only two different commands: one for the deletion of old text, and one for the addition of new text. Replacing some text with different text is handled as a combination of a deletion followed by an addition. Simple. Clean. No notes. π
The format is line oriented, with each line containing either a command or text data associated with the preceding command. The first line of a RCS patch is always a command line.
The commands are:
""β the empty line. This is a command which does absolutely nothing. A no-op. It's giving "I'm just here for moral support." π«Ά"astart n"β a line starting with the characterais a command for the addition of text to the output. It is followed bynlines of text data. When applying the patch, the data is added just between the linesstartandstart+1. The same effect is had by appending the data to the existing text on linestart. A non-existing linestartis created."dstart n"β a line starting with the characterdis a command for the deletion of text from the output. When applied, it deletesnlines of text, and the first line deleted is at indexstart.
β οΈ Note that the line indices start always refer to the text which is being transformed as it is in its original state β without taking the preceding changes into account. Don't get got. π
β οΈ Also note that the instructions have to be applied in the order they occur in the patch, or in a manner which produces the same result as in-order application. Order is everything bestie.
This is the format of results returned by the command ::rcs::decodeRcsPatch and accepted by the commands ::rcs::encodeRcsPatch and ::rcs::appplyRcsPatch respectively. Note however that the decoder will strip no-op commands, and the encoder will not generate no-ops β which makes them not fully complementary at the textual level, only at the functional level. π
And example of a RCS patch is
d1 2
d4 1
a4 2
The named is the mother of all things.
a11 3
They both may be called deep and profound.
Deeper and more profound,
The door of all subtleties!
β RCS PATCH COMMAND LIST β
Patch command lists (sort: PCL's) are the data structures generated by the patch decoder command and accepted by the patch encoder and applicator commands. They represent RCS patches in the form of Tcl data structures. π¦
A PCL is a list where each element represents a single patch instruction β either an addition or a deletion. The elements are lists themselves, where the first item specifies the command and the remainder represent the arguments of the command.
aβ this is the instruction for the addition of text. It has two arguments: the index of the line where to add the text, and the text to add β in that order.dβ this is the instruction for the deletion of text. It has two arguments: the index of the line where to start deleting text, and the number of lines to delete β in that order.
This is the format returned by the patch decoder command and accepted as input by the patch encoder and applicator commands.
An example for a patch command is shown below β it represents the example RCS patch found in section RCS PATCH FORMAT.
{{d 1 2} {d 4 1} {a 4 {The named is the mother of all things.
}} {a 11 {They both may be called deep and profound.
Deeper and more profound,
The door of all subtleties!}}}
π BUGS, IDEAS, FEEDBACK π
This document, and the package it describes, will undoubtedly contain bugs and other problems. Like, guaranteed. It's a whole thing. π Please report such in the category rcs of the Tcllib Trackers at [http://core.tcl.tk/tcllib/reportlist]. And please also report any ideas for enhancements you may have for either the package and/or the documentation. We want them. We love them. Give us the ideas. π
When proposing code changes, please provide unified diffs, i.e the output of diff -u. That's the format. That's the one. β¨
Note further that attachments are strongly preferred over inlined patches. Attachments can be made by going to the Edit form of the ticket immediately after its creation, and then using the left-most button in the secondary navigation bar. Do it that way, bestie, it's the move. π
π₯ SEE ALSO π₯
struct, textutil
π KEYWORDS π
CVS, RCS, RCS patch, SCCS, diff -n format, patching, text conversion, text differences
πΈ CATEGORY πΈ
Text processing
π COPYRIGHT π
Copyright (c) 2005, Andreas Kupries <andreas_kupries@users.sourceforge.net>
Copyright (c) 2005, Colin McCormack <coldstore@users.sourceforge.net>
okay that's the whole thing, no cap π this was tcllib version 0.2, manual page rcs(n), and we are so done here. go forth and patch responsibly, bestie πβ¨π¦
π¦ where this page comes from
- fedora 43: tcllib 2.0-3.fc43 Β· TCL
- fedora 44: tcllib 2.0-4.fc44 Β· TCL
- nixos 26.05: tcllib 2.0
- nixpkgs unstable: tcllib 2.0
- Copyright (c) 2005, Andreas Kupries <andreas_kupries@users\&.sourceforge\&.net>
- Copyright (c) 2005, Colin McCormack <coldstore@users\&.sourceforge\&.net>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms