Bueno, más o menos resuelto sólo para dos controles personalizados (descarga de documentos y nota lateral). Os lo dejo por si sirve de ayuda a alguien (y también para mejorarlo y sugerir, claro):
Código vb:
Ver originalProtected Overrides Sub Render(ByVal writer As HtmlTextWriter)
writer.Write(String.Format("<h1>{0}</h1>", Titulo))
writer.Write("<!-- Iniciando proceso de contenido -->")
writer.Write(procesarContenidos(Contenido))
writer.Write("<!-- Contenido procesado -->")
writer.Write(String.Format("<div class=""fechasSeccion"">Publicado: {0:dd/MM/yyyy}", FechaPublicacion))
If FechaActualizacion <> FechaPublicacion Then
writer.Write(String.Format(" Última actualización: {0:dd/MM/yyyy}</div>", FechaActualizacion))
End If
writer.Write("</div>")
End Sub
Private Function procesarContenidos(ByVal texto As String) As String
Dim er As New System.Text.RegularExpressions.Regex("")
Dim strPatt As String = String.Empty
Dim match As System.Text.RegularExpressions.Match
Dim sb As StringBuilder
Dim tw As System.IO.StringWriter
Dim hw As HtmlTextWriter
'Procesa primero todos los controles de descarga de documentos
'(HyperLink personalizado) ya que no pueden tener controles hijo
strPatt = "\[cpersDescargaDocumento NavigateUrl=""(?<NavigateUrl>[^\s]*)"" Target=""([^\s]*)"" Text=""(?<Text>[^""]*)"" /\]"
Do While er.Match(texto, strPatt).Success
sb = New StringBuilder
tw = New System.IO.StringWriter(sb)
hw = New HtmlTextWriter(tw)
match = er.Match(texto, strPatt)
Dim dd As New ControlesPersonalizados.DescargaDocumento
dd.NavigateUrl = match.Groups("NavigateUrl").Value
dd.Target = match.Groups("Target").Value
dd.Text = match.Groups("Text").Value
dd.RenderControl(hw)
texto = String.Format("{0}{1}{2}", _
texto.Substring(0, match.Index), _
sb.ToString, _
texto.Substring(match.Index + match.Length))
Loop
'Procesa los cuadros de notas laterales (Panel personalizado)
strPatt = "\[cpersCuadroNotas Titulo=""(?<Titulo>[^\""]*)""\](?<Contenido>.*)\[/cpersCuadroNotas\]"
Do While er.Match(texto, strPatt).Success
sb = New StringBuilder
tw = New System.IO.StringWriter(sb)
hw = New HtmlTextWriter(tw)
match = er.Match(texto, strPatt)
Dim cn As New ControlesPersonalizados.CuadroNotas
cn.Titulo = match.Groups("Titulo").Value
cn.ContenidoAlternativo = match.Groups("Contenido").Value
cn.RenderControl(hw)
texto = String.Format("{0}{1}{2}", _
texto.Substring(0, match.Index), _
sb.ToString, _
texto.Substring(match.Index + match.Length))
Loop
Return texto
End Function
Un saludo.