Glenn BarnasGlenn Barnas KiX Supporter
Registered: 2003-01-28
Posts: 4395
Loc: New Jersey
WARNING - the PostPrep.zip attached to this post does not work with Kix32 version 4.63. An update is being tested and will be uploaded when validated.
For those of you that don't know - PostPrep is the Kix script that colorizes kix code, generating HTML that can be pasted directly into a message as you see below, without using Code tags. You must select HTML or HTML/UBB as the message type when posting a message with PostPrep content.
This postprep release runs from a command line -
Kix32 ppcl.kix -s:myscript.kix -c
The postprepped code is placed on the clipboard, ready to paste into a KORG message. The default (without -c) writes a .HTM file with the same name as the source file. Run without args for usage info.
The PostPrep.INI file will be posted in the next message. The script expects this file to be in the path defined by %S_CONFIG%, or - if not there - in @SCRIPTDIR.
This version is quick & easy to use, and is capable of postprepping an entire folder of Kix files automatically. The zip file contains both the GUI and command-line versions of PostPrep, and both share a common configuration file.
Due to the size of this post, it is presented in 3 parts. Parts 1 & 2 are the core script, part 3 is the config file. The code presented here is primarily to illustrate the concept and code structure. You are strongly encouraged to download the entire code set - PostPrep.kxw, PostPrep.ini, PPCL.Kix, and the ReadMe.txt file from the attached zip file. Only the zip file will be updated as versions change!!
Registered: 2002-05-13
Posts: 309
Loc: STRASBOURG, France
What a nice job !!!
but i had some little problems when I copied and pasted to my text editor (same result if I save as in .txt format). Applying ppc.kix to itself gives a wrong result.
1) the following comment line has been broken in two lines !!! ; If the destination file wasn't specified, use the SourceFileSpec and change the extension to ".htm"
2) in "; Set the Border directive based on the flag value", the comment line has been broken in two lines. The second line begins with an extra comma and kixtart considers the begins of the second line has an unknown command.
3) in "; Define the body settings", the correct line should be $Body = '<font face="' instead of $Body = '$I = ReadProfileString($ConfigFile, 'FieldSet', 'TypeFace')
this is because of the < character
4) same as 1) in the enumini function with return nothing. this function always returned an empty array !!!
5) at the end of Kix2HTML function, the $OutBuffer line has been broken and there is an extra comma : $OutBuffer = $OutBuffer + Join(Split(Join(Split(Join(Split(Join($SrcTxt,@CRLF),$1),'&'),,$2),$Lc),$3),$Tc)
Correct line should be : $OutBuffer = $OutBuffer + Join(Split(Join(Split(Join(Split(Join($SrcTxt,@CRLF),$1),'&'),$2),$Lc),$3),$Tc)
With theses changes, I have a result but if I apply the new version of ppc to itself, the result is still wrong. Point 3 should be solved by replacing < character by a variable. Point 1, 2, 3 ou 4 seem to come from the same reason.
Registered: 2002-05-13
Posts: 309
Loc: STRASBOURG, France
Hi,
the problem is the following lines :
Code:
If $Cp > 85 And InStr(Chr(9) + Chr(32) + ',+-/*', $C)
$Line = $Indent + SubStr($Line, $Cp) ; reset the line
$Ll = Len($Line)
$Cp = 0 ; and the pointer
$OBuf = $OBuf + @CRLF ; break the line here
EndIf
if I comment theses lines, the result is correct. may be it is not a good thing to break a line after the 85th column !!!
first, if the line is commented (or end of line), new line should be commented. second, when the line is broken, the last character is repeated at the beginning of the new line. Example :
Glenn BarnasGlenn Barnas KiX Supporter
Registered: 2003-01-28
Posts: 4395
Loc: New Jersey
Christope
Thanks for the feedback!!
I've updated the post, and changed how the long-line wrapping is done. It now works by checking after most characters are added to the output buffer, which fixes the clipped character. The wrap-check function evaluates the original line to determine the indent, and returns the number of chars to indent (+2) if wrapping is needed. The wrap position is now defined in the PostPrep.ini file - the WordWrap was changed from a boolean to a numeric value, indicating at/after which column wrapping should be considered.
I also removed the funky "$Lc + 'font..." type definitions by replacing the "<" and ">" chars with their HTML string equivelents.
Give the new version a go and let me know if you find any more issues.
One caveat with line wrapping - it wraps on space, tab, and these characters: ",+-/*". Since "-" is also a dash/heyphen, I'm thinking about removing that as a breakable character.
Also - when strings are broken, the resulting code may insert a CRLF in the output. The code would be more complex, but creating a "diversion" to hold the string text (with quotes" and breaking before and/or after might be better. Maybe the next release.
For now, the user should be aware that text strings may need to be "repaired" back to single lines. I'm also reviewing the HTML guide - maybe the answer is to insert HTML "soft" spaces?
Glenn
_________________________ Actually I am a Rocket Scientist!
Also - when strings are broken, the resulting code may insert a CRLF in the output. The code would be more complex, but creating a "diversion" to hold the string text (with quotes" and breaking before and/or after might be better. Maybe the next release.
If quoted strings are broken, they should just need to have a closing quote, a concatenation +, and an opening quote on the newline to prevent a multiline embedding.
Easier said than done. :p
_________________________
Give a man a fish and he will be back for more. Slap him with a fish and he will go away forever.
Glenn BarnasGlenn Barnas KiX Supporter
Registered: 2003-01-28
Posts: 4395
Loc: New Jersey
OK - that's actually very easy to accomplish - same logic as handling comments. My biggest concern is - just how much modification of the original code is "OK" for the sake of wrapping long lines?
Glenn
_________________________ Actually I am a Rocket Scientist!
Registered: 2002-05-13
Posts: 309
Loc: STRASBOURG, France
Hi,
one of the last change is worst than the original version. you replace $Lc+' by '< and '+$Tc by >'. This is not a good idea because all strings that look like HTML tag now disappear !!!
other changes seem OK.
one suggestion : i know at least 3 special characters in HTML : <>& at the beginning of Kix2HTM, special char are replaced with chr(1), chr(2), chr(3) at the end of Kix2HTM, why not replace these characters with special HTML tag. I have tried to replace
Glenn BarnasGlenn Barnas KiX Supporter
Registered: 2003-01-28
Posts: 4395
Loc: New Jersey
The whole point is to allow and translate htm code. The problem was that I translated the < and > chars, but did not handle the & - this caused the < and > to be interpredted by the BBS, displaying the line as you saw it, even though that's not what the code was.
I did a compare of the .GEN file and the .HTM file and it reports that the two files are identical except for blanks. This is understandable as Kix2Htm adds a space character to every blank line to preserve formatting.
I think we're good now. (although.. I did just realize I need to add a code block to handle Block Comments.)
Glenn
_________________________ Actually I am a Rocket Scientist!
Glenn BarnasGlenn Barnas KiX Supporter
Registered: 2003-01-28
Posts: 4395
Loc: New Jersey
Updates to the Kix2Htm UDF, as follows: In Kix2Htm() Added support for Block Comments
In WC() If Not $_WF was changed to: If $_Wf = 0
This was done to allow the use of 0 (zero) to disable line wrapping via the WordWrap value in PostPrep.ini. The alternative was to use a very large number, such as 9999, which isn't intuitive.
Also updated the PostPrep.ini file with new function references.
Attached a ZIP file with the complete code and INI file.
Glenn
_________________________ Actually I am a Rocket Scientist!
Glenn BarnasGlenn Barnas KiX Supporter
Registered: 2003-01-28
Posts: 4395
Loc: New Jersey
Updates!
Version is now 2.1.0.0 for both GUI and C/L versions
GUI and C/L versions share a common code base.
New zip file attached to first post - PostPrep.zip - replaces PPCL.ZIP.
ZIP file now contains both the GUI and command-line versions, and both share a common configuration file.
The command-line version now supports a -W switch, which is designed to generate .HTM files from an entire folder of .KIX, .UDF, or .KXF files. This is how I publish my UDF library on my web site, automatically updated every night.
The GUI utilizes separate tabbed windows to display script source, HTML, and colorized preview. Launching IE is no longer required to preview the PostPrepped code.
Kix2HTM UDF has been updated (minor) to insert a Global var called $NOTICE, which adds a comment to the HTML indicating the method and version of PostPrep that was used. This will aid in identifying version-specific issues.
Glenn
_________________________ Actually I am a Rocket Scientist!
Glenn BarnasGlenn Barnas KiX Supporter
Registered: 2003-01-28
Posts: 4395
Loc: New Jersey
Minor modification based on UBB post testing. Both versions will display a warning if the generated HTML is larger than 65500 characters - 64K or the current UBB post size limit. It will not affect generation of the HTML, it will only display a warning.
Updated the ZIP file in post #1.
Glenn
_________________________ Actually I am a Rocket Scientist!
now as the ubb code has been cracked to comply with long line police rules, you should edit the postprep to support it as well. so, in the code's pre-field <pre> add the class: <pre class="ubbcode-body">
I just have to say Glenn, you have so many comments in the kix2htm that I can't see any of my handywork in there anymore... not even able to tell if there is any left. makes me sad :P
Glenn BarnasGlenn Barnas KiX Supporter
Registered: 2003-01-28
Posts: 4395
Loc: New Jersey
Jooel,
It does say "Rewrite of original postprep code by Jochen Polster & Jooel Nieminen", which implies that it was rewritten from scratch based on your original code. If I recall (almost 5 years ago..), this was some of the code that gave rise to the term "Lonkenized"! I rewrote it because it was hard to maintain in your "tight" style and you had become busy with some other project.
I do have the entire dev tree including versions 1.0, 1.0.3.4, and 1.3 that led to the 2.0 release if you're feeling nostalgic.
G-
_________________________ Actually I am a Rocket Scientist!
not that much. I was actually thinking about finally incorporating it to the forums as integral part so the postsize limit wouldn't be an issue no more.
something like this... I just add [postprep] tag inside code-tags and it will be prepped on the fly:
Code:
[postprep]
;; KixGenerated: 2007/10/13 21:46:19
; UBB PostPrep 2.0.0
; ----------------------------------------------------------------------------------------------
; MINIMUM REQUIREMENTS
;
; KIXTART 4.53 (KiX32.exe)
; ----------------------------------------------------------------------------------------------
; AUTHORs
; Glenn Barnas - This development tree
; ----------------------------------------------------------------------------------------------
; ACKNOWLEDGEMENTS
; Jochen Polster - Form, Controls, original design
; Jooel Nieminen - original conversion Engine !
; ----------------------------------------------------------------------------------------------
; VERSION HISTORY
;
; 2.0.0.0 - 12/30/2006 Glenn Barnas - New development tree based on PostPrep 1.0.3.4
; requires Kix 4.53
; COMMAND-LINE version, HTML only (no UBB output)
; 2.0.0.1 - 03/24/2007 Changes to Kix2Htm UDF
; 2.0.2.0 - 10/15/2007 Change to WC function to allow WORDWRAP=0 setting
; Added support to Kix2Htm() to support Block Comments
; ----------------------------------------------------------------------------------------------
Break On
Dim $ShowStats ; Display conversion time stats if true
Dim $Version ; Current version string
Dim $ ; general purpose "throwaway" var
Dim $ConfigFile ; Filespec for PPCL configuration file
Dim $SourceFile ; Source file to process
Dim $DestFile ; Output file
Dim $FileContent ; Content of file as a single string
Dim $CommandLine ; Command Line Args
Dim $I ; Index pointer
Dim $Clip ; Boolean - copy generated output to clipboard if true
Dim $Wrap ; Boolean - wrap long lines when true
Dim $Commands ; Array of Commands
Dim $Functions ; Array of Functions
Dim $Border ; Border / background specification
Dim $TimerS ; Start time of conversion
Dim $TimerE ; End time of conversino
Dim $Body ; Body text specifier
Dim $Sections[7] ; Types of formatting
Dim $ColorTable[7] ; Table of format colors for various types
Dim $BoldTable[7] ; Table of format bolding for various types
$Sections = 'Comments','Strings','Numbers','Commands','Functions','Macros','Operators','Variables'
$ = SetAscii('On')
$ = SetOption('Explicit', 'On')
$ = SetOption('WrapAtEOL', 'On')
$ = SetOption('NoVarsInStrings', 'On')
$ = SetOption('NoMacrosInStrings', 'On')
$Version = '2.0'
; Exit if not at KiX V4.53
$ = KixVer('4.53')
; initialization
$ConfigFile = ''
$SourceFile = ''
$DestFile = ''
; check for a Config file in the standard system configuration folder
If Exist(%S_CONFIG% + '\PostPrep.ini')
$ConfigFile = %S_CONFIG% + '\PostPrep.ini'
EndIF
; If we didn't find it in the standard location, look in the folder where the script was launched
If Exist(@SCRIPTDIR + '\PostPrep.ini') And Not $ConfigFile
$ConfigFile = @SCRIPTDIR + '\PostPrep.ini'
EndIf
; Parse the command line
$CommandLine = GetCommandLine(1)
; Complain and exit if no arguments were specified.
If UBound($CommandLine) = 1
'No input arguments were specified.' ?
' Usage: ppcl -s:SrcFileSpec [-o:DestFileSpec] [-p:AltConfigFile] [-c]' ?
' -c copies the resulting HTM output to the clipboard INSTEAD OF' ?
' generating the .HTM file.' ?
Quit 1
EndIF
; Have arguments - figure out what to do
For $I = 2 to UBound($CommandLine)
Select
Case Left($CommandLine[$I], 3) = '-s:'
$SourceFile = SubStr($CommandLine[$I], 4)
Case Left($CommandLine[$I], 3) = '-o:'
$DestFile = SubStr($CommandLine[$I], 4)
Case Left($CommandLine[$I], 3) = '-p:'
$ConfigFile = SubStr($CommandLine[$I], 4)
Case $CommandLine[$I] = '-c'
$Clip = 1
Case 1
'Warning: Argument ' $CommandLine[$I] ' was not understood! Ignored!' ?
EndSelect
Next
; Verify that the source file exists
If Not $SourceFile
? 'A source file was not specified - aborting!' ? ?
Quit 1
EndIF
If Not Exist($SourceFile)
? 'The defined source file "' $SourceFile '" was not found - aborting!' ? ?
Quit 1
EndIf
; If the destination file wasn't specified, use the SourceFileSpec and change the extension to ".htm"
If Not $DestFile
$DestFile = Left($SourceFile, InStrRev($SourceFile, '.')) + 'htm'
EndIf
; Abort if no config file was found, otherwise load the configuration settings
If Not $ConfigFile
'This Script requires a PostPrep.ini configuration - aborting!' ?
Quit 1
Else
; OK to proceed - read the configuration data
For $I = 0 to UBound($Sections)
$ColorTable[$I] = ReadProfileString($ConfigFile, 'FormatTable', $Sections[$I] + 'Color')
$BoldTable[$I] = Bool(ReadProfileString($ConfigFile, 'FormatTable', $Sections[$I] + 'Bold'))
Next
$Commands = EnumIni($ConfigFile, 'Commands')
$Functions = EnumIni($ConfigFile, 'Functions')
; verify the config file contains valid information
If Not UBound($Commands)
Or Not UBound($Functions)
Or Not UBound($ColorTable)
Or Not UBound($BoldTable)
? 'This Script requires a consistent configuration file - aborting!' ? ?
Quit 1
EndIf
$ShowStats = Bool(ReadProfileString($ConfigFile, 'Global', 'ShowStats'))
$Wrap = ReadProfileString($ConfigFile, 'Global', 'WordWrap')
$Border = Bool(ReadProfileString($ConfigFile, 'Global', 'Border'))
; Set the Border directive based on the flag value
If $Border
; read from PostPrep.ini - can be one of none,hidden,dotted,dashed,solid,double,groove,ridge,inset, or outset
$I = ReadProfileString($ConfigFile, 'FieldSet', 'Background-Color')
$Border = 'background:' + IIf($I, $I, 'white')
$I = ReadProfileString($ConfigFile, 'FieldSet', 'Border-Style')
$Border = $Border + ';border-style:' + IIf($I, $I, 'none')
$I = ReadProfileString($ConfigFile, 'FieldSet', 'Border-Width')
$Border = $Border + ';border-width:' + IIf($I, $I, '0')
Else
$Border = 'background:white;border-style:none;border-width:0'
EndIf
; Define the body settings
$Body = '<font face="'
$I = ReadProfileString($ConfigFile, 'FieldSet', 'TypeFace')
$Body = $Body + IIf($I, $I, 'Courier New')
$I = ReadProfileString($ConfigFile, 'FieldSet', 'FontSize')
$Body = $Body + '" size="' + IIf($I, $I, '2')
$Body = $Body + '" color="#000000">'
EndIf
;===================================================================
; Load the file contents into a string
If Open(1,$SourceFile,2) = 0
$I = ReadLine(1) + @CRLF
While @ERROR = 0
$FileContent = $FileContent + $I
$I = ReadLine(1) + @CRLF
Loop
$ = Close(1)
Else
? 'Error opening ' $SourceFile ' - aborting!' ?
@SERROR ? ?
Quit 1
EndIf
;===================================================================
$TimerS = @TICKS
$FileContent = Kix2HTM($FileContent,$ColorTable,$BoldTable,$Functions,$Commands,$Border, $Body, $Wrap)
$TimerE = @TICKS - $TimerS
; Copy to clipboard if the -c option was specified.
If $Clip
$ = CopyToClipboard($FileContent)
Else
Del $DestFile
$ = RedirectOutput($DestFile)
$FileContent
$ = RedirectOutput('')
EndIf
; Display time statistics if requested
If $ShowStats
? 'PostPrep completed processing in '
If Val($TimerE) < 1000
$TimerE ' milliseconds.' ?
Else
($TimerE / 1000) '.' CStr($TimerE Mod 1000) ' seconds.' ?
EndIf
EndIf
Function CopyToClipboard($strCopy)
Dim $objIE
$objIE = CreateObject("InternetExplorer.Application")
$objIE.Navigate("about:blank")
$CopyToClipboard = $objIE.document.parentwindow.clipboardData.SetData("Text",$strCopy)
$objIE.Quit
Exit @ERROR
EndFunction
;;
;;======================================================================
;;
;;FUNCTION Bool()
;;
;;ACTION return True if Flag is "non-zero", "T", "Y", or "ON"
;;
;;AUTHOR Glenn Barnas
;;
;;SYNTAX Bool(flag [,other_true] [,default])
;;
;;PARAMETERS Flag - REQUIRED, a text string - can be null
;;
;; Extra - OPTIONAL, a string of other "true" matches, comma-delimited.
;; "En*" will match the leftmost 2 chars
;;
;; Default - OPTIONAL, a default value to use if Flag is null
;;
;;REMARKS Returns TRUE if any of the following condidions are met:
;; First char of flag is "Y" (yes)
;; First char of flag is "T" (true)
;; First char of flag is a non-zero digit
;; Flag text is "ON"
;; Flag text matches optional Extra value
;;
;;RETURNS 1 if the flag evaluates to a "true" boolean, 0 otherwise
;;
;;DEPENDENCIES none
;;
;;TESTED WITH W2K, WXP, W2K3
;;
;;EXAMPLES If Bool(ReadProfileString('config.ini', 'sect', 'setting')
;; 'Setting is on!' ?
;; EndIf
;;
;; ; In this configuration, the default is T, and the config.ini value is
;; ; used to turn it off. If the setting in the ini file is not defined,
;; ; the default value is used.
;; $Default = 'T'
;; If Bool(ReadProfileString('config.ini', 'sect2', 'setting'), '', $Default)
;; 'Setting is on!' ?
;; EndIf
;
Function Bool($_Flag, OPTIONAL $_Extra, OPTIONAL $_Default)
; Handle embedded ReadLine errors passed to this wrapper func
If @ERROR Exit @ERROR EndIf
Dim $_XV, $_aXV, $bT, $bF
$bT = Not 0 ; TRUE value
$bF = Not $bT ; FALSE value
; set default value if defined and test value (Flag) is not defined
If $_Flag = '' And $_Default <> ''
$_Flag = $_Default
EndIf
$_Flag = UCase($_Flag) ; force uppercase chars
$Bool = $bF ; default to FALSE
If $_Extra
$_Extra = 'ON,TRUE,T,YES,Y,' + $_Extra
Else
$_Extra = 'ON,TRUE,T,YES,Y' ; default test values
EndIf
; Handle the numeric test
If Val($_Flag) <> 0 ; flag is non-zero
$Bool = $bT
EndIf
; process string comparisons
If Not $Bool
$_aXV = Split($_Extra, ',') ; get array of string match values
For Each $_XV in $_aXV ; then compare each one
If InStr($_XV, '*') ; is it a substring compare?
If UCase(Left($_XV, InStr($_XV, '*') - 1)) = Left($_Flag, InStr($_XV, '*') - 1)
$Bool = $bT
EndIf
Else ; or a direct compare
If UCase($_XV) = $_Flag
$Bool = $bT
EndIf
EndIf
Next
EndIf
Exit 0 ; always successful ;\)
EndFunction
;;
;;======================================================================
;;
;;FUNCTION EnumIni()
;;
;;ACTION Enumerates sections or keys of an INI file
;;
;;AUTHOR Glenn Barnas
;;
;;VERSION 2.0
;;
;;DATE CREATED 2003/11/17
;;
;;DATE MODIFIED 2004/10/16
;;
;;SYNTAX EnumIni(File [, Section])
;;
;;PARAMETERS File - REQUIRED, path/name of INI file to examine
;;
;; Section - OPTIONAL, Section name to parse
;;
;;REMARKS Returns an array containing the sections in an INI file, or
;; an array of key names in a specified section. Errors are returned
;; for non-existant files or INI file reads. If the specified file
;; contains no sections, or the specified section contains no keys,
;; the UDF exits with error 13 and returns a null array. Thus, a For-Each loop
;; will properly perform no iterations if no data is returned.
;;
;; CAUTION - Error 13 is returned for empty files, or nonexistant sections.
;; This is not necessarily a "failure".
;;
;;RETURNS Array of sections or keys in a section
;;
;;DEPENDENCIES none
;;
;;TESTED WITH Kix 4.2+, NT4, W2K, WXP, W2K3
;;
;;EXAMPLES $Sections = EnumIni('.\config.ini')
;; $Keys = EnumIni('.\config.ini', 'Common')
;
Function EnumIni($_fSrcFile, OPTIONAL $_fSectName)
Dim $_fSectList
; die if the file doesn't exist
If Exist($_fSrcFile) = 0
Exit 2
EndIf
; Get the list of sections or keys
$_fSectList = ReadProfileString($_fSrcFile, $_fSectName, '')
; Return if error occurred
If @ERROR
Exit @ERROR
EndIf
; If len is >0, return an array of sections
; If len is 0, either no sections or keys exist, or an invalid section name was specified. Return nothing.
If Len($_fSectList) > 0
$EnumIni = Split(Left($_fSectList,len($_fSectList)-1), Chr(10))
Exit 0
EndIF
; return an error here for value not found (no sections or no keys in section)
Exit 13
EndFunction
Registered: 2006-08-16
Posts: 686
Loc: Maryland, USA
Glenn or Jooel,
I'm not sure if this is a function of postprep or the forum software, but it would be nice to have the "postprepped code window" no longer than x lines. Say 10 or 15. It takes a long time to scroll across all that code in order to see the next post.
might be a feature of both. I added some func like that into the board software. the vertical limitation got removed cause having a too small view of the code is counter-beneficial. horisontal scroll doesn't always work but when it does, I smile cause I know those pesky long lines in a pre-field would have otherwise killed the experience
let me see what I can do about the vertical. 10 is surely too little, but something from 15-20 should already provide a good compromise.
ok, updated one style. takes a while to get through them all. anyways, now if the code is way long it is changed to scrolling. accepted width, with possible vertical scroll: 800 accepted height, with possible horisontal scroll: 500
glenn, I modified your kix2htm() post above by adding class to the pre-tag and it fired the sizing. we talked about this earlier, iirc.
if you agree to the sizing, add that class to the postprep, otherwise you can leave it out