OmniMark
OmniMark är ett fjärde generationens programmeringsspråk som används mest inom förlagsbranschen . Det är för närvarande en egenutvecklad mjukvaruprodukt från Stilo International. Från och med juli 2022 var den senaste versionen av OmniMark 11.0.
Användande
OmniMark används för att bearbeta data och konvertera det från ett format till ett annat, med hjälp av en strömningsarkitektur som gör att den kan hantera stora volymer innehåll sekventiellt utan att behöva ha allt i minnet. Den har en inbyggd XML- parser och stöd för XQuery via integration med Sednas inbyggda XML-databas. Den har också funktioner för att bearbeta hitta regler som implementerar ett liknande koncept som reguljära uttryck , även om syntaxen för mönsteruttryck är mer engelsk-liknande än den reguljära uttryckssyntax som används i Perl och andra språk som Ruby-programmeringsspråket , som båda är mer allmänt används än OmniMark. OmniMark kan också användas för schematransformationsuppgifter på samma sätt som XSLT , men stöder växling mellan procedurkod och funktionell kod utan att behöva några ytterligare konstruktioner för att stödja procedurelementen.
Historia
OmniMark skapades ursprungligen på 1980-talet av Exoterica, ett kanadensiskt mjukvaruföretag, som ett SGML- bearbetningsprogram som heter XTRAN. XTRAN döptes senare om till OmniMark och Exoterica blev OmniMark Technologies. De nuvarande ägarna av OmniMark, Stilo International, har sina huvudkontor i Storbritannien men har även ett kontor i Kanada.
1999 meddelade OmniMarks VD och koncernchef John McFadden att OmniMark 5 skulle vara tillgänglig gratis för att bättre kunna konkurrera med Perl. OmniMark distribueras inte längre under en sådan modell.
Programmeringsmodell
OmniMark behandlar input som ett flöde som kan skannas en gång, snarare än som en statisk samling av data som stöder slumpmässig åtkomst. Mycket av ett OmniMark-program är i form av condition=>action rule där villkoret känner igen en längd av data som ska åtgärdas och åtgärden specificerar vad som ska göras med data. Det finns två typer av tillstånd:
- En elementregel , som endast kan användas med strukturerade dokument (välformad XML, giltig XML eller SGML), känner igen ett komplett element: starttaggen, elementinnehållet och sluttaggen. Eftersom innehållet kan innehålla andra element, kan elementregler fungera på ett kapslat sätt. OmniMark hanterar kapslingen på ett sådant sätt att elementreglerna kan definieras oberoende av varandra.
- Ett mönster , som kan användas med både strukturerade och ostrukturerade dokument, känner igen en textlängd. Mönster används som reguljära uttryck på andra språk (python, Perl, awk, ...) men har en engelsk-liknande syntax som underlättar skapandet av komplexa uttryck. När du analyserar ett strukturerat dokument kan mönster användas på text som går in i tolken eller på text som kommer ut ur tolken.
Bearbetar ostrukturerad input
Hitta regler används för att tillämpa mönster på ostrukturerad inmatning. Längder på text känns igen av ett mönster som inkluderar tillfälliga mönstervariabler för att fånga alla delar av texten som kommer att behövas i utdata. Åtgärden använder dessa variabler för att producera den önskade utdata :
; Ändra priser från engelskt format till franskt format hitta "$" siffra + => dollar "." siffra { 2 } => cent ; mata ut priset i nytt format output dollar || "," || cent || "$"
Om två sökregler kan känna igen samma textsekvens kommer den första regeln att "äta upp" sekvensen och den andra regeln kommer aldrig att se texten. Indata som inte känns igen av någon sökregel "äts inte upp" och går rakt igenom till utgången.
Bearbetar strukturerad indata (XML, SGML)
OmniMark ser input som ett flöde; ett program håller inte indata i minnet om inte en del av datan har sparats i variabler. När inmatningen flyter förbi, upprätthåller OmniMark en elementstack som innehåller information som kan användas för att styra omvandlingen av text via OmniMarks mönstermatchningsfunktion. När varje starttagg påträffas, skickar OmniMark ytterligare en elementbeskrivning på stacken. Elementbeskrivningen inkluderar elementnamnet, attributnamnen med attributens typer och värden, tillsammans med annan information från parsern (t.ex. om det elementet är ett EMPTY-element). När motsvarande sluttagg påträffas, plockas elementbeskrivningen från toppen av stacken. Med SGML kan vissa taggar utelämnas, men OmniMark agerar som om taggarna fanns och på rätt ställen.
OmniMark element stack
innehåll < h1 > . </ h1 > < body > | . | </ body > < exempel > | | . | | </ exempel > | | | . | | | | | | . | | | | | | . | | | ABC . DEF X X: aktuell position i inmatningsdokumentet Skanna Tillgänglig platsinformation A till F element exempel B till E element exempel, body C till D element exempel, body, h1 C början av innehåll D slutet av innehåll
Ett OmniMark-program använder elementregler för att bearbeta XML- eller SGML-dokument. En elementregel :
- får kontroll precis efter att starttaggen har analyserats och elementbeskrivningen har tryckts på elementstacken. Åtgärden för elementregeln har tillgång till beskrivningarna av det aktuella elementet och alla förfäderselement s tillbaka till dokumentroten.
- skickar kontrollen tillbaka till parsern genom att begära det analyserade innehållet i elementet i specialvärdet "
%c"
. Innehållet begärs vanligtvis för skanning med mönstermatchning, snarare än för lagring i en variabel. - får kontroll igen när motsvarande sluttagg har analyserats, men innan elementbeskrivningen tas bort från elementstacken. Åtgärden för elementregeln har fortfarande tillgång till beskrivningarna av det aktuella elementet och alla förfäderelement tillbaka till dokumentroten.
Eftersom element kan kapslas kan flera elementregler vara i spel samtidigt, var och en med en motsvarande elementbeskrivning på elementstacken. Elementregler är avstängda medan de väntar på att tolken ska slutföra analysen av deras innehåll. Endast regeln för elementet överst i stack kan vara aktiv. När slutet av innehållet nås för elementet överst i stack, får åtgärden för motsvarande elementregel kontroll igen. När den åtgärden avslutas, visas elementbeskrivningen och kontrollen återgår till åtgärden för nästa lägre element i stacken. En elementregel kan helt enkelt mata ut det analyserade innehållet (som text) och lägga till ett suffix:
element "kod" utgång "%c" ; tolka och utdataelementinnehåll gör när förälder inte ( "h1" | "h2" | "h3" | " h4" | "h5" | "h6") utmatning "%n" ; lägg till en ny rad om inte i en rubrik klar
Ett program behöver inte namnge alla dokumentelement om de icke namngivna elementen kan ges någon form av generisk bearbetning:
element #implied gör när förälder är "huvud" undertrycka ; kassera underordnade element annars utdata "%c" ; tolka och mata ut elementinnehåll gjort
Mönstermatchning vid utdata från parsern
Det analyserade innehållet för varje element görs tillgängligt inom en elementregel och kan modifieras av ett repeterande ... skanningsblock som använder mönster för att identifiera texten som ska modifieras:
element "p" ; Ändra priser från engelskt format till franskt format upprepad skanning "%c" ; tolka och skanna elementinnehåll matchar "$" siffra + => dollar "." siffra { 2 } => cent ; mata ut priset i nytt format output dollar || "," || cent || "$" matchar ( alla utom "$" ) + => text ; mata ut icke-prissekvenser utan förändring utdata text match "$" => text ; utgång isolerad valutasymbol utan ändring utgångstext klar
Det första mönstret som matchar en inledande del av texten kommer att "äta upp" den texten och texten kommer inte att vara tillgänglig för följande mönster även om en av följande delar skulle kunna matcha en längre inledande del av texten. Varje inledande del som inte matchar ett av mönstren i ett repeterande ... skanningsblock kommer att kasseras.
Mönstermatchning vid inmatning till parsern
Översättningsregler får kontroll precis efter att taggar har separerats från text men innan analysen är klar. Varje översättningsregel har ett mönster som identifierar en textlängd som ska bearbetas. Den textlängden kommer inte att innehålla några taggar, men kan vara lika mycket som hela textlängden mellan två taggar.
En användning av översättningsregler är att göra en specifik förändring genom ett helt dokument:
; Ändra uppmärkningstecken till entitet som representerade det i indatatranslate " &" output "&"
Taggarna före den aktuella punkten i inmatningen har redan gått igenom parsern, så elementstacken har redan en beskrivning av elementet (eller kapslade element) som innehåller texten. Följaktligen kan informationen på elementstacken användas för att styra vad som görs med texten. Till exempel kan operationen av en översättning begränsas till teckeninnehållet i ett eller flera element:
; Ändra priser från engelskt format till franskt format översätt "$" siffra + => dollar "." siffra { 2 } => cent när element är ( "p" | "kod" ) ; mata ut priset i nytt format output dollar || "," || cent || "$"
Exempelkod
I vissa applikationer kan mycket av ett dokument hanteras av en väldesignad generisk handling, så att endast en bråkdel av dokumentet behöver specialhantering. Detta kan avsevärt minska storleken och komplexiteten hos ett program och, när det gäller XML-dokument, kan det göra ett program mycket tolerant mot förändringar i strukturen för inmatningsdokumentet.
Ett enkelt program
Detta är det grundläggande "Hej, värld!" program :
processutgång "Hello World!"
Ostrukturerad inmatning (text)
Det här programmet matar ut alla ord som börjar med stor bokstav, ett ord per rad och kasserar all annan text:
process skicka filen "minfil.txt" ; eller skicka "ALL text kassera gemener" ; mata ut ord med versaler, lägg till en nyradssökning ( uc bokstav * ) = > temp output temp || "%n" ; kassera alla andra tecken hitta några ; ingen utgång
Strukturerad indata (XML)
OmniMark kan acceptera välformaterad XML, giltig XML eller SGML som strukturerad indata. Det här programmet matar ut en lista med rubriker på första och andra nivån från en xhtml-fil, och drar in rubrikerna på andra nivån:
; xhtml-headings.xom ; Lista rubriker på första och andra nivån från xhtml- eller xhtml5-filen ; Andra nivåns rubriker är indragna process ; omvandla inmatningsdokumentet ; gör xml-parse dokument ; parse giltig XML do xml - parse ; tolka välformad XML- skanningsfil " example.html" output "%c" ; tolka och mata ut dokumentinnehåll gjort element "head" suppress ; kassera underordnade element element "h1" utgång "%c" ; analysera och mata ut elementinnehåll utdata "%n" ; lägg till ett linjeändelement "h2" output " " ; indrag 2 blanksteg utgång "%c" ; analysera och mata ut elementinnehåll utdata "%n" ; lägg till en radslut ; hantera alla element som inte nämns i explicita regler ovanför elementet #implied do när förälder är "kropp" ; kassera alla underordnade element förutom de som nämns ovan undertrycka ; kassera underordnade element annat ; behåll innehållet i alla andra elementutdata " %c" ; tolka och mata ut elementinnehåll gjort ; kassera teckeninnehåll från elementet "body" om det elementet ; har blandat innehåll översätt alla + => X när element är body ; ingen utgång (gör ingenting med variabel "X")
Elementet #implied
regeln tar upp alla element som inte känns igen av någon av de andra elementreglerna.
Structured input (SGML)
Detta program ersätter de utelämnade taggarna i ett enkelt SGML-dokument och matar ut något som liknar välformaterad XML. Programmet översätter inte tomma SGML-taggar korrekt till tomma XML-taggar och det hanterar inte många av de SGML-funktioner som kan användas i SGML-dokument.
Program
; Infoga utelämnade taggar i SGML-dokument ; ; Detta program är förenklat, endast för demonstration, ; Programmet hanterar inte många funktioner i SGML ; Ett mer utarbetat program skulle krävas för att producera ; välformad XML från de flesta SGML-dokument. process do sgml - tolka dokumentskanna fil "example.sgml" output " %c" ; analysera och mata ut dokumentinnehåll gjort element #implied output "<%q" ; börja start tagg ; skriv attribut som name="value"-par upprepas över specificerade attribut som attr- utgång " " || nyckel för attribut attr || "=%" % v ( attr ) % "" igen output ">" ; avsluta starttagg ; skriv elementinnehåll utdata "%c" ; skriv sluttagg om element tillåter innehållsutmatning " </%q>" om inte innehållet är ( tom | conref ) ; översätta uppmärkningstecken (i text) tillbaka till enheterna ; som representerade dem i den ursprungliga ingången översätt "&" output "&" översätt "<" utgång "<" translate ">" output ">"
Exempelinmatning
<!-- Ett enkelt SGML-dokument för inmatning till OmniMark-demos --> <!DOCTYPE-exempel [ <!ELEMENT-exempel O - (huvud, kropp)> <!ELEMENT-huvud OO (titel?)> <!ELEMENT-titel - - ( #PCDATA)> <!ELEMENT body - O ((empty|p)*)> <!ELEMENT empty - O EMPTY> <!ELEMENT p - O (#PCDATA)> <!ATTLIST P id ID #IMPLIED> <!ENTITY amp "&"> <!ENTITY lt "<"> <!ENTITY gt "> "> ]> <exempel> <title> Titel </title> <body> <p> Text <empty> <p id= "P -2" > <&> </exempel>
Exempel utgång
<EXAMPLE><HEAD><TITLE> Titel </TITLE></HEAD><BODY><P> Text </P><EMPTY><P ID= "P-2" > <&> </P></BODY></EXAMPLE>
Vidare läsning
- Baker, Mark (2000). Internetprogrammering med OmniMark . Boston: Kluwer Academic Publishers.
- Smith, Norman E. (1998). Praktisk guide till SGML/XML-filter . Plano, TX: WordWare Publishing.
externa länkar
- Stilo Omnimark
- OmniMarks utvecklarresurser
- OmniMarks programmeringsprinciper - Allmänt index (översiktsbild av internetarkiv av onlinebok av Errol Chopping)