Tämä juttukokonaisuus käsittelee rivinvaihtojen erilaisia esitysmuotoja datan tallentamisessa, siirtämisessä ja muussa käsittelyssä. Erot aiheuttavat jatkuvasti ongelmia etenkin siirrettäessä dataa erilaisten ohjelmien välillä.
Rivinvaihto ja kappale ovat melko selviä asioita silloin, kun tarkastellaan vain paperilla olevia dokumentteja. Tosin emme ehkä ajattele rivinvaihtoja minään "olioina", vaan teksti vain jakautuu eri riveille.
Tietokoneessa asia on toinen. Jos teksti halutaan esittää tietokoneella luettavassa muodossa (digitaalisessa muodossa) siten, että esityksessä on mukana tekstin jako riveihin, on rivinvaihdotkin jotenkin esitettävä. Mutta pitäisikö teksti esittää siten? Hyvä kysymys. Joskus rivinvaihdoilla on rakenteellinen merkitys, esimerkiksi luetteloita esitettäessä. Useat vanhat ohjelmointikielet suunniteltiin niin, että lähdekielinen ohjelma piti jakaa riveihin määrätyllä tavalla. Lisäksi ATK:n alkuaikoina tekstidatan esitys oli varsin alkeellista ja sitä käsittelevät ohjelmat rajoittuneita. Niinpä useinkin tekstin kirjoittajan piti jakaa teksti valmiiksi riveille, jotta se tulostuisi kunnolla. Tekstieditoritkin olivat usein ns. rivieditoreja, joissa rivijako oli olennainen.
Joka tapauksessa tekstidatan tallentamiseen ja käsittelyyn tietokoneilla on alusta alkaen kuulunut kysymys, mikä on rivinvaihdon esitysmuoto. Tässä jutussa käsiteltävät ongelmat johtuvat enimmäkseen siitä, että tämä kysymys on eri tietokoneissa, ohjelmissa ja järjestelmissä ratkaistu eri tavoin.
Yksi vanhimmista tavoista, joka on edelleen laajasti käytössä, perustuu alkujaan ajatusmalliin, joka on peräisin vanhoista mekaanisista kirjoituskoneista. Sellaisella kirjoitettaessa rivin lopettaminen ja uuden aloittaminen koostuu toisaalta telanpalautuksesta (carriage return) eli telan siirtämisestä ääriasentoon oikealle niin, että kirjoituskohta tulee paperin vasempaan reunaan, toisaalta rivinsiirrosta (line feed) eli telan pyörittämisestä yhden rivin verran. (Alkujaan nämä tehtiin vivusta vääntämällä, myöhemmin erityisellä rivinvaihtonäppäimellä return key.) Tätä jäljitellen otettiin käyttöön kontrollikoodit eli "kontrollimerkit" CR ja LF. Tämä tarkoittaa, että tiedostoon tallennetaan kaksi dataa (käytännössä yleensä luvut 13 ja 10), joista on sovittu, että ne eivät esitä mitään merkkejä vaan tietynlaisia ohjaustoimintoja.
Tämän mukaisesti määriteltiin Asciin mukaiset kontrollikoodit:
Pos. Name Abbr. Definition
0/10 Format effector 2 (Line feed)
FE2 (LF)
A format effector which advances the active
position to the same character position of the nextline.
0/11 Format effector 3 (Vertical tabulation)
FE3 (VT)
A format effector which advances the active
position to the same character position
on the next pre-determined line.
0/12 Format effector (Form feed)
FE4 (FF)
A format effector which advances the active
position to the same character position
on the next pre-determined line of the next form or page.
0/13 Format effector (Carriage return)
FE5 (CR)
A format effector which moves the active
position to the first character position on the
same line.
C0 Set of ISO 646
(PDF-muotoinen)
Kyseisen tavan ollessa käytössä return- tai enter-näppäimen painallus päätteen tai tietokoneen näppäimistöltä aiheuttaa siis kontrollikoodien CR ja LF tallentumisen ohjelman muistiin taikka tiedostoon. Vastaavasti tekstidatan tulostaminen kuvaruutuun tai paperille aiheuttaa rivinvaihdot kyseisissä kohdissa. Toiminta saattaa jopa olla aivan analogista kirjoituskoneen toiminnan kanssa siinä mielessä, että CR ja LF aiheuttavat ovat kaksi erillistä asiaa: kirjoituskohdan siirto ääriasentoon vasemmalle sekä kirjoituskohdan siirto yhden rivin verran alaspäin. Tällöin pelkän CR:n esiintyminen tekstissä aiheuttaa sen, että sen jälkeinen teksti tulostuu rivillä jo olevan tekstin päälle (päällekirjoitus, overwrite). Vastaavasti pelkkä LF aiheuttaisi jotain seuraavantapaista:
Tässä on tekstiä ja tässä se jatkuu alemmalla rivillä.
Toisaalta voidaan ajatella - ja monella taholla ajateltiinkin - että kahden kontrollikoodin käyttö on turhaa, kun yksi riittää. Voidaanhan tulostuslaite tehdä tai ohjelmoida toimimaan halutulla tavalla. Niinpä joissakin järjestelmissä ruvettiin käyttämään pelkkää CR-koodia rivinvaihdon merkkinä, joissakin taas pelkkää LF-koodia. Ongelmia tietysti syntyi, jos dataa siirrettiin järjestelmästä toiseen ja kontrollikoodikäytännöt olivat erilaiset. Mutta tämä tapahtui aikana, jolloin ei juurikaan edes unelmoitu datan joustavasta siirtämisestä eri ohjelmien ja koneiden ja järjestelmien välillä - eikä Internetiä ollut keksittykään. Ja nämä ongelmat olivat sentään aika hyvin hallittavissa verrattuina datansiirron muihin ongelmiin. Dataa tutkimalla selvisi yleensä, mitä rivinvaihtojen esitystä oli käytetty, eikä monitulkintaisuutta syntynyt, koska CR- ja LF-koodeilla ei juuri ollut muuta käyttöä.
Kirjavuutta lisäsi se, että käyttöön otettiin muitakin tapoja esittää rivinvaihdot. Aikoinaan käytettiin paljon reikäkortteja (punched cards). Yhteen korttiin voitiin tallentaa (lävistää) 80 merkkiä, ja oli luonnollista ajatella, että yksi kortti vastaa yhtä riviä. Jos rivi oli lyhyempi kuin 80 merkkiä, jätettiin vain kortin loppuosa käyttämättä. Korteista tietokoneen muistiin tai levylle luettu data tallennettiin yleisesti kortinkuvina (card images), mikä tarkoittaa, että tallennettiin tasan 80 merkkiä korttia kohti käyttäen lopussa tarvittaessa täytemerkkinä välilyöntiä (tyhjää väliä, space, blank). Tällöin mitään rivinvaihtokoodeja ei tarvita. Rivit ovat suoraan peräkkäin eli rivin viimeistä merkkiä seuraa välittömästi seuraavan rivin ensimmäinen merkki. Datan käsittelyssä vain otettiin huomioon, että kukin rivi on tasan 80 merkin mittainen.
Muista tavoista mainittakoon ratkaisu, jossa kutakin riviä edeltää data, joka kertoo rivin pituuden merkkeinä. Tällöinkään ei mitään erillisiä rivinvaihtokoodeja tarvita.
Kappaleiden erottamiseen toisistaan käytetään yleisesti tyhjää riviä etenkin silloin, kun kehittyneempiä menetelmiä ei ole käytettävissä - siis esimerkiksi silloin, kun teksti on "pelkkää tekstiä". Tyhjä rivi tarkoittaa yleensä sitä, että on peräkkäin kaksi rivinvaihtoa. Tosin se saattaa tarkoittaa myös riviä, joka koostuu vain yhdestä tai useammasta välilyöntimerkistä.
Tekstidatan käsittelyssä puhutaan usein rivistä tietueena (record). Tällöin kyse on ns. fyysisestä tietuekäsitteestä, joka viittaa johonkin, jota teknisistä syistä kohdellaan jonkinlaisena kokonaisuutena datan käsittelyssä. Fyysinen tietue voi olla samalla myös looginen tietue eli loogisesti yhteenkuuluvan datan muodostama kokonaisuus, esimerkiksi yhdestä mittauksesta saadut datat taikka yhtä ihmistä koskevat tiedot puhelinluettelossa.
Aikana, jolloin data syötettiin tietokoneeseen reikäkorteilla ja tulosdata kirjoitettiin rivikirjoittimelle, oli luonnollista pitää riviä tekstidatan käsittelyn fyysisenä tietueena. Ohjelmat kirjoitettiin niin, että datan lukeminen ja tulostaminen tapahtui rivi kerrallaan. Varhaisissa ohjelmointikielissä ei usein muu luku- tai tulostustapa ollut edes mahdollinen.
Edelleenkin on riveittäinen käsittelytapa varsin tavallinen. Suureksi osaksi tämä johtuu siitä, että varsin usein lähdekieliset tietokoneohjelmat, komentotiedostot, data-aineistot ja tulosteet ovat sellaisia, että rivijaon sisällyttäminen itse dataformaattiin on luonnollista tai välttämätöntäkin. Lisäksi sellainen muoto on usein luotettavin tapa siirtää dataa ohjelmien välillä. Esimerkiksi Excel-taulukko voidaan tallentaa muodossa, jossa taulukon kukin rivi on yksi tekstirivi (ja alkioiden välissä on erottimina sarkausmerkit), ja tällaisena data on luettavissa sellaiseenkin ohjelmaan, joka ei lainkaan ymmärtäisi Excelin omaa dataformaattia.
Aluksi tekstin kirjoittamiseen ja muokkaamiseen tietokoneella käytettiin suhteellisen yksinkertaisia ohjelmia, editoreita (text editor), joita edelleenkin käytetään laajasti mm. pienten tekstien kirjoittamiseen sekä ohjelmointiin yms. Myöhemmin kehitettiin ohjelmia varsinaiseen tekstinkäsittelyyn, text processing tai word processing. Tällaisista ohjelmista ovat nykyisin kai tunnetuimpia MS Word, WordPerfect ja WordStar. Raja editorin ja tekstinkäsittelyohjelman, word processor, välillä on osittain aika häilyvä. Käytännössä tekstinkäsittelyohjelmaa käytetään, kun halutaan saada paperille tulostettava teksti tyylikkäässä muodossa. Teknisesti tärkeänä erona on useimmiten se, että editori tallentaa tekstin "pelkkänä tekstinä" (plain text) kun taas tekstinkäsittelyohjelma käyttää omaa erityistä (ohjelmasta ja jopa sen versiosta riippuvaa) dataformaattiaan, jossa on mukana myös tietoa käytetyistä kirjasinlajeista ym.
Tekstinkäsittelyohjelmiin on yleisesti toteutettu automaattinen rivinvaihto (automatic line wrap) siten, että käyttäjä voi kirjoittaa tekstiä jatkuvasti, huolehtimatta rivinvaihdoista. Ohjelma vaihtaa automaattisesti riviä, kun riville ei mahdu enempää; tällöin se käyttää jotain valmiiksi asetettua tekstin enimmäisleveyttä, joka on yleensä käyttäjän säädeltävissä.
Tietokoneiden käyttäjistä monet ovat tottuneet tähän niin, että hämmästyvät, jos asiat jossain tilanteessa eivät toimikaan sillä tavoin. Ja toisaalta monet toisenlaisiin ohjelmiin tottuneet ovat tottuneet painamaan enter-näppäintä aina, kun rivi uhkaa "tulla täyteen" eli niin pitkäksi kuin ohjelman ikkunaan mahtuu.
Luonnollinen ajatus on, että tällaisia automaattisia rivinvaihtoja ei tarvitse eikä ole syytäkään tallentaa tiedostoon. Kun tiedoston sisältämää tekstiä myöhemmin katsellaan, voi käytettävä ohjelma uudestaan jakaa sen eri riveille, mahdollisesti aivan erilevyiseksi. Vain tieto tekstin jakautumisesta kappaleisiin on tärkeää tallentaa tiedostoon; kappaleen sisällä ei tarvitse olla valmiita rivinvaihtoja. Tämän sinänsä hyvän idean toteuttamisessa tehtiin eräs onneton ratkaisu, jonka seurauksista kärsimme vielä pitkään: kappaleiden erottimeksi otettiin koodi, joka jo oli käytössä rivinvaihtona monissa muissa järjestelmissä.
Kun aiemmin rivinvaihtoja tarkoittaneita koodeja ruvettiin käyttämään kappaleen vaihdon merkkeinä, otettiin muita kontrollikoodeja rivinvaihtomerkeiksi. Esimerkiksi MS Wordissä VT-koodi, joka alkujaan tarkoitti pystysuoraa sarkausta (vertical tabulation), otettiin rivinvaihdon merkiksi. Tämä ja muunlaiset valinnat aiheuttivat vielä lisää kirjavuutta.
Ei tarvitse kuvitella, millaista sotkua tulee, kun yhdessä ohjelmassa CR tarkoittaa rivinvaihtoa ja toisessa kappaleen vaihtoa. Sellaiseen törmätään ATK-alalla jatkuvasti. Esimerkiksi jos MS Wordillä kirjoitettu teksti halutaan tallentaa "pelkkänä tekstinä", esim. käsiteltäväksi jollakin editorilla taikka muulla ohjelmalla, joka ei tunne Wordin omaa tiedostomuotoa, niin (Save As -valikon) vaihtoehto "Text Only" merkitsee sitä, että kustakin kappaleesta tulee yksi pitkä rivi. Vaihtoehto "Text Only with Line Breaks" tekee kustakin ruudulla näkyvästä rivistä yhden rivin tiedostoon. Tällöinkin rivinpituus voi olla sopimaton jatkokäsittelyä varten.
Käänteinen ongelma voi syntyä, kun tekstidataa siirretään editorilla tehdystä tiedostosta tekstinkäsittelyohjelmaan. Jos tiedostossa on rivien välissä rivinvaihtomerkit, jotka tekstinkäsittelyohjelma tulkitsee kappaleenvaihdoiksi, täytyy tehdä sopiva muunnos. Sitä ei kannata ruveta tekemään "käsin" eli poistamalla yksitellen jokainen rivinvaihto, ellei ole ihan pakko, koska siinä menee hermot ja tulee virheitä. Tarvittava muunnoshan on aika yksinkertainen ja siten ohjelmoitavissa: pitää korvata kaksi peräkkäistä rivinvaihtoa yhdellä rivinvaihdolla ja muutoin jokainen rivinvaihto välilyönnillä. (Tämä olettaen, että tekstissä ole jaettu sanoja eri riveille, mikä toisi omat ongelmansa.)
Yhtä dokumenttia tarkasteltaessa voidaan yleensä päätellä, mitä esimerkiksi CR-koodi siinä tarkoittaa. Kappaleethan ovat yleensä sen verran pitkiä, että jos kukin kappale on yhtenä rivinä, sen huomaa. Mutta yleisiä datankäsittelyohjelmia ja -tapoja on hankala tehdä niin, että ne osaavat jotenkin järkevästi käsitellä tekstiä, oli CR sitten rivien erotin tai kappaleenvaihto. Raportti Unicode Newline Guidelines sisältää tätä koskevia suosituksia, mutta ne ovat pakostakin "heuristisia" eli sisältävät sen, että kun ei voi tietää, täytyy arvata - mieluiten siten, että väärästä arvauksesta koituva haitta on mahdollisimman pieni. Aiheesta kertoo lisää kirjoitukseni Unicode line breaking rules: explanations and criticism.
Seuraava taulukko listaa eräitä kontrollikoodeja, jotka liittyvät rivinvaihtoihin, kappaleenvaihtoihin tai sivunvaihtoihin.
lyh. | Unicode | Ascii | selityksiä | |
---|---|---|---|---|
LF | U+000A |
line feed | 10 | rivinvaihto tai rivinsiirto tai kappaleen vaihto; "control-J", NL |
VT | U+000B |
vertical tabulation | 11 | sarkaus pystysuunnassa;
MS Wordissä rivinvaihto;
|
FF | U+000B |
form feed | 12 | sivunvaihto; "control-L", NP |
CR | U+000D |
carriage return | 13 | rivinvaihto tai rivin alkuun paluu tai kappaleen vaihto; "control-M" |
NEL | U+0085 |
next line | (ei ole) | rivinvaihto tai kappaleen vaihto |
LS | U+2028 |
line separator | (ei ole) | rivinvaihto |
PS | U+2029 |
paragraph separator | (ei ole) | kappaleenvaihto |
Ascii-sarake sisältää koodiarvon desimaalisena Ascii-koodissa. Ilmaisut "control-J" yms. viittaavat yleiseen tapaan puhua näistä koodeista. Tämä liittyy siihen, että joissakin järjestelmissä voidaan esim. LF lähettää näppäimistöltä näpäyttämällä J-näppäintä tilanteessa, jossa Control-näppäintä (tai Ctrl- tai CTL-näppäintä) pidetään alas painettuna. Joissakin tilanteissa saattavat ohjelmat näyttää kontrollikoodit tavalla, joka vastaa tätä yhteyttä, esim. LF:n muodossa ^J jne.
CR LF on käytössä mm. DOSissa. Sitä käyttävät yleisesti myös Windows-ohjelmat silloin, kun ne tallentavat datan pelkkänä tekstinä. Merkittävintä nykyisin on, että se on useissa Internet-protokollissa (esim. RFC 822 ja HTTP) käytetty.
LF on käytössä Unix-tyyppisissä järjestelmissä ja mm. Amigassa.
CR on käytössä mm. Macintosheissa.
VMS:ssä on käytetty useita erilaisia rivirakenteen osoittavia tapoja eri yhteyksissä, mutta tavallisin on sellainen, jossa kunkin rivin edessä on erillinen pituustieto. Ks. tarkemmin liitettä Rivinvaihdot VMS:ssä.
NEL on käytössä joissakin sellaisissa IBM-järjestelmissä, joissa merkkikoodina on Ebcdic. Ebcdicistä on useita versioita, ja niinpä NEL-koodikin saattaa olla joko 15 tai 25 (heksadesimaalisena).
LS ja PS ovat Unicoden mukaiset suositellut kontrollikoodit silloin, kun tekstidatassa halutaan yksikäsitteisesti esittää rivinvaihto ja kappaleenvaihto.
IBM:n VM-järjestelmissä tiedostomuoto voi olla sellainen, jossa kaikki rivit ovat kiinteänmittaisia, tai sellainen, jossa kuhunkin riviin liittyy tieto sen pituudesta. Kummassakaan tapauksessa ei erillisiä rivinvaihtokoodeja ole.
Jori Mäntysalo on toteuttanut verkkoon palvelun, jolla voi tutkia tiedoston rivinvaihtoja ja myös yrittää muuntaa rivinvaihtojen esitysmuotoja: Test file type and check linefeed convention.
SGML on metakieli, jolla voidaan määritellä erilaisia merkkauskieliä, tarkemmin sanoen niiden muodollinen rakenne eli syntaksi. Suurelle yleisölle tunnetuin tällainen kieli on HTML. Tosin todellisuudessa HTML:n SGML-pohjaisuus on osittain vain nimellistä.
SGML:llä määritellyssä kielessä rivirakenne on periaatteessa sellainen, että kukin rivi alkaa rivinaloituskoodilla ja päättyy rivinlopetuskoodilla. Näille koodeille käytetään symboleita RS ja RE (jotka johtuvat sanoista record start ja record end), mutta kyse on tällöin ns. abstraktista syntaksista, ei mistään kiinteästi määrätyistä koodeista. Ns. konkreettisessa syntaksissa tällaiset asiat kiinnitetään jollakin tapaa, ja oletusarvoisesti (ns. reference concrete syntax) RS on LF ja RE on CR.
Tosin SGML kaikessa käsitteellisyydessään ja yleisyydessään lähtee siitä, että datalla ei tarvitse olla rivirakennetta, tai kuten SGML:ssä sanotaan: tietuerakennetta. Mutta SGML-standardi sanoo, että jos sellainen rakenne on, niin sen tulee noudattaa edellä mainittuja sääntöjä.
Tämä merkitsee, että verrattuna muotoon, jossa rivinvaihtona on CR LF, SGML-pohjaisessa kielessä tulisi periaatteessa olla LF koko datan alussa (ensimmäisen rivin aloituskoodina) ja lisäksi CR viimeisen rivin lopussa. Tätä suhteellisen harvoin noudatetaan, ja käytännössä mainitunlaisia kieliä käsittelevien ohjelmien edellytetään selviävän perinteisemmästäkin formaatista. Hiljentykäämme seuraamaan ankaraa käsien vatkutusta HTML 2.0 -spesifikaatiossa:
SGML specifies that a text entity is a sequence of records, each
beginning with a record start character and ending with a record end
character (code positions 10 and 13 respectively) (section
7.6.1, "Record Boundaries" in [SGML]).
[MIME] specifies that a body of type `text/*' is a sequence of
lines, each terminated by CRLF, that is, octets 13, 10.
In practice, HTML documents are frequently represented and
transmitted using an end of line convention that depends on the
conventions of the source of the document; frequently, that
representation consists of CR only, LF only, or a CR LF
sequence. Hence the decoding of the octets will often result in
a text entity with some missing record start and record end
characters.
Since there is no ambiguity, HTML user agents are encouraged to
infer the missing record start and end characters.
An HTML user agent should treat end of line in any of its
variations as a word space in all contexts except
preformatted text. Within preformatted text, an HTML user agent
should treat any of the three common representations of
end-of-line as starting a new line.
Uudemmat spesifikaatiot näyttävät vaikenevan tästä nolosta asiasta. Monella muullakin tavalla HTML 2.0 -spesifikaatio on selkeydessä merkittävä parannus seuraajiinsa nähden.
Edellä olevan lainauksen viimeinen kappale sanoo olennaisesti sen, että rivinvaihdon teknisestä esitysmuodosta riippumatta HTML:ssä rivinvaihto vastaa välilyöntiä.
Tähän on kuitenkin eräs näennäisesti pieni poikkeus: SGML:n yleiset säännöt sanovat, että aloitustägiä (esim. <p>) välittömästi seuraava rivinvaihto tulee jättää huomiotta, samoin lopetustägiä (esim. </p>) välittömästi edeltävä rivinvaihto. Tällä on merkitystä, koska useissa tilanteissa ei ole yhdentekevää, onko tägin ja sitä seuraavan tai edeltävän tekstin välissä välilyönti vai ei mitään. HTML 4.0 -spesifikaatio erikseen mainitsee tämän asian (liitteen B kohdassa line breaks), mutta käytännössä tämä on ymmärrettävä varoitukseksi siitä, että selaimet yleisesti eivät noudata tätä sääntöä. Tällöin esimerkiksi rakenne
<td><img src="foo.gif" alt="bar"> </td>ei tarkoitakaan samaa kuin
<td><img src="foo.gif" alt="bar"></td>kuten pitäisi vaan samaa kuin
<td><img src="foo.gif" alt="bar"> </td>Ja kun sitten selaimet saattavat tulkita kuvaa seuraavan välilyönnin dataksi, joka vaikuttaa dokumentin esitysmuotoon, seurauksena on usein ikävä pieni kummallisuus kuten ylimääräinen reunus jossakin. Niinpä HTML:ää kirjoittavan onkin syytä varautua siihen, että selaimet ovat näkevinään välilyöntejä sielläkin, missä niitä ei ole; täten voi olla hyvä opetella kirjoittamaan lopetustägi rivin loppuun eikä seuraavan rivin alkuun. Ks. White Space Bugs in Browsers.
Muista Web-selainten virheistä mainittakoon se, että ne eivät
suinkaan aina käsittele rivinvaihtoja oikein määritteiden
(attributes) arvojen sisällä. Tämä aiheuttaa ongelmia mm.
alt
-määritteiden
kirjoittamisessa.
Edellä sanottu koskee HTML:llä (tai muulla SGML-pohjaisella kielellä) kirjoitetun dokumentin rakennetta. Tästä on tarkoin erotettava dokumentin mahdollinen näkyvä esitys esimerkiksi sellaisena, kuin Web-selain sen muotoilee kuvaruudulle tai paperille. Tätä koskeva menettely on parhaiten kuvattu HTML 2.0 -spesifikaatiossa:
An HTML user agent should present the body of an HTML document as a collection of typeset paragraphs and preformatted text. Except for preformatted elements (PRE, XMP, LISTING, TEXTAREA), each block structuring element is regarded as a paragraph by taking the data characters in its content and the content of its descendant elements, concatenating them, and splitting the result into words, separated by space, tab, or record end characters (and perhaps hyphen characters). The sequence of words is typeset as a paragraph by breaking it into lines.
Täten siis selain olennaisesti lukee tekstidatan, erottelee sen "sanoiksi" eli osiksi, joita erottavat toisistaan välilyönnit, sarkainmerkit tai rivinvaihdot, ja sitten "latoo" tekstin kappaleiksi, jotka jakautuvat riveihin sopivalla tavalla. Olennaista on, että tieto siitä, mitä "sanojen" välissä oli (esim. välilyönti tai rivinvaihto, tai montako välilyöntiä), putoaa pois, ennenkuin selain rupeaa muotoilemaan tulostusta.
Edellä lainatussa tekstissä oleva maininta "(and perhaps
hyphen characters)" on osoittautunut pahaenteiseksi.
Useimmat Web-selaimet eivät käsittele yhdysmerkkiä
(hyphen,
oikeastaan hyphen-minus)
datassa millään erityisellä tavalla. Mutta Internet Explorer
tulkitsee sen kohdaksi, josta sanan saa jakaa eri riveille.
Tämä on jo itsessään kyseenalainen ratkaisu, mutta järjettömäksi
sen tekee se mekaanisuus, jolla IE sitä käsittelee. Se kylmän
tyynesti jakaa myös esimerkiksi ilmaisun "control-J"
kahdelle riville.
Se vieläpä käsittelee esimerkiksi tekstin "tuloaika ja -paikka"
niin, että "-paikka" on sana, jonka voi rivitystä varten
jakaa osiin "-" ja "paikka"!
Valitettavasti ainoa tehokas tapa estää moinen tolkuttomuus on
ilmeisestikin käyttää nobr
-merkkausta
(esim. <nobr>control-J</nobr>
),
HTML-kielessä voidaan kyllä pakottaa rivinvaihto
dokumentin näkyvään esitysmuotoon, mutta tätä ei tehdä
millään ohjauskoodeilla vaan erityisellä tägillä,
<br>
. Tämä tägi sopii huonosti HTML:n
yleisiin periaatteisiin, koska se ei varsinaisesti
kuvaa dokumentin rakennetta vaan pikemminkin ulkoasua.
Lisäksi kun esimerkiksi kappale esitetään elementtinä,
jolla on aloitustägi, sisältö ja lopetustägi, olisi loogista,
että vastaavasti on rivielementti, jos rivirakenne ylipäänsä
otetaan mukaan. Voidaankin sanoa, että
<br>
-tägi otettiin kieleen
keinotekoisesti, rivinvaihdon ohjauskoodien
melko suoraksi vastineeksi.
Eräät ohjelmointikielet, kuten Fortranin vanhimmat versiot, ovat vahvasti rivirakenteisia siinä mielessä, että lähdekielisen ohjelman (source program) pitää jakautua riveille määrätyllä tavalla. Muissakin kielissä on yleisesti sääntöjä, jotka rajoittavat ohjelman vapaata jakamista eri riveille. Esimerkiksi C-kielessä on ns. direktiivit kirjoitettava kukin omalle rivilleen.
Erittäin tavallista on, että merkkijonovakiota
ei saa ainakaan suoraan jakaa eri riveille. Koska toisaalta
usein tarvitaan pitkiä merkkijonovakioita, on yleensä käytössä
jokin jatkorivikonventio. Tyypillinen konventio on sellainen,
että rivin loppuun kirjoitetaan
kenoviiva \
ja kirjoittamista jatketaan
heti seuraavan rivin alusta (vaikka muuten olisi käytetty sisennyksiä).
Esimerkki C-kielestä:
char *s = "Tämä\ on merkkijono"merkitsee samaa kuin
char *s = "Tämäon merkkijono"
Huomannet sudenkuopan: on helppoa luulla, että rivinvaihto
vastaisi välilyöntiä, kuten se usein vastaa.
Esimerkiksi Fortranin uusissa versioissa (Fortran-90:stä alkaen) ns.
vapaassa muodossa (free source form) on suunnilleen
vastaava jatkorivikonventio mutta merkkinä on \
:n
asemesta et-merkki &
; tosin asiaan vielä
liittyy eräitä lisäsääntöjä.
Rivinvaihtojen sisällyttäminen merkkijonovakioon
saattaa myös olla mahdollista. Tämä on tarkoin erotettava edellä kuvatusta
jatkorivikäytännöstä. C-kielessä, ja sitä matkien useissa muissa kielissä,
voidaan tarkoitukseen käyttää merkintää \n
. Esimerkiksi
"hui\nhai"
on merkkijonovakio, jonka sisällä on rivinvaihto.
C-standardin mukaan \n
on kontrollikoodi, jonka merkitys on
"moves the active position to the initial position of the next line".
(Tästä seuraa, että sen fyysinen toteutus riippuu siitä järjestelmästä,
jossa C-ohjelma suoritetaan. Kuitenkin sen tulee olla yksi
koodi, yksi "ohjausmerkki",
esim. LF tai CR mutta ei niiden yhdistelmä, koska \n
vie (esim. merkkijonovakion sisäisessä esityksessä) saman verran tilaa
kuin yksi merkki. Tästä seuraa, että jos järjestelmässä on käytössä
CR LF rivinvaihdon esityksenä, täytyy C-kielen toteutuksen automaattisesti
muuntaa \n
:n sisäinen esitys tulostuksessa CR LF:ksi.)
Aivan eri asia sitten on, miten ohjelma lukee tekstidataa ja kirjoittaa sitä. Kuten kohdassa Rivi ja tietue mainittiin, aluksi käsittely oli yleensä rivipohjaista - ja on usein nykyisinkin. Vaikka esimerkiksi Perliä pidetään modernina kielenä, se on suunniteltu ensisijaisesti rivi kerrallaan tapahtuvaan datan käsittelyyn. Perlin yksinkertaisimman käytön perusidiomeihin kuuluu rakenne
while(<>) { käsittele syöterivi print; }
missä käsittely voi koostua esimerkiksi käskystä
s/x/ks/g;
(korvaa jokainen x-kirjain kirjainparilla ks).
Tässä ei missään vaiheessa erikseen sanota, mikä data on käsittelyn
kohteena, vaan se on koko ajan implisiittisesti "nykyinen syöterivi".
(Tosin siihen voitaisiin viitata muuttujalla $_
.)
Useat ohjelmointikielet on suunniteltu niin, ettei tekstidataa edes voi lukea ja tulostaa kuin rivi kerrallaan. Toki yksittäisiä merkkejäkin voi käsitellä, mutta siten, että esim. syötteen käsittelyssä ohjelma ensin lukee rivin vaikkapa taulukkoon, josta se sitten indeksoimalla poimii merkkejä. Tämä toimi ja toimii hyvin monissa tilanteissa, mutta vuorovaikutteisista ohjelmista tulee kömpelöitä, jos jokainen näppäimistöltä annettava ohjaus on päätettävä return- tai enter-näppäintä painamalla. Muutoinkin vuorovaikutteinen, merkki kerrallaan tapahtuva syöttö ja tulostus vaativat usein erikoistoimia, esimerkiksi erityisesti siihen sopivien aliohjelmien käyttöä.
Erikseen mainittakoon
Fortran-ohjelmoinnin se vaikeus, että
jokainen write
- tai print
-lause tulostaa
vähintään yhden rivin. Aiemmin tämä ongelma kierrettiin järjestämällä
tulostustoiminnot niin, että ohjelma tulostaa vain tilanteissa, joissa
sillä on koko rivi "valmiina".
Tämä ei tietenkään ollut mahdollista esim. tilanteessa, jossa halutaan
tulostaa tekstiä kehotteeksi niin, että käyttäjä voi kirjoittaa
syöttötiedot suoraan sen perään, samalle riville.
Saatettiin myös käyttää erilaisia kielen
epästandardeja laajennuksia. Fortran-90:ssä ongelma ratkeaa siististi
käyttämällä tulostuslauseessa argumenttia
advance='no'
.
Toisaalta silloinkin, kun kielen syöttö- ja tulostustoiminnot on
suunniteltu ensisijassa merkeittäiseen käsittelyyn, kannattaa
usein käyttää rivipohjaista käsittelyä apuna. Esimerkiksi C-kielisen
ohjelmoinnin tyylioppaat usein suosittavat tekemään ohjelmat niin, että
ohjelma ensin lukee rivin merkkejä puskuriin (merkkitaulukkoon) ja
sitten siitä sitten esimerkiksi sscanf
-funktiolla (eikä
suoraan syötetiedoista scanf
-funktiolla). Jos esimerkiksi
on olennaista tunnistaa, miten numeerinen
syöttötietoaineisto jakautuu eri riveille,
niin scanf
-funktiota ei voi käyttää, koska se iloisesti ohittaa
rivinvaihdot pitäen niitä välilyönteihin rinnastuvina.
Yleensä ns. korkean tason ohjelmointikielet on pyritty suunnittelemaan
niin, että ohjelmat voidaan kirjoittaa
riippumattomiksi rivinvaihtojen esityksestä.
Ohjelman voi siis koodata lukemaan rivi kerrallaan tai tunnistamaan
rivinvaihtoja ilman, että ohjelmoijan tarvitsee edes tietää, onko
rivinvaihdon esitysmuoto CR, LF, CR LF vai kenties jotain muuta.
Esimerkiksi kun C-ohjelma lukee tiedostosta dataa merkki kerrallaan, se
"näkee" rivinvaihdon C-standardin mukaisella tavalla kontrollikoodina,
johon voidaan viitata merkinnällä \n
(esim. if(merkki=='\n')
...). Näin siitä riippumatta, mikä
rivinvaihtojen fyysinen esitysmuoto tiedostoformaatissa on.
Eri asia sitten on, että lukemalla tiedostoa binaarisesti
(esim. fread
-funktiolla) on mahdollista päästä näkemään
se fyysinen esitysmuotokin.
Selvää on, että ohjelmoijan kannattaa tulostuksessa
vastaavasti yleensä käyttää kielen rakenteita, jotka on määritelty
niin, että ne saavat aikaan rivinvaihdon, esim. Pascalissa writeln
ja C:ssä vaikkapa putchar('\n')
, yhden monista
mahdollisuuksista mainitaksemme. Sen sijaan
putchar('\012')
012
on
sen luvun oktaaliesitys, jonka desimaaliesitys on 10). Vaikka vaikutus
on useissa järjestelmissä sama, niin se ei suinkaan ole
yleisesti sama.
Yleensä tulostuksen loppuunkin on syytä kirjoittaa
rivinvaihto eli kirjoittaa viimeinen rivi kuten muutkin,
esim. C:ssä printf("Loppu.\n")
, ei
printf("Loppu.")
.
Perusteluja tälle on
seuraavassa kohdassa.
Tiedoston lopussa ei loogisesti ottaen tarvittaisi mitään rivinvaihtokoodia. Tavallista on kuitenkin, että editorit ja tekstinkäsittelyohjelmat panevat loppuun rivinvaihdon. Jos loppuun kirjoitetaan useita rivinvaihtoja, niin on luonnollista ajatella siellä olevan tyhjiä rivejä, ja tämän mukaisesti monet ohjelmat toimivat.
Mahdollinen olisi sellainenkin ajatustapa, että jos lopussa on rivinvaihto, se merkitsee, että lopussa on yksi tyhjä rivi. Yllättävää kyllä Forté (Free) Agent -nyysiohjelma näyttää toimivan näin: jos artikkelia kirjoittaessa lopettaa sen painamalla returnia tai enteriä, niin ohjelma tekee siitä tyhjän rivin. Tästä johtuva esteettinen haitta on toki varsin pieni.
Tiedoston alussa rivinvaihto merkitsee yleensä sitä, että alussa on tyhjä rivi. Tästä voi aiheutua yllätyksiä, jos tiedostoa käsittelevä ohjelma ei ole siihen varautunut.
Unix-järjestelmien käyttäjille on aiheuttanut ongelmia se, että Emacs-editori ei automaattisesti kirjoita tiedoston loppuun rivinvaihtoa, ellei käyttäjä lopussa paina enteriä tai returnia. Tilanteen voi tarkistaa Emacsissa menemällä tiedoston loppuun (esim. M->:llä). Jos kursori jää viimeisen rivin loppuun eikä sen alle uuden rivin alkuun, lopusta puuttuu rivinvaihto. Tämä taas aiheuttaa hankaluuksia sen takia, että eräät ohjelmat eivät lainkaan käsittele sellaista "vajaata" riviä!.
Asiaa vielä mutkistaa se, että joissakin tilanteissa Emacs automaattisesti kirjoittaa tiedoston loppuun rivinvaihdon. Tämä saattaa ns. totuttaa liian hyvällä.
Olettakaamme, että meillä on teksti, jossa ei ole valmiita rivinvaihtoja ja joka pitäisi tulostaa paperille. Yhtä hyvin voimme olettaa, että valmiit rivinvaihdot pitää unohtaa eli teksti pitää muotoilla uudestaan. Joka tapauksessa meillä on olennaisesti teksti, joka on aivan liian pitkä mahtuakseen yhdelle riville ja joka siis pitää rivittää.
Oletamme, että jokin ulkoinen seikka kuten paperin tai kuvaruudun leveys määrää rivien enimmäispituuden. Emme tässä puutu siihen, että tämän pituuden mittayksikkönä voi olla merkki tai fysikaalinen mitta kuten millimetri. Emme myöskään puutu siihen, miten ohjelma laskee, paljonko kullekin riville mahtuu tai miten se mahdollisesti tasaa rivit samanmittaisiksi käyttämällä vaihtelevanmittaisia sananvälejä.
Yksinkertaisin rivitystapa on se, että jokaista välilyöntiä pidetään mahdollisena jakokohtana. Tässä on kaksi ongelmaa. Toisaalta tulos voi olla huono, koska mahdollisia jakokohtia on liian vähän, etenkin, jos rivinpituus on melko pieni (esim. sanomalehden palsta) ja jos tekstissä on pitkiä sanoja, kuten suomessa on. Toisaalta mahdollisia jakokohtia on liikaa, koska jokainen välilyönti ei ole fiksu jakokohta. Esimerkiksi ilmaisua "1 000 000" ei pitäisi jakaa eri riveille, ei mielellään myöskään sellaista kuin "5 m" (lue: "viisi metriä").
Jälkimmäiseen ongelmaan eräs ratkaisu on käyttää merkkiä tai merkintää, joka vastaa välilyöntiä mutta jonka kohdalta rivinjako ei ole sallittu. Ks. kirjoitusta Sitovan välilyönnin käyttö suomen kielessä. Tämä on melkoisen kömpelö tapa, koska tekstin kirjoittajan tai muokkaajan pitää nähdä paljon vaivaa. Toisenlaista lähestymistapaa edustaa Unicode Technical Report #14: Line Breaking Properties, jossa on pyritty yksityiskohtaisesti määrittelemään joukko perussääntöjä (oletussääntöjä) rivitykselle. Nämä säännöt, joita tuskin on vielä missään toteutettu, auttaisivat osaltaan parantamaan rivitysmenetelmiä. On kuitenkin huomattava, että ne koskevat merkkitasoa, eikä kaikkia asiaan liittyviä ongelmia voida suinkaan ratkaista sillä tasolla, siis esim. tyyppiä "sen-ja-sen merkin jälkeen ei saa panna rivinvaihtoa" olevilla säännöillä.
Tiedostojen siirtämisessä FTP:llä on kaksi eri siirtomuotoa, tekstimuotoinen ("ascii") ja binaarinen (binary, "image").
Binaarinen siirto tarkoittaa datan kopiointia sellaisenaan, ja sitä käytetään mm. kuvatiedostoille, tekstinkäsittelyohjelmien omissa formaateissa oleville dokumenteille sekä käännetyille ohjelmille - ylipäänsä kaikkeen, mikä ei ole tekstiä.
Tekstimuotoinen siirto poikkeaa tästä siten, että FTP-ohjelma ehkä pyrkii tekemään merkkikoodimuunnoksen siitä merkkikoodista, joka lähdekoneessa on käytössä, siihen merkkikoodiin, joka kohdekoneessa on käytössä. Esimerkiksi tällainen siirto Ebcdic-koodia käyttävästä koneesta Unix-koneeseen merkitsisi sitä, että kunkin merkin esitys muuntuu Ebcdicin mukaisesta Asciin tai esim. ISO Latin 1:n mukaiseksi. Asioita hankaloittaa se, että merkkikoodeista on eri versioita käytössä ja että yhden järjestelmän sisälläkin voi olla eri merkkikoodeja.
FTP-ohjelma saattaa yrittää "arvata" esimerkiksi tiedostonnimen perusteella, onko parempi käyttää binaarista vai tekstisiirtoa. Arvaus menee usein pieleen, joten on parempi, että käyttäjä määrää tavan. Esim. suositussa WS_FTP-ohjelmassa on painonapit tätä varten (ASCII ja Binary).
Tekstimuotoisessa siirrossa voi myös rivinvaihtojen esitys muuttua.
Jos PC:stä siirretään tekstitiedosto esim. Unix-koneeseen,
on syytä käyttää tekstimuotoa silloinkin, kun se ei merkkikoodien takia
olisi tarpeen. Jos nimittäin siirretään
binaarimuodossa, niin tulos voi olla muutoin normaali
mutta esimerkiksi
Emacsilla
katsottaessa jokaisen rivin lopussa
näkyy ^M
. Tämä on Emacsin tapa kertoa, että siellä
on CR eli "control-M", joka on Unixissa aivan ylimääräinen merkki.
Ohjelmasta riippuu, haittaako CR, mutta ei siitä mitään hyötyäkään ole.
Jos tiedosto olisi siirretty tekstimuodossa, olisi rivinvaihdon esitys
Unixin normaali LF eikä CR LF. Mutta asian voi toki korjata
jälkikäteenkin, esimerkiksi Emacsin
korvauskäskyllä,
kontrollikoodit control-Q:lla "lainaten":
Kyseisen muunnoksen voi toki tehdä myös erilaisilla ns.
työkaluohjelmilla
Unixissa, esim. tr
-ohjelmalla näin:
tr -d '\015' < vanhatiedosto > uusitiedosto
Kuten Nyysioppaan kohdassa Teknisiä rajoituksia: merkistö, rivinpituus ym. neuvotaan, nyysiartikkelin tulisi olla pelkkää tekstiä, jaettuna riveihin, joiden pituus on enintään 80 merkkiä, mieluiten enintään 72 merkkiä (mutta ei toisaalta kovin lyhytrivistäkään).
Ongelmia aiheuttavat tässä suhteessa erityisesti sellaiset nyysiohjelmat, jotka noudattavat tekstinkäsittelyohjelmien käytäntöä: ne jakavat käyttäjän kirjoittaman tekstin kuvaruudulla eri riveille mutta sisäisesti tallentavat ja lähettävät sen siten, että kukin kappale on yksi rivi. Tämä sopii erittäin huonosti nyyseihin.
Mainitut ongelmat kyllä hoitunevat yleensä panemalla ohjelman asetukset kuntoon. Ks. erityisesti Nyysioppaan kohtaa Web-selainten nyysikäyttö. Kummallista on, että Outlook Expressissä on, ainakin eräässä versiossa, oletusasetuksena "Automatically wrap text at 132 characters, when sending" mutta siihen liittyvä ohjeteksti sanoo (sinänsä lähes asiallisesti):
Specifies whether Outlook Express should automatically wrap
the text of outgoing messages so that each line is no more than
the number of characters indicated. Some older Internet mail
programs do not properly display messages with lines over 80
characters long. If you clear this check box, your message
might appear to have extra line breaks to recipients whose mail
or newsreading program can display only 80 characters per line.
It is suggested that you set your limit to about 72 characters.
Most mail and newsreading programs indent quoted text in
replies or forwards. Setting the limit to 72 allows the message to
be quoted several times without causing extra line breaks.
Mainittu 132 merkin oletusarvo on tietysti huutavassa ristiriidassa opastustekstin kanssa. Ja se aiheuttaa tyypillisesti sen, että jos käyttäjä ei itse paina returnia tai enteriä vaihtaakseen riviä, ohjelma näyttää sen hänelle järkevännäköisesti mutta lähettää noin 132-merkkisiä rivejä. Ja luettuna ohjelmalla, joka katkoo yli 80-merkkiset rivit voidakseen ylipäänsä näyttää ne, viesti onkin sitten aika karmeannäköisessä muodossa: joka toinen rivi noin 80-merkkinen, joka toinen noin 50-merkkinen! Itse asiassa se ei edes OE:llä itsellään luettuna näytä järkevältä, vaan tämäntapaiselta:
Olipa kerran ukko ja akka. Ja he kirjoittivat pitkähkön tekstiviestin nyyseihin nähdäkseen, miten Outlook Express jakaa tekstin riveiksi, kun käytetään tavallisen tyhmiä oletusasetuksia. Saapa nähdä, mitä tästäkin tulee. Ja vielä pitäisi keksiä lisää tekstiä. No jospa nyt jo riittäisi!
Joten se 132 on todella syytä muuttaa 72:ksi.
HTML-kielellä tehdyissä lomakkeissa Web-sivuilla voi olla muun muassa seuraavanlaisia kenttiä:
Return- tai enter-näppäimen painamisella eri kentissä voi olla hyvin erilaisia vaikutuksia. Kyse ei varsinaisesti ole rivinvaihtokoodeista vaan näppäimistä, mutta on olennaista, milloin rivinvaihtonäppäimen painaminen aiheuttaa rivinvaihtokoodin sisällyttämisen lomakedataan ja milloin ei. |
Tekstirivin syötössä alkuperäisenä ideana oli se, että jos lomakkeessa on vain yksi tekstinsyöttökenttä, selain voisi käsitellä return- tai enter-näppäimen painalluksen lomakkeen lähettämispyyntönä. Tämä ei aiheuta mitään rivinvaihtokoodia lähtevään lomakedataan (esim. hakusanoihin). Tämä sopii hyvin yksinkertaisiin hakulomakkeisiin:
Tällöin on huomattava, että jos lomakkeessa olisi esimerkiksi valintanapeilla valittavia vaihtoehtoja, jotka tarkemmin ohjaavat hakua, käyttäjä saattaa tulla lähettäneeksi lomakkeen liian aikaisin. Hän ehkä ajatteli kirjoittaa ensin hakusanat ja sitten kiinnittää huomionsa nappeihin, mutta "vaistonvaraisesti" lopetti tekstin kirjoittamisen enterillä. Hakulomakkeissa tämä ei ole kovin vakavaa, koska haun voi uusia, mutta se voi olla ikävää, jos lomakkeella tilattiin auto ja oletusarvona oli Rolls Royce.
Erityisiä hankaluuksia on aiheuttanut se, että Internet Exploreriin
tuli versiossa 4 "parannus": edellä kuvattu idea toimii myös
silloin, kun lomakkeessa on useita tekstirivikenttiä.
Tämä saattaa joissakin erikoistapauksissa; ks. esim.
lomakettani nyyseistä tehtäviä hakuja varten, jota tämän
ansiosta voi IE:llä käyttää niin, että esim. kirjoittaa vain meiliosoitteen
yhteen kenttään ja painaa enteriä, jolloin saa listan artikkeleista,
joiden From
-kentässä on kyseinen osoite. Mutta
yleisesti tämä piirre on erittäin huono. Ks.
Alan Flavellin
kirjoitusta
Submit form by hitting ENTER?
Käytännössä
Yleisemmin tällainen enterin tai returnin käyttö on esimerkki kyseisten näppäinten käytöstä valintaan tai vahvistukseen. Tämä saattaa olla jossain määrin hämäävää, koska sillä loogisesti ottaen ei ole rivinvaihdon kanssa muuta tekemistä kuin että voidaan tulkita, että kyse on tyhjän rivin syöttämisestä. Esimerkiksi tekstipohjaisissa käyttöliittymissä on tavallista, että valikosta valitaan vaihtoehto menemällä sen kohdalle ja painamalla enteriä. (Toinen tavallinen vaihtoehto on välilyöntinäppäin, mutta tämä tietysti riippuu ohjelmasta.) Vastaavasti ohjelma saattaa kysyä vahvistusta jonkin toimenpiteen suorittamiselle, oletusarvojen hyväksymiselle tms. siten, että pelkän enterin painaminen merkitsee vahvistusta. Tilanteesta riippuu, onko tämä mielekästä. Varmempi varmistus on toki sellainen, jossa käyttäjän pitää kirjoittaa esim. yes ja painaa enteriä. Mitä tärkeämmästä toimenpiteestä on kyse, sitä hyväksyttävämpää on vaatia ylimääräistä näpyttelyä.
Monirivisessä tekstikentässä
perusajatuksena on mahdollistaa mielivaltaisen tekstimäärän syöttö.
Käytännössä selaimet asettavat tälle
joitakin rajoituksia. Mutta erityisesti ideana on, että
textarea
-elementin rows
- ja
cols
-määrite ilmoittavat vain näkyvän alueen koon;
sekin on sarakkeiden määrän osalta lähinnä viitteellinen ainakin silloin,
kun kirjasimet eivät ole tasalevyisiä. Tarkoitus ja
joidenkin selainten käytäntö on,
että käyttäjä voi kirjoittaa mielivaltaisen pitkiä rivejä ja niin monta
riviä kuin haluaa, vaikka tämä "rullauksen" takia voikin olla hankalaa,
jos näkyvän alueen koko ylitetään. Kun käyttäjä kirjoittaessaan
vaihtaa riviä (painaa returnia tai enteriä), dataan
tulee mukaan rivinvaihtokoodi. Sen esitys on tässä yhteydessä
lisäksi tarkoin määritelty, siitä riippumatta, mikä on käytetyn
tietokonejärjestelmän "oma" esitysmuoto: CR LF, jonka selain
lomakedataa koskevien koodaussääntöjen mukaan esittää
ns. URL-koodatussa muodossa
. Lomaketta käsittelevä
ohjelma yleensä "näkee" tämän datan kuitenkin sellaisen liitynnän
kautta, että ohjelmassa voidaan suoraan testata rivinvaihtoa tyyliin
if(merkki=='\n')
(tietenkin kunkin ohjelmointikielen
sääntöjen mukaan). Yksityiskohdat riippuvat siitä, millaisia rutiineita
käytetään, mutta edellä sanottu pätee esim. yleisesti käytettyyn
CGI.pm
-moduliin.
Valitettavasti ainakin Internet Explorer ja Opera toimivat väärin. Ne jakavat tekstiä eri riveille omia aikojaan (tekstinkäsittelyohjelmien tapaan). Tosin tämä koskee vain näkyvää esitysmuotoa, sillä itse lomakedataan ne eivät sisällytä mitään tästä johtuvia rivinvaihtoja. Mutta tästä seuraa, että käyttäjä ei näe, mikä on hänen kirjoittamansa ja siten itse datan mukana lähtevä rivinvaihto.
Asia voidaan korjata IE:n osalta lisäämällä
textarea
-elementtiin määrite wrap="off"
.
Tällainen määrite ei kuulu mihinkään HTML-spesifikaatioihin,
mutta se siis tarvitaan, jos halutaan IE:n toimivan
spesifikaation mukaisesti!
IE ja Netscape, ainakin niiden tarpeeksi uudet versiot, tunnistavat myös
määritteen
wrap="hard"
, mutta sen aiheuttamat ns. kovat rivinvaihdot ovat
vielä pahempi vaihtoehto: selain lisäilee todellisia rivinvaihtoja dataan siten,
että muun haitan lisäksi käyttäjän on mahdotonta syöttää pitempää riviä kuin
cols
-määrite ilmoittaa. (Lomakkeen tekijä ei tietenkään voi
luottaa tällaiseen rajoitukseen, koska se on selainkohtainen ja
muutenkin kierrettävissä.)
- Lisätietoja wrap
-määritteestä on
dokumenttini
How to limit the number of characters entered in a
textarea
in an HTML form kohdassa
Implementations, especially wrapping.
Jos lomakedatan käsittelyssä halutaan huolehtia siitä, että rivit eivät ole liian pitkiä jatkokäsittelyyn mennessään, täytyy käsittelevän ohjelman joka tapauksessa varautua pilkkomaan tai katkomaan rivejä. Tarvittaessa on tietysti annettava käyttäjälle huomautus tai varoitus tai ehkä palautettava lomake korjaamista varten.
Lomakkeenlähetyskentän input type="submit"
tyypillinen graafinen selain toteuttaa "nappina" (fyysistä painonappia
tai nappulaa muistuttavana näyttöoliona, engl. button), ja
tavallisin tapa käyttää sitä on napsauttaa (engl. click) sitä
hiiren avulla. On kuitenkin mahdollista - useissa
graafisissakin selaimissa - siirtyä lomakkeen kentästä toiseen
sarkausnäppäintä (tab key) käyttämällä. Ja kun on tällä tavoin siirrytty
lomakkeenlähetyskenttään, enterin painaminen yleisesti vastaa napsauttamista
eli lähettää lomakkeen. Tämä on käytettävyyttä olennaisesti parantava seikka
muun muassa siksi, että se mahdollistaa lomakkeen täyttämisen ja lähettämisen
silloinkin, kun hiirtä ei ole tai sitä ei syystä tai toisesta voi käyttää.