home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / orx8.zip / sgmlentity_util.cmd < prev    next >
OS/2 REXX Batch file  |  1997-07-21  |  14KB  |  335 lines

  1. /*
  2.    Module to allow translation from characters to SGML-entities and vice-versa,
  3.    used e.g. in HTML
  4.  
  5. program:   sgml_entities.cmd
  6. type:      Object REXX, REXXSAA 6.0
  7. purpose:   implements functions and classes for x-lating chars <--> SGML-entities (HTML)
  8. version:   1.0
  9. date:      1997-04-15
  10.  
  11. author:    Rony G. Flatscher
  12.            Rony.Flatscher@wu-wien.ac.at
  13.            (Wirtschaftsuniversitaet Wien, University of Economics and Business
  14.            Administration, Vienna/Austria/Europe)
  15.  
  16. needs:     NLS_UTIL.CMD
  17.  
  18. usage:     call or require this module, which will set up tables for translating
  19.            characters according to a code-page to the appropriate SGML-entities as
  20.            they are used in HTML-files (being based on SGML); thereafter the following
  21.            two routines are available:
  22.  
  23.              CPString2SGMLEntity( string [, [CodePage] [, "Reverse" ] ] )
  24.                 ... returns a string in which characters are translated according
  25.                     to the given codepage (defaults to NLS_UTIL' default codepage);
  26.                     if the third argument "R" is given then translation occurs from
  27.                     SGML-entities to the appropriate characters according to the given
  28.                     codepage
  29.  
  30.              CPFile2SGMLEntity( filename [, [CodePage] [, "Reverse" ] ] )
  31.                 ... works on the contents of the file denoted by "filename"; for
  32.                     its work it uses CPString2SGMLEntity(), hence the second and
  33.                     third argument are the same as above
  34.  
  35.  
  36. comments:  prepared for the "8th International Rexx Symposium 1997", April 1997, Heidelberg/Germany
  37.  
  38.  
  39. All rights reserved and copyrighted 1997 by the author,
  40. no guarantee that it works without errors, etc. etc.
  41.  
  42. You are granted the right to use this module under the condition that you don't charge money for this module (as you didn't write
  43. it in the first place) or modules directly derived from this module, that you document the original author (to give appropriate
  44. credit) with the original name of the module and that you make the unaltered, original source-code of this module available on
  45. demand.  If that holds, you may even bundle this module (either in source or compiled form) with commercial software.
  46.  
  47. If you find an error, please send me the description (preferably a *very* short example);
  48. I'll try to fix it and re-release it to the net.
  49.  
  50. !!!!!!
  51. If you extend the definitions with the codepage of *your* country, *please* send me those
  52. definitions and I will extend this module and re-release it to the net.
  53. !!!!!!
  54. */
  55.  
  56.  
  57.  
  58. /* initialize, setup CP 850 (Western Europe) and 437 (US)       */
  59. /* Codepage 850 (Europe) */
  60. cp850tab = .table ~ new                            /* create a table */
  61.  
  62. /*       VALUE sgml-entity: |  INDEX in form of the appr. CP-character     */
  63. cp850tab ~ PUT( "Ç"  ,  D2C( 128 ) )
  64. cp850tab ~ PUT( "ü"    ,  D2C( 129 ) )     /* e.g. German umlaut-"u"       */
  65. cp850tab ~ PUT( "é"  ,  D2C( 130 ) )
  66. cp850tab ~ PUT( "â"   ,  D2C( 131 ) )
  67. cp850tab ~ PUT( "ä"    ,  D2C( 132 ) )
  68. cp850tab ~ PUT( "à"  ,  D2C( 133 ) )     /* e.g. french "a" with accent grave */
  69. cp850tab ~ PUT( "å"   ,  D2C( 134 ) )
  70. cp850tab ~ PUT( "ç"  ,  D2C( 135 ) )
  71. cp850tab ~ PUT( "ê"   ,  D2C( 136 ) )
  72. cp850tab ~ PUT( "ë"    ,  D2C( 137 ) )
  73. cp850tab ~ PUT( "è"  ,  D2C( 138 ) )
  74. cp850tab ~ PUT( "ï"    ,  D2C( 139 ) )
  75. cp850tab ~ PUT( "î"   ,  D2C( 140 ) )
  76. cp850tab ~ PUT( "ì"  ,  D2C( 141 ) )
  77. cp850tab ~ PUT( "Ä"    ,  D2C( 142 ) )
  78. cp850tab ~ PUT( "Å"   ,  D2C( 143 ) )     /* e.g. nordic "A" with a ring on top */
  79. cp850tab ~ PUT( "É"  ,  D2C( 144 ) )
  80. cp850tab ~ PUT( "æ"   ,  D2C( 145 ) )
  81. cp850tab ~ PUT( "Æ"   ,  D2C( 146 ) )
  82. cp850tab ~ PUT( "ô"   ,  D2C( 147 ) )
  83. cp850tab ~ PUT( "ö"    ,  D2C( 148 ) )
  84. cp850tab ~ PUT( "ò"  ,  D2C( 149 ) )
  85. cp850tab ~ PUT( "û"   ,  D2C( 150 ) )
  86. cp850tab ~ PUT( "ù"  ,  D2C( 151 ) )
  87. cp850tab ~ PUT( "ÿ"    ,  D2C( 152 ) )
  88. cp850tab ~ PUT( "Ö"    ,  D2C( 153 ) )
  89. cp850tab ~ PUT( "Ü"    ,  D2C( 154 ) )
  90. cp850tab ~ PUT( "ø"  ,  D2C( 155 ) )
  91. cp850tab ~ PUT( "£"   ,  D2C( 156 ) )
  92. cp850tab ~ PUT( "Ø"  ,  D2C( 157 ) )
  93. cp850tab ~ PUT( "×"   ,  D2C( 158 ) )
  94. cp850tab ~ PUT( "á"  ,  D2C( 160 ) )
  95. cp850tab ~ PUT( "í"  ,  D2C( 161 ) )
  96. cp850tab ~ PUT( "ó"  ,  D2C( 162 ) )
  97. cp850tab ~ PUT( "ú"  ,  D2C( 163 ) )
  98. cp850tab ~ PUT( "ñ"  ,  D2C( 164 ) )
  99. cp850tab ~ PUT( "Ñ"  ,  D2C( 165 ) )
  100. cp850tab ~ PUT( "ª"    ,  D2C( 166 ) )
  101. cp850tab ~ PUT( "º"    ,  D2C( 167 ) )
  102. cp850tab ~ PUT( "¿"  ,  D2C( 168 ) )
  103. cp850tab ~ PUT( "®"     ,  D2C( 169 ) )
  104. cp850tab ~ PUT( "¬"     ,  D2C( 170 ) )
  105. cp850tab ~ PUT( "½"  ,  D2C( 171 ) )
  106. cp850tab ~ PUT( "¼"  ,  D2C( 172 ) )
  107. cp850tab ~ PUT( "¡"   ,  D2C( 173 ) )
  108. cp850tab ~ PUT( "«"   ,  D2C( 174 ) )
  109. cp850tab ~ PUT( "»"   ,  D2C( 175 ) )
  110. cp850tab ~ PUT( "Á"  ,  D2C( 181 ) )
  111. cp850tab ~ PUT( "Â"   ,  D2C( 182 ) )
  112. cp850tab ~ PUT( "À"  ,  D2C( 183 ) )
  113. cp850tab ~ PUT( "©"    ,  D2C( 184 ) )
  114. cp850tab ~ PUT( "¢"    ,  D2C( 189 ) )
  115. cp850tab ~ PUT( "¥"     ,  D2C( 190 ) )
  116. cp850tab ~ PUT( "ã"  ,  D2C( 198 ) )
  117. cp850tab ~ PUT( "Ã"  ,  D2C( 199 ) )
  118. cp850tab ~ PUT( "¤"  ,  D2C( 207 ) )
  119. cp850tab ~ PUT( "ð"     ,  D2C( 208 ) )
  120. cp850tab ~ PUT( "Ð"     ,  D2C( 209 ) )
  121. cp850tab ~ PUT( "Ê"   ,  D2C( 210 ) )
  122. cp850tab ~ PUT( "Ë"    ,  D2C( 211 ) )
  123. cp850tab ~ PUT( "È"  ,  D2C( 212 ) )
  124. cp850tab ~ PUT( "Í"  ,  D2C( 214 ) )
  125. cp850tab ~ PUT( "Î"   ,  D2C( 215 ) )
  126. cp850tab ~ PUT( "Ï"    ,  D2C( 216 ) )
  127. cp850tab ~ PUT( "&brkbar;"  ,  D2C( 221 ) )
  128. cp850tab ~ PUT( "Ì"  ,  D2C( 222 ) )
  129. cp850tab ~ PUT( "Ó"  ,  D2C( 224 ) )
  130. cp850tab ~ PUT( "ß"   ,  D2C( 225 ) )
  131. cp850tab ~ PUT( "Ô"   ,  D2C( 226 ) )
  132. cp850tab ~ PUT( "Ò"  ,  D2C( 227 ) )
  133. cp850tab ~ PUT( "õ"  ,  D2C( 228 ) )
  134. cp850tab ~ PUT( "Õ"  ,  D2C( 229 ) )
  135. cp850tab ~ PUT( "µ"   ,  D2C( 230 ) )
  136. cp850tab ~ PUT( "Þ"   ,  D2C( 231 ) )
  137. cp850tab ~ PUT( "þ"   ,  D2C( 232 ) )
  138. cp850tab ~ PUT( "Ú"  ,  D2C( 233 ) )
  139. cp850tab ~ PUT( "Û"   ,  D2C( 234 ) )
  140. cp850tab ~ PUT( "Ù"  ,  D2C( 235 ) )
  141. cp850tab ~ PUT( "ý"  ,  D2C( 236 ) )
  142. cp850tab ~ PUT( "Ý"  ,  D2C( 237 ) )
  143. cp850tab ~ PUT( "&hibar;"   ,  D2C( 238 ) )
  144. cp850tab ~ PUT( "´"   ,  D2C( 239 ) )
  145. cp850tab ~ PUT( "±"  ,  D2C( 241 ) )
  146. cp850tab ~ PUT( "¾"  ,  D2C( 243 ) )
  147. cp850tab ~ PUT( "¶"    ,  D2C( 244 ) )
  148. cp850tab ~ PUT( "§"    ,  D2C( 245 ) )
  149. cp850tab ~ PUT( "÷"  ,  D2C( 246 ) )
  150. cp850tab ~ PUT( "¸"   ,  D2C( 247 ) )
  151. cp850tab ~ PUT( "°"     ,  D2C( 248 ) )
  152. cp850tab ~ PUT( "¨"     ,  D2C( 249 ) )
  153. cp850tab ~ PUT( "·"  ,  D2C( 250 ) )
  154. cp850tab ~ PUT( "¹"    ,  D2C( 251 ) )
  155. cp850tab ~ PUT( "³"    ,  D2C( 252 ) )
  156. cp850tab ~ PUT( "²"    ,  D2C( 253 ) )
  157. .SGMLEntity ~ setentry( 850, cp850tab ) /* add codepage table to directory */
  158.  
  159.  
  160.  
  161.  
  162. /* Codepage 437 (US) , almost the same as 850, except ... */
  163.  
  164. cp437tab = cp850tab ~ copy      /* make a copy of cp850tab */
  165.  
  166. /* the following entries differ from 850, replace them: */
  167.  
  168. cp437tab ~ PUT( "¢"    ,  D2C( 155 ) )
  169. cp437tab ~ PUT( "¥"     ,  D2C( 157 ) )
  170.  
  171. /* remove entries in code page "437" which do not have a corresponding SGML-entity,
  172.    i.e. leave them verbatim in the text */
  173.  
  174. cp437tab ~ REMOVE( D2C( 158 )  )
  175. cp437tab ~ REMOVE( D2C( 169 )  )
  176. cp437tab ~ REMOVE( D2C( 181 )  )
  177. cp437tab ~ REMOVE( D2C( 182 )  )
  178. cp437tab ~ REMOVE( D2C( 183 )  )
  179. cp437tab ~ REMOVE( D2C( 184 )  )
  180. cp437tab ~ REMOVE( D2C( 189 )  )
  181. cp437tab ~ REMOVE( D2C( 190 )  )
  182. cp437tab ~ REMOVE( D2C( 198 )  )
  183. cp437tab ~ REMOVE( D2C( 199 )  )
  184. cp437tab ~ REMOVE( D2C( 208 )  )
  185. cp437tab ~ REMOVE( D2C( 209 )  )
  186. cp437tab ~ REMOVE( D2C( 210 )  )
  187. cp437tab ~ REMOVE( D2C( 211 )  )
  188. cp437tab ~ REMOVE( D2C( 212 )  )
  189. cp437tab ~ REMOVE( D2C( 214 )  )
  190. cp437tab ~ REMOVE( D2C( 215 )  )
  191. cp437tab ~ REMOVE( D2C( 216 )  )
  192. cp437tab ~ REMOVE( D2C( 221 )  )
  193. cp437tab ~ REMOVE( D2C( 222 )  )
  194. cp437tab ~ REMOVE( D2C( 224 )  )
  195. cp437tab ~ REMOVE( D2C( 225 )  )
  196. cp437tab ~ REMOVE( D2C( 226 )  )
  197. cp437tab ~ REMOVE( D2C( 227 )  )
  198. cp437tab ~ REMOVE( D2C( 228 )  )
  199. cp437tab ~ REMOVE( D2C( 229 )  )
  200. cp437tab ~ REMOVE( D2C( 231 )  )
  201. cp437tab ~ REMOVE( D2C( 232 )  )
  202. cp437tab ~ REMOVE( D2C( 233 )  )
  203. cp437tab ~ REMOVE( D2C( 234 )  )
  204. cp437tab ~ REMOVE( D2C( 235 )  )
  205. cp437tab ~ REMOVE( D2C( 236 )  )
  206. cp437tab ~ REMOVE( D2C( 237 )  )
  207. cp437tab ~ REMOVE( D2C( 238 )  )
  208. cp437tab ~ REMOVE( D2C( 239 )  )
  209. cp437tab ~ REMOVE( D2C( 243 )  )
  210. cp437tab ~ REMOVE( D2C( 244 )  )
  211. cp437tab ~ REMOVE( D2C( 245 )  )
  212. cp437tab ~ REMOVE( D2C( 247 )  )
  213. cp437tab ~ REMOVE( D2C( 249 )  )
  214. cp437tab ~ REMOVE( D2C( 251 )  )
  215. cp437tab ~ REMOVE( D2C( 252 )  )
  216. .SGMLEntity ~ setentry( 437, cp437tab ) /* add codepage table to directory */
  217.  
  218.  
  219.  
  220. /* define default SGMLEntity-table, if codepage is 0 */
  221.  
  222. processCodePage = SysQueryProcessCodePage()     /* get code page of current process     */
  223.  
  224. IF .SGMLEntity ~ hasentry( processCodePage ) THEN       /* use process' CP as default CP*/
  225.    .SGMLEntity ~ setentry( 0, .SGMLEntity ~ entry( processCodePage) )
  226. ELSE                                                    /* not found                    */
  227.    .SGMLEntity ~ setentry( 0, cp850tab )                /* default to code page 850     */
  228.  
  229.  
  230.  
  231.  
  232. :: REQUIRES nls_util.cmd        /* load national language support */
  233.  
  234. /* ---------------------------------------------------------------------------
  235. CPFile2SGMLEntity( filename [, [CodePage] [, "Reverse" ] ] )
  236. CPString2SGMLEntity( string [, [CodePage] [, "Reverse" ] ] )
  237.  
  238.         e.g. ( "höher", "850", "Reverse" ) ... change string back, if possible
  239.              SGML2Entity( "d:\aha.html", "850",, "File" )  ... change a file
  240.  
  241. --------------------------------------------------------------------------- */
  242. /* work on a file                       */
  243. :: ROUTINE CPFile2SGMLEntity    PUBLIC
  244.    USE ARG filename, CodePage, Reverse
  245.  
  246.    IF \ VAR( "CodePage" ) THEN CodePage = get_nls_default_object() ~ codepage
  247.    IF \ VAR( "Reverse" )  THEN Reverse  = ""
  248.  
  249.    /* read file into one variable, to treat it as a large string */
  250.    stream = .stream ~ new( filename ) ~~ open       /* open for reading and writing */
  251.    FileString = stream ~ charin( 1, stream ~ query( "Size" ) )
  252.    stream ~ close
  253.    FileString = CPString2SGMLEntity( FileString, CodePage, Reverse )
  254.    stream ~~  open( "WRITE REPLACE" )           /* truncate file                */
  255.    stream ~ charout( FileString, 1 )            /* write string back to file    */
  256.    stream ~ close
  257.    DROP FileString
  258.  
  259.  
  260.  
  261.  
  262. /* work on a string                     */
  263. :: ROUTINE CPString2SGMLEntity  PUBLIC
  264.    USE ARG string, CodePage, Reverse
  265.  
  266.    IF \ VAR( "CodePage" ) THEN CodePage = get_nls_default_object() ~ codepage
  267.    IF \ VAR( "Reverse" )  THEN Reverse  = ""
  268.  
  269.                                 /* does given CP exist, if not use default CP   */
  270.    cpTable = .SGMLEntity ~ entry( codepage )    /* try to retrieve CP-2-SGMLentity table  */
  271.    IF cpTable = .nil THEN       /* SGMLentity-table for codepage not found, raise error */
  272.    DO
  273.       SIGNAL ON SYNTAX
  274.       RAISE SYNTAX 40.904 ARRAY ( "CPString2SGMLEntity()", '2 ("CodePage")',,
  275.                                   "supported SGMLEntity codepages", codepage )
  276.    END
  277.                                 /* call proc according to third argument        */
  278.    IF ( TRANSLATE( LEFT( Reverse, 1 ) ) = "R" ) THEN
  279.       RETURN sgml2chars( string )       /* reverse      */
  280.    ELSE
  281.       RETURN chars2sgml( string )
  282.  
  283. /* --------------- procedure ----------------- */
  284. CHARS2SGML :
  285.    tmpSupp = cpTable ~ supplier /* get a supplier from table */
  286.    DO WHILE tmpSupp ~ available
  287.       string = CHANGESTR( tmpSupp ~ index, string, tmpSupp ~ item )         /* translate chars to HTML/SGML entities */
  288.       tmpSupp ~ next
  289.    END
  290.    RETURN string
  291.  
  292.  
  293. /* --------------- procedure ----------------- */
  294. SGML2CHARS :
  295.    tmpSupp = cpTable ~ supplier /* get a supplier from table */
  296.    DO WHILE tmpSupp ~ available
  297.       string = CHANGESTR( tmpSupp ~ item, string, tmpSupp ~ index )     /* translate chars to HTML/SGML entities */
  298.       tmpSupp ~ next
  299.    END
  300.    RETURN string
  301.  
  302.  
  303. SYNTAX : RAISE PROPAGATE        /* raise error in caller        */
  304.  
  305.  
  306.  
  307.  
  308. /* ========================================================================= */
  309.  
  310. /* this class keeps known codepages <---> HTML translation tables at the class level,
  311.    if the class is asked e.g. for codepages 850 or 437, then the table describing them will be
  312.    returned;
  313.  
  314.    one can add any other table by adding (setentry), replacing (setentry) or removing (setentry)
  315.    it at the class level ...
  316.    (the UNKNOWN class method will forward it to the class object directory-variable )
  317.  
  318. */
  319.  
  320. :: CLASS SGMLEntity           /* PUBLIC */
  321.  
  322. :: METHOD init CLASS
  323.    EXPOSE cpDirectory
  324.  
  325.    cpDirectory = .directory ~ new       /* directory to contain codepages */
  326.  
  327.  
  328.  
  329. :: METHOD unknown       CLASS           /* forward messages to .directory */
  330.    EXPOSE cpDirectory
  331.    USE ARG mess_name, mess_args
  332.  
  333.    FORWARD MESSAGE (mess_name) ARGUMENTS (mess_args) TO ( cpDirectory )
  334.  
  335.