*>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   (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
*»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»*