You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
7.5KB

  1. <%
  2. ' Self-explained Constant
  3. Const DI_CurrentFolder = "../"
  4. ' ASP block tags
  5. Private DI_CloseTag : DI_CloseTag = Chr(37)&Chr(62)
  6. Private DI_OpenTag : DI_OpenTag = Chr(60)&Chr(37)
  7. Private DI_OpenClose : DI_OpenClose = DI_OpenTag & DI_CloseTag
  8. Private DI_OpenBreakClose : DI_OpenBreakClose = DI_OpenTag & (vbNewLine & DI_CloseTag)
  9. Private DI_CloseOpen : DI_CloseOpen = DI_CloseTag & DI_OpenTag
  10. Private DI_CloseBreakOpen : DI_CloseBreakOpen = DI_CloseTag & (vbNewLine & DI_OpenTag)
  11. ' ASP write block tags
  12. Private DI_WriteTag : DI_WriteTag = DI_OpenTag & "="
  13. Private DI_ResponseWrite : DI_ResponseWrite = DI_OpenTag & " Response.Write "
  14. Private DI_Require : DI_Require = DI_OpenTag & (" Require($1) " & DI_CloseTag)
  15. ' Public variables for file inclusion
  16. Public DynamicInclude_PreviousPath : DynamicInclude_PreviousPath = vbNullString
  17. Public DynamicInclude_CurrentPath : DynamicInclude_CurrentPath = DI_CurrentFolder
  18. Public DynamicInclude_TrimHtml : DynamicInclude_TrimHtml = false
  19. Public DynamicInclude_TrimNewlines : DynamicInclude_TrimNewlines = false
  20. ' Executes an imported file in the global namespace
  21. Sub ExecuteFile(ByVal File)
  22. Const DI_Bar = "/"
  23. Const DI_ReverseBar = "\"
  24. Dim BarIndex, Parsed, Path, FileName, CallerPath
  25. Path = Replace(File, DI_ReverseBar, DI_Bar)
  26. BarIndex = InStrRev(Path, DI_Bar)
  27. FileName = IIf(IsNull(BarIndex) Or BarIndex = 0, Path, Mid(Path, BarIndex + 1))
  28. Path = IIf(IsNull(BarIndex) Or BarIndex = 0, vbNullString, Mid(Path, 1, BarIndex))
  29. ' Update paths for recursive imports, remembering the caller's own
  30. ' baseline so it can be restored (not clobbered to the global default)
  31. ' once this file - and anything it recursively includes - has run.
  32. CallerPath = DynamicInclude_CurrentPath
  33. DynamicInclude_PreviousPath = DynamicInclude_CurrentPath
  34. DynamicInclude_CurrentPath = DynamicInclude_CurrentPath & Path
  35. ' Parse and execute the file - only the bare filename is appended here,
  36. ' since the directory portion is already folded into DynamicInclude_CurrentPath.
  37. Parsed = ParseFile(DynamicInclude_CurrentPath & FileName)
  38. ExecuteGlobal Trim(Parsed)
  39. ' Restore the caller's baseline so sibling #include's in the same parent
  40. ' file (e.g. a header then a footer) keep resolving correctly.
  41. DynamicInclude_CurrentPath = CallerPath
  42. DynamicInclude_PreviousPath = vbNullString
  43. End Sub
  44. ' Reads and parses an ASP file
  45. Function ParseFile(ByRef File)
  46. Const DI_LineJoin = """ & vbNewLine & """
  47. Const DI_Space = " "
  48. Const DI_Quote = """"
  49. Const DI_DoubleQuote = """"""
  50. Dim LineArray(4), KeepLeft, KeepRight, Match, Rows, PlainRow, Regex
  51. ' Read the file content
  52. ParseFile = ReadFile(File)
  53. ' Replace tags and write commands
  54. ParseFile = Replace(ParseFile, DI_CloseOpen, DI_CloseBreakOpen)
  55. ParseFile = Replace(ParseFile, DI_OpenClose, DI_OpenBreakClose)
  56. ParseFile = Replace(ParseFile, DI_WriteTag, DI_ResponseWrite)
  57. ' Convert ASP imports to Require calls
  58. Set Regex = New RegExp
  59. With Regex
  60. .Global = True
  61. .MultiLine = True
  62. .IgnoreCase = True
  63. .Pattern = "<!--\s*#include file=(""[^""]+"")\s*-->"
  64. End With
  65. ParseFile = Regex.Replace(ParseFile, DI_Require)
  66. ' Ensure proper ASP tags are present
  67. If Left(ParseFile, 2) <> DI_OpenTag Then
  68. ParseFile = (DI_OpenClose & vbNewLine) & ParseFile
  69. End If
  70. If Right(ParseFile, 2) <> DI_CloseTag Then
  71. ParseFile = ParseFile & (vbNewLine & DI_OpenClose)
  72. End If
  73. ' Trim the first open tag and last close tag
  74. ParseFile = Mid(ParseFile, 3, Len(ParseFile) - 4)
  75. ParseFile = Replace(ParseFile, "%", "&percnt;")
  76. ParseFile = Replace(ParseFile, "<&percnt;", DI_OpenTag)
  77. ParseFile = Replace(ParseFile, "&percnt;>", DI_CloseTag)
  78. ' Trim HTML if required
  79. If DynamicInclude_TrimHtml Then
  80. Regex.Pattern = "([^%]>)\s+(<[^%]\/?)"
  81. ParseFile = Regex.Replace(ParseFile, "$1$2")
  82. Regex.Pattern = "([^%](?!pre)>)\s*([^\s]+)\s*(<[^%](?!pre))"
  83. ParseFile = Regex.Replace(ParseFile, "$1$2$3")
  84. End If
  85. ' Insert plain texts in Response.write commands
  86. Regex.Pattern = (DI_CloseTag & "([^%])+") & DI_OpenTag
  87. Set Rows = Regex.Execute(ParseFile)
  88. LineArray(0) = vbNewLine
  89. LineArray(1) = "Response.write """
  90. LineArray(3) = DI_Quote
  91. LineArray(4) = vbNewLine
  92. For Each Match In Rows
  93. PlainRow = Mid(Match.Value, 3, Len(Match.Value) - 4)
  94. If (Left(PlainRow, 2) = vbNewLine) Then
  95. PlainRow = Right(PlainRow, Len(PlainRow) - 2)
  96. End If
  97. PlainRow = Replace(PlainRow, DI_Quote, DI_DoubleQuote)
  98. PlainRow = Replace(PlainRow, vbNewLine, DI_LineJoin)
  99. If (Right(PlainRow, Len(DI_LineJoin)) = DI_LineJoin) Then
  100. PlainRow = Left(PlainRow, Len(PlainRow) - Len(DI_LineJoin))
  101. End If
  102. If DynamicInclude_TrimHtml Then
  103. KeepLeft = (Left(PlainRow, 1) = DI_Space)
  104. KeepRight = (Right(PlainRow, 1) = DI_Space)
  105. PlainRow = Trim(PlainRow)
  106. If KeepLeft Then
  107. PlainRow = DI_Space & PlainRow
  108. End If
  109. If KeepRight Then
  110. PlainRow = PlainRow & DI_Space
  111. End If
  112. End If
  113. LineArray(2) = PlainRow
  114. ParseFile = Replace(ParseFile, Match.Value, Join(LineArray, vbNullString))
  115. Next
  116. ' Clean up
  117. Set Rows = Nothing
  118. Set Match = Nothing
  119. Erase LineArray
  120. ' Remove empty Response.write commands and duplicate new lines
  121. ParseFile = Replace(ParseFile, "Response.write """"" & vbNewLine, vbNullString)
  122. If DynamicInclude_TrimNewlines Then
  123. Regex.Pattern = "(?:\s+\n)+"
  124. ParseFile = Regex.Replace(ParseFile, vbNewLine)
  125. End If
  126. ParseFile = Replace(ParseFile, "&percnt;", "%")
  127. Set Regex = Nothing
  128. End Function
  129. ' Reads a file as plain text
  130. Function ReadFile(ByRef File)
  131. Dim System : Set System = Server.CreateObject("Scripting.FileSystemObject")
  132. Dim Path, FileData
  133. If File = vbNullString Then
  134. File = DI_CurrentFolder
  135. End If
  136. Path = Server.MapPath(File)
  137. If System.FileExists(Path) Then
  138. Set FileData = System.OpenTextFile(Path, 1)
  139. ReadFile = FileData.ReadAll
  140. Set FileData = Nothing
  141. ' Normalize line endings to vbNewLine regardless of how the file was
  142. ' saved. ParseFile's plain-text-to-Response.write splicing searches
  143. ' for vbNewLine specifically - a lone LF left unconverted embeds a
  144. ' raw newline inside a generated string literal, breaking it.
  145. ReadFile = Replace(ReadFile, Chr(13) & Chr(10), Chr(10))
  146. ReadFile = Replace(ReadFile, Chr(10), vbNewLine)
  147. Else
  148. Err.Raise 53, "DynamicIncludes.ReadFile", "File '" & File & "' was not found."
  149. End If
  150. Set System = Nothing
  151. End Function
  152. ' Tries to include a file silently
  153. Sub Include(ByVal File)
  154. On Error Resume Next
  155. ExecuteFile File
  156. On Error GoTo 0
  157. End Sub
  158. ' Tries to include a file and stops execution on error
  159. Sub Require(ByVal File)
  160. On Error Resume Next
  161. ExecuteFile File
  162. If Err.Number > 0 Then
  163. Response.Write "---FATAL ERROR: while trying to execute <b>" & File & "</b>---<br>" & _
  164. "---Error description: " & Err.Description & "<br>" & _
  165. "---Error Source: " & Err.Source & "<hr>" & _
  166. "---Error Line: " & Err.Line & "<hr>"
  167. Response.End
  168. End If
  169. On Error GoTo 0
  170. End Sub
  171. Function IIf(expr, truePart, falsePart)
  172. If CBool(expr) Then
  173. IIf = truePart
  174. Else
  175. IIf = falsePart
  176. End If
  177. End Function
  178. %>

Powered by TurnKey Linux.