: ) wonderful world ( :

the metasyntactic variable

Archive for May 2009

core context oriented programming with ContextL

without comments

ContextL is a part of the Closer project with contributions from Pascal Costanza and probably others. As per the code repository, it’s actively developed.

(defpackage :a-test
  (:use :cl))

(in-package :a-test)

(contextl:define-layered-class
    bar ()
    ((value :initarg :value :layered-accessor bar-value)))

(contextl:define-layered-function bar-incf (f))

(contextl:define-layered-method
    bar-incf ((b bar))
    (incf (bar-value b)))

(contextl:deflayer log-layer)

(contextl:define-layered-class
    bar :in log-layer ()
    ())

(contextl:define-layered-method
    bar-incf :in log-layer :around ((b bar))
    (progn
      (princ (format nil "~A is incfed" b))
      (call-next-method)))

(defparameter +a-bar+
  (make-instance 'bar :value 11))

 

And now, the REPL:

A-TEST> +a-bar+
#<BAR {BEB2581}>
A-TEST> (bar-value +a-bar+)
11
A-TEST> (bar-incf +a-bar+)
12
A-TEST> (bar-value +a-bar+)
12
A-TEST> (contextl:with-active-layers (log-layer) (bar-incf +a-bar+))
#<BAR {BEB2581}> is incfed
13
A-TEST> (bar-value +a-bar+)
13
A-TEST>

Written by grault

May 29, 2009 - 11:23 pm at May 29, 2009 - 11:23 pm

Posted in lisp

ms access relations into graphviz

without comments

Today is a scripting day : )

If you have to maintain a large MS Access database (manipulate data in it) with complex relationship matrix, the built-in relations diagram is quite useless. This is because Access won’t compute a proper layout. It just displays the nodes (the tables) next to each other and draw all the edges. Period. An idea is to dump these relations into a graphviz .dot file and let graphviz do the layout. This solution is very useful if you want to understand a complex database represented in Access.

C:\Users\grault\Desktop>dir/b test.accdb
test.accdb

C:\Users\grault\Desktop>type dumpRelationship.vbs
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objAcc = CreateObject("Access.Application")
fileName = objFSO.GetAbsolutePathName(WScript.Arguments.Item(0))
outName = objFSO.GetAbsolutePathName(WScript.Arguments.Item(1))

objAcc.OpenCurrentDatabase(fileName)
Set outFile = objFSO.CreateTextFile(outName)

outFile.WriteLine ("digraph G { graph [rankdir=""LR""];")
For Each tbl In objAcc.CurrentDb.Tabledefs
   If LCase(Left(tbl.Name, 4)) <> "msys" Then
     entry = """" & tbl.Name & """ [label=""<" & tbl.Name & "> " & tbl.Name
     For Each fi In tbl.Fields
       entry = entry & "| <" & fi.Name & "> " & fi.Name
     Next
     entry = entry & """ shape=""record""];"
     outFile.WriteLine(entry)
   End If
Next

For Each rel In objAcc.CurrentDb.Relations
  For Each fld In rel.Fields
    arrow = """" & rel.Table & """:" & fld.Name & " -> " & _
            """" & rel.ForeignTable & """:" & fld.ForeignName & _
            " [arrowhead=""odotodot"" arrowtail=""orboxrtee""];"
    outFile.WriteLine(arrow)
  Next
Next

outFile.WriteLine("}")
outFile.Close
objAcc.CloseCurrentDataBase
objAcc.Quit

C:\Users\grault\Desktop>dumpRelationship.vbs test.accdb test.dot

C:\Users\grault\Desktop>type test.dot
digraph G { graph [rankdir="LR"];
"Table1" [label="<Table1> Table1| <ID> ID| <Desc> Desc" shape="record"];
"Table2" [label="<Table2> Table2| <ID> ID| <Ref1> Ref1| <OtherDesc> OtherDesc"
shape="record"];
"Table1":ID -> "Table2":Ref1 [arrowhead="odotodot" arrowtail="orboxrtee"];
}

C:\Users\grault\Desktop>dot -Tpng -o test.png test.dot

(dot.exe:6480): Pango-WARNING **: couldn't load font
"Times Roman Not-Rotated 14 ",
falling back to "Sans Not-Rotated 14", expect ugly output.

C:\Users\grault\Desktop>

 

the result

the result

Written by grault

May 15, 2009 - 4:14 pm at May 15, 2009 - 4:14 pm

Posted in notes, script, windowns

concatenate or merge docx Word files dot vbs

without comments

In case you have generated Word files which are parts of a future “master” document and also you want to automate the process of assembling them together by writing some sort of build script, the following snippet is probably useful. Generating documents is good to avoid redundancy. In case you have to have a document in which parts can be computed based on other parts (with also the miserable contraint on document format and production environment) , it’s good to consider splitting the document, generating the parts and assembling them at the end. And now, the code:

C:\Users\grault\Desktop\a>dir/b
a1.docx
a2.docx
build.vbs

C:\Users\grault\Desktop\a>type build.vbs
Set objWord = CreateObject("Word.Application")
Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objDoc = objWord.Documents.Add()

objDoc.ActiveWindow.View.Type = 2 'wdOutlineView
For I = 1 To WScript.Arguments.Count - 1
   objDoc.Subdocuments.AddFromFile _
     (objFSO.GetAbsolutePathName(WScript.Arguments.Item(I)))
Next

objDoc.SaveAs(objFSO.GetAbsolutePathName(WScript.Arguments.Item(0)))
objWord.Quit
C:\Users\grault\Desktop\a>build.vbs out.docx a1.docx a2.docx

C:\Users\grault\Desktop\a>dir/b
a1.docx
a2.docx
build.vbs
out.docx

C:\Users\grault\Desktop\a>

Written by grault

May 15, 2009 - 9:46 am at May 15, 2009 - 9:46 am

Posted in notes, script, windowns