*>b:DetagHTML * The above line is for my PhxAss.rexx script for CED (autosaves binary to this path/name) *««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««* * * © 1997 by Kenneth C. Nilsen. E-Mail: kennecni@IDGonline.no * * Name * DetagHTML.asm a very FAST html stripper/entity converter * * Synopsis * DetagHTML * * Function * Strips HTML tags and converts entities to ISO chars. Special * developed for use with Thor messages and the new Netscape * "fever".. HTML postings on the usenet.. cheese! :-) * * Inputs * - load file. Save as + .txt * * Notes * Public Domain.. do what you want with this source. Just * remember to give me credit for it :^) * * Assemble with UCASE=LCASE! You will also need the * Startup.asm file (in archive) pluss OS includes. * Original assembled with PhxAss 4.34. * * Changes * * 1.3 - All entities added * More typos changed * Added WARN return in case of error (no HTML tag found) * Added better header info to mail/news in script * 1.2 - Improved arexx script for thor * Optimized search routine * Optimized special table routine * Optimized uppercase routine for specific use * Optimized compare routine (tag) * Optimized file extension copier * Removed dir check.. can't open() a dir anyway.. * Removed size check on read * Changed &NBSP; (non breakable space) to space (32) * Changed about text (option ?) * Corrected more typos (entities) * 1.1 - Added more tags * * Bugs * What?! :-) * * Created : 5.1.97 * Last change : 13.1.97 *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»* StartSkip = 0 Incdir "" Include lvo:Exec_lib.i Include lvo:Dos_lib.i Incdir inc: Include dos/dos.i Include Startup.asm Incdir "" dc.b "$VER: DetagHTML 1.3 (13.1.97)",10 dc.b "Copyright © 1997, Kenneth C. Nilsen. All rights reserved. ",0 even *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»* Call Macro jsr _LVO\1(a6) ENDM *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»* Init TaskName "DetagHTML" DefLib dos,37 DefEnd Start LibBase dos Call output ;get default output handler move.l d0,OutH NextArg beq About move.l d0,a0 cmp.b #'?',(a0) beq About lea FileName(pc),a1 ;name buffer .copy move.b (a0)+,(a1)+ ;fast copy.. bne.b .copy ; check file: move.l #FileName,d1 move.l #1005,d2 Call Open ;try open that file.. move.l d0,File beq ErrorF LibBase exec move.l #260,d0 move.l #$10002,d1 ;need 260 bytes in chipmem Call AllocMem ;for FIB.. should perhaps use AllocDosObject(), but move.l d0,DosO ;it's not required with FIB/Examine(FH) beq ErrorM LibBase dos move.l d0,d2 move.l File(pc),d1 Call ExamineFH ;get FIB of file tst.l d0 beq ErrorE move.l fib_size(a0),Size ;get filesize beq ErrorS ;allocate memory and read file into buffer: LibBase exec move.l Size(pc),d0 addq.l #1,d0 ;so we get a nullterminated buffer move.l #$10001,d1 ;size of file+1 in any mem Call AllocMem move.l d0,Mem beq ErrorM LibBase dos move.l File(pc),d1 move.l d0,d2 move.l Size(pc),d3 Call Read ;read whole file into buffer (it's ;a text message.. usually not multimegs..) move.l File(pc),d1 Call Close clr.l File ;clear so we don't crash at exit (cleanup) ; Ok, check if there exists a tag in buffer: move.l Mem(pc),a5 .search move.b (a5)+,d1 beq .noTag cmp.b #'<',d1 ;search tag identifier bne.b .search .check moveq.l #6,d0 lea Buffer(pc),a0 lea -1(a5),a5 .copyKW move.b (a5)+,(a0)+ ;search for "" or "" or "" etc. tst.b (a5) beq .noTag subq.l #1,d0 bne.b .copyKW ; upper case: lea Buffer+1(pc),a0 ;everything in uppercase.. easier to compare :-) moveq.l #3,d0 ;number of chars to uppercase .loop and.b #($ff-$20),0(a0,d0.w) .cont dbra d0,.loop ; compare: lea KeyWord(pc),a0 ;compare with out keyword lea Buffer+1(pc),a1 moveq.l #4,d0 .cmp cmp.b (a0)+,(a1)+ bne.b .search dbra d0,.cmp ; Strip rest of buffer: ;*** PASS 1 - STRIP TAGS < -- > move.l OutH(pc),d1 beq.b .noOutP1 move.l #Pass1,d2 moveq.l #Pass1L,d3 Call Write .noOutP1 move.l Mem(pc),a5 lea (a5),a4 ;"new" buffer (stripped html will be less or equal!) moveq.l #0,d7 ;counter for new filesize .detag move.b (a5)+,d0 beq.b .done cmp.b #'<',d0 ;search for html tags beq .strip cmp.b #13,d0 ;strip LF-NL beq.b .next move.b d0,(a4)+ addq.l #1,d7 .next bra.b .detag .strip move.b (a5)+,d0 beq.b .done cmp.b #'>',d0 ;end of html tag bne.b .strip bra.b .detag .done clr.b (a4) ;end of new buffer move.l d7,NewSize beq ErrorW ;nothing left in buffer ;*** PASS 2 - CONVERT ENTITIES TO ISO move.l OutH(pc),d1 beq.b .noOutP2 move.l #Pass2,d2 moveq.l #Pass2L,d3 Call Write .nooutP2 move.l Mem(pc),a5 lea (a5),a4 moveq.l #0,d7 .convr move.b (a5)+,d0 beq.b .doneConvert cmp.b #'&',d0 ;search for "&" in entities beq.b .checkTable .noEnt move.b d0,(a4)+ addq.l #1,d7 bra.b .convr .checkTable lea FromTable(pc),a3 ;check with table of entities moveq.l #0,d6 .cmpEnt move.l (a3)+,d1 beq.b .noEnt move.l d1,a0 addq.w #1,d6 lea (a5),a1 .doit tst.b (a0) beq.b .itsHit cmp.b (a0)+,(a1)+ beq.b .doit bra.b .cmpEnt .itsHit move.b d6,d0 cmp.b #64,d0 ble.b .table sub.b #65,d0 lea SpecialTab(pc),a1 ;special entities (NBSP,GT,ST,QUOT etc.) move.b 0(a1,d0.w),d0 bra.b .movePr .table add.b #191,d0 .movePr moveq.l #8,d2 .moveFW move.b (a5)+,d1 beq.b .doneConvert ;end of buffer subq.l #1,d2 beq.b .noEnt ;safty margin if entity is buggy (missing ";") cmp.b #';',d1 bne.b .moveFW ;get mempointer to end of entity bra .noEnt .doneConvert tst.l d7 beq ErrorW ;nothing left in buffer ; this part will strip all unused linefeeds at the end of the buffer: move.l Mem(pc),a0 cmp.l #3,d7 blt.b .save ;< 3 bytes ? skip LF stripping add.l d7,a0 lea -2(a0),a0 ;save one LF .strpLF cmp.b #10,(a0) bne.b .save lea -1(a0),a0 subq.l #1,d7 bne.b .strpLF bra ErrorW ; Save file: .save move.l d7,NewSize lea FileName(pc),a0 .findE tst.b (a0)+ bne.b .findE lea Extension(pc),a1 lea -1(a0),a0 .copyEx move.b (a1)+,(a0)+ ;append ".txt" to filename bne.b .copyEx move.l #FileName,d1 move.l #1006,d2 Call Open move.l d0,File beq ErrorSA move.l d0,d1 move.l #Header,d2 move.l #HeaderL,d3 Call Write ;save header move.l File(pc),d1 move.l Mem(pc),d2 move.l NewSize(pc),d3 Call Write cmp.l d3,d0 bne ErrorLE ;didn't write whole buffer.. corrupt? move.l OutH(pc),d1 beq.b .bye move.l #Done,d2 moveq.l #7,d3 Call Write ;we're done! .bye bra Close .noTag bra ErrorH *----------------------------------------------------------------------------* Close LibBase dos move.l File(pc),d1 beq .noFile Call Close ;close file .noFile LibBase exec move.l Mem(pc),d0 beq .noMem move.l d0,a1 move.l Size(pc),d0 addq.l #1,d0 Call FreeMem ;remove file from memory .noMem move.l DosO(pc),d0 beq .noOb move.l d0,a1 move.l #260,d0 Call FreeMem ;remove FIB buffer .noOb tst.b Warn beq.b .exit Return 5 .exit Return 0 *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»* InitTxt macro move.l #\1,d2 bra Print endm About InitTxt AboutTxt ErrorF InitTxt ErrorFile ErrorD InitTxt ErrorDos ErrorE InitTxt ErrorExamine ErrorS InitTxt ErrorSize ErrorM InitTxt ErrorMem ErrorH st Warn LibBase dos lea FileName(pc),a0 .findE tst.b (a0)+ bne.b .findE lea Extension(pc),a1 lea -1(a0),a0 .copyEx move.b (a1)+,(a0)+ ;append ".txt" to filename bne.b .copyEx move.l #FileName,d1 move.l #1006,d2 Call Open move.l d0,d5 beq .skip move.l d0,d1 move.l #ErrFile,d2 move.l #ErrFileL,d3 Call Write ;save header move.l d5,d1 Call Close .skip InitTxt ErrorHTML ErrorW InitTxt ErrorWrite ErrorSA InitTxt ErrorSave ErrorLE move.l #ErrorWrite2,d2 Print LibBase dos move.l OutH(pc),d1 beq.b .noOut moveq.l #0,d3 ;size of string move.l d2,a0 .count tst.b (a0)+ beq.b .end addq.w #1,d3 ;no internal text in this program is bra.b .count ;larger than 64kb... .end Call Write .noOut bra Close *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»* File dc.l 0 Size dc.l 0 NewSize dc.l 0 Mem dc.l 0 DosO dc.l 0 OutH dc.l 0 Buffer dcb.w 3,0 *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»* FromTable dc.l Bagrave,Baacute,Bacirc,Batilde,Bauml,Baring,Baelig dc.l Bccedil,BEgrave,BEacute,BEcirc,BEuml,Bigrave,Biacute dc.l BIcirc,Biuml,BETH,BNtilde,BOgrave,BOacute,BOcirc dc.l BOtilde,BOuml,dummy,BOslash,BUgrave,BUacute,BUcirc dc.l BUuml,BYacute,BTHORN,szlig,agrave,aacute,acirc,atilde dc.l auml,aring,aelig,ccedil,egrave,eacute,ecirc,euml dc.l igrave,iacute,icirc,iuml,eth,ntilde,ograve,oacute dc.l ocirc,otilde,ouml,dummy,oslash,ugrave,uacute,ucirc dc.l uuml,yacute,thorn,yuml,nbsp,gt,lt,quot,copy,reg dc.l apos,ast,brvbar,cent,colon,comma,commat,deg,dollar dc.l emsp,ensp,equals,excl,half,hyphen,iexcl,iquest dc.l laquo,lpar,lsqb,micro,middot,ndash,not,para dc.l percnt,period,plus,plusmn,pound,quest,raquo,rpar dc.l rsqb,sect,semi,shy,tilde,trade,yen,verbar,amp dc.l mdash,frac12,frac14,frac34,frac18,frac38,frac58 dc.l frac78,sup1,sup2,sup3,0 SpecialTab dc.b " ",">","<",'"',"©","®","'","*","¦","¢",":",",","@" dc.b "°","$"," "," ","=","!","½","-","¡","¿","«","(","[" dc.b "µ","·"," ","¬","¶","%",".","+","±","£","?","»",")" dc.b "]","§",";","­","~","®","¥","|","&"," ","½","¼","¾" dc.b "#","#","#","#","¹","²","³" ;Every entities: (hopefully) dummy dc.b " ;",0 Bagrave dc.b "Agrave;",0 Baacute dc.b "Aacute;",0 Bacirc dc.b "Acirc;",0 Batilde dc.b "Atilde;",0 Bauml dc.b "Auml;",0 Baring dc.b "Aring;",0 Baelig dc.b "AElig;",0 Bccedil dc.b "Ccedil;",0 BEgrave dc.b "Egrave;",0 BEacute dc.b "Eacute;",0 BEcirc dc.b "Ecirc;",0 BEuml dc.b "Euml;",0 BIgrave dc.b "Igrave;",0 BIacute dc.b "Iacute;",0 BIcirc dc.b "Icirc;",0 BIuml dc.b "Iuml;",0 BETH dc.b "ETH;",0 BNtilde dc.b "Ntilde;",0 BOgrave dc.b "Ograve;",0 BOacute dc.b "Oacute;",0 BOcirc dc.b "Ocirc;",0 BOtilde dc.b "Otilde;",0 BOuml dc.b "Ouml;",0 BOslash dc.b "Oslash;",0 BUgrave dc.b "Ugrave;",0 BUacute dc.b "Uacute;",0 BUcirc dc.b "Ucirc;",0 BUuml dc.b "Uuml;",0 BYacute dc.b "Yacute;",0 BTHORN dc.b "THORN;",0 szlig dc.b "szlig;",0 agrave dc.b "agrave;",0 aacute dc.b "aacute;",0 acirc dc.b "acirc;",0 atilde dc.b "atilde;",0 auml dc.b "auml;",0 aring dc.b "aring;",0 aelig dc.b "aelig;",0 ccedil dc.b "ccedil;",0 egrave dc.b "egrave;",0 eacute dc.b "eacute;",0 ecirc dc.b "ecirc;",0 euml dc.b "euml;",0 igrave dc.b "igrave;",0 iacute dc.b "iacute;",0 icirc dc.b "icirc;",0 iuml dc.b "iuml;",0 eth dc.b "eth;",0 ntilde dc.b "ntilde;",0 ograve dc.b "ograve;",0 oacute dc.b "oacute;",0 ocirc dc.b "ocirc;",0 otilde dc.b "otilde;",0 ouml dc.b "ouml;",0 oslash dc.b "oslash;",0 ugrave dc.b "ugrave;",0 uacute dc.b "uacute;",0 ucirc dc.b "ucirc;",0 uuml dc.b "uuml;",0 yacute dc.b "yacute;",0 thorn dc.b "thorn;",0 yuml dc.b "yuml;",0 ;special entity tags: nbsp dc.b "nbsp;",0 gt dc.b "gt;",0 lt dc.b "lt;",0 quot dc.b "quot;",0 copy dc.b "copy;",0 reg dc.b "reg;",0 apos dc.b "apos;",0 ast dc.b "ast;",0 brvbar dc.b "brvbar;",0 cent dc.b "cent;",0 colon dc.b "colon;",0 comma dc.b "comma;",0 commat dc.b "commat;",0 deg dc.b "deg;",0 dollar dc.b "dollar",0 emsp dc.b "emsp;",0 ensp dc.b "ensp;",0 equals dc.b "equals;",0 excl dc.b "excl;",0 half dc.b "half;",0 hyphen dc.b "hyphen;",0 iexcl dc.b "iexcl;",0 iquest dc.b "iquest;",0 laquo dc.b "laquo;",0 lpar dc.b "lpar;",0 lsqb dc.b "lsqb;",0 mdash dc.b "mdash;",0 micro dc.b "micro;",0 middot dc.b "middot;",0 ndash dc.b "ndash;",0 not dc.b "not;",0 para dc.b "para;",0 percnt dc.b "percnt;",0 period dc.b "period;",0 plus dc.b "plus;",0 plusmn dc.b "plusmn;",0 pound dc.b "pound;",0 quest dc.b "quest;",0 raquo dc.b "raquo;",0 rpar dc.b "rpar;",0 rsqb dc.b "rsqb;",0 sect dc.b "sect;",0 semi dc.b "semi;",0 shy dc.b "shy;",0 tilde dc.b "tilde;",0 trade dc.b "trade;",0 yen dc.b "yen;",0 verbar dc.b "verbar;",0 amp dc.b "amp;",0 frac12 dc.b "frac12;",0 frac14 dc.b "frac14;",0 frac34 dc.b "frac34;",0 frac18 dc.b "frac18;",0 ;these can't be supported since Amiga frac38 dc.b "frac38;",0 ;(ISO) don't have these special signs frac58 dc.b "frac58;",0 ;(AFAIK). frac78 dc.b "frac78;",0 ;---- sup1 dc.b "sup1;",0 sup2 dc.b "sup2;",0 sup3 dc.b "sup3;",0 ; Entities this program don't support: ; ; <, > (without ";" at the end) ; ™ (trademark (TM)) -> using ® instead... Warn dc.b 0 AboutTxt dc.b 10,"DetagHTML version 1.3 - by Kenneth C. Nilsen.",10 dcb.b 50,"-" dc.b 10,"This program is in the PUBLIC DOMAIN",10,10 dc.b "DetagHTML will strip textfiles for HTML tags",10 dc.b "and convert entities to ISO chars.",10,10 dc.b "For bugreports, suggestions etc. e-mail me at:",10 dc.b "Kenneth C. Nilsen (kennecni@idgonline.no).",10,10 dc.b " USAGE: DetagHTML ",10,10 dc.b "The saved file will be extended with '.txt'.",10,10,0 KeyWord dc.b "HTML>" Extension dc.b ".txt",0 ErrorFile dc.b "Couldn't open file!",10,0 ErrorDos dc.b "Couldn't allocate dosobject!",10,0 ErrorExamine dc.b "Couldn't examine file!",10,0 ErrorSize dc.b "File is null size file!",10,0 ErrorMem dc.b "Out of memory! Couldn't load file into memory!",10,0 ErrorHTML dc.b "Couldn't find a tag in buffer! Terminating..",10,0 ErrorWrite dc.b "Stripped file is null bytes! Terminating..",10,0 ErrorSave dc.b "Couldn't open output file!",10,0 ErrorWrite2 dc.b "WARNING: File saved may be corrupt!",10,0 Pass1 dc.b 10,"DetagHTML by Kenneth C. Nilsen",10,10 dc.b "Pass 1.. (stripping tags)",10 Pass1L =*-Pass1 Pass2 dc.b "Pass 2.. (converting entities)",10 Pass2L =*-Pass2 Done dc.b "Done!",10,10 Header dc.b "Message stripped with DetagHTML 1.3 by Kenneth C. Nilsen",10,10 HeaderL =*-Header ErrFile dc.b "DetagHTML: Couldn't find any tag in message! Terminating..",10,0 ErrFileL =*-ErrFile FileName dcb.b 200,0 *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»*