Reply to topic  [ 10 posts ] 
Do other forum members also get this error message? 
Author Message

Joined: 2012-12-19 05:02:52
Posts: 226
Hello everybody,

When I run the following macro, I get this error:
The "join" property requires an object, instead found "undefined" from "$dayNames{?}"

I wonder if it's just me, or do other forum members also see this?

Code:
### Insert Calendar ###

# Inserts a calendar showing the current month.

# Localized day names may not be correct.

# This macro was originally written by Kino, whose other macros can
# be found at http://www2.odn.ne.jp/alt-quinon/files/NWPro/

Require Pro Version 1.3
$lproj = Application Property 'localization'

$doc = Document.active
if $doc == undefined
   exit
end
$origSel = $doc.textSelection
$origSel.length = 0

$dayNames = Hash.new
$dayNames{'Danish'} = Array.new 'ma', 'ti', 'on', 'to', 'fr', 'lø', 'sø'
#$dayNames{'English'} = Array.new 'Sun', 'Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat'
$dayNames{'English'} = Array.new 'Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat', 'Sun'
$dayNames{'French'} = Array.new 'dim','lun','mar','mer','jeu','ven','sam'
$dayNames{'German'} = Array.new 'Son','Mon','Die','Mit','Don','Fre','Sam'
$dayNames{'Italian'} = Array.new 'dom', 'lun', 'mar', 'mer', 'gio', 'ven', 'sab'
$dayNames{'Japanese'} = Array.new '日','月','火','水','木','金','土'
$dayNames{'Polish'} = Array.new 'Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'So', 'N'
$dayNames{'Spanish'} = Array.new 'dom','lun','mar','mié','jue','vie','sm'

$dayNamesText = $dayNames{$lproj}.join "\t"

$SundayColor = Color.newWithRGB 0.498, 0, 0  # Dark Red
$SaturdayColor = Color.newWithRGB 0, 0, 0.498  # Dark Blue

$calData = undefined
begin Perl
   $calData = `/usr/bin/cal`;
end
$calData.replaceAll '^\x20+|\n+\z', '', 'E'
$calData = $calData.split "\n"
foreach $i, $data in $calData
   if $i == 0  # overwrite the 1st row (month, year)
      $now = Date.now
      $month = Date.nameOfMonth $now.month
      $data = $month & "\x20"
      $data &= $now.year
   elsif $i == 1  # overwrite the 2nd row (day names)
      $data = $dayNamesText
      $data = $dayNames{$lproj}.join "\t"
   else
      $data.replaceAll '\x20+', '\t', 'E'
      if $i == 2  # 3rd row: first week
         $n = 13 - $data.length
         $n = $n / 2
         $leadingTab = undefined
         while $n
            $leadingTab &= "\t"
            $n -= 1
         end
         $data = $leadingTab & $data
      end
   end
   $calData[$i] = $data
end

$calData = $calData.join "\n"
$calData = $calData & "\n"
$calData = Cast to String $calData
$calData = Cast to Attributed String $calData

$SmallCaps = $Bold = $Italic = $Shadow = $ConvertToTable = $MergeCells = $AlignCellsCenter = $AlignCellsMiddle = Hash.new

$SmallCaps{'Danish'} = ':Format:STORT/lille tegn:Vis som små kapitæler'
$Bold{'Danish'} = ':Format:Fed'
$Italic{'Danish'} = ':Format:Kursiv'
$Shadow{'Danish'} = ':Format:Skygge'
$ConvertToTable{'Danish'} = ':Tabel:Konverter til tabel'
$MergeCells{'Danish'} = ':Tabel:Flet celler'
$AlignCellsCenter{'Danish'} = ':Tabel:Justér celler:Centreret'
$AlignCellsMiddle{'Danish'} = ':Tabel:Justér celler:Midte'

$SmallCaps{'English'} = ':Format:Character Case:Display as Small Caps'
$Bold{'English'} = ':Format:Font Face:Bold'
$Italic{'English'} = ':Format:Font Face:Italic'
$Shadow{'English'} = ':Format:Font Face:Shadow'
$ConvertToTable{'English'} = ':Table:Convert to Table'
$MergeCells{'English'} = ':Table:Merge Cells'
$AlignCellsCenter{'English'} = ':Table:Align Cells:Center'
$AlignCellsMiddle{'English'} = ':Table:Align Cells:Middle'

$SmallCaps{'French'} = ':Format:Casse Caractère:Afficher comme Petites Majuscules'
$Bold{'French'} = ':Format:Gras'
$Italic{'French'} = ':Format:Italique'
$Shadow{'French'} = ':Format:Ombre'
$ConvertToTable{'French'} = ':Tableau:Convertir en tableau'
$MergeCells{'French'} = ':Tableau:Fusionner les Cellules'
$AlignCellsCenter{'French'} = ':Tableau:Aligner les cellules:Centrer'
$AlignCellsMiddle{'French'} = ':Tableau:Aligner les cellules:Deuxième nom'

$SmallCaps{'German'} = ':Format:Groß-/Kleinschreibung:Anzeigen als Kapitälchen'
$Bold{'German'} = ':Format:Fett'
$Italic{'German'} = ':Format:Kursiv'
$Shadow{'German'} = ':Format:Schatten'
$ConvertToTable{'German'} = ':Tabelle:In Tabelle umwandeln'
$MergeCells{'German'} = ':Tabelle:Zellen zusammenführen'
$AlignCellsCenter{'German'} = ':Tabelle:Zellen ausrichten:Zentriert'
$AlignCellsMiddle{'German'} = ':Tabelle:Zellen ausrichten:Mitte'

$SmallCaps{'Italian'} = ':Formato:Maiuscole/minuscole:Mostra in maiuscoletto'
$Bold{'Italian'} = ':Formato:Neretto'
$Italic{'Italian'} = ':Formato:Corsivo'
$Shadow{'Italian'} = ':Formato:Ombreggiato'
$ConvertToTable{'Italian'} = ':Tabella:Converti in tabella'
$MergeCells{'Italian'} = ':Tabella:Unisci celle'
$AlignCellsCenter{'Italian'} = ':Tabella:Allinea celle:Centrato'
$AlignCellsMiddle{'Italian'} = ':Tabella:Allinea celle:Centro'

$SmallCaps{'Japanese'} = ':フォーマット:小文字/大文字:Small Caps'
$Bold{'Japanese'} = ':フォーマット:太字'
$Italic{'Japanese'} = ':フォーマット:斜体'
$Shadow{'Japanese'} = ':フォーマット:影付き'
$ConvertToTable{'Japanese'} = ':表:表に変換'
$MergeCells{'Japanese'} = ':表:セル結合'
$AlignCellsCenter{'Japanese'} = ':表:セル内位置揃え:中央揃え'
$AlignCellsMiddle{'Japanese'} = ':表:セル内位置揃え:中央'

$SmallCaps{'Polish'} = ':Format:Wielkość Znaków:Wyświetl jakokapitaliki'
$Bold{'Polish'} = ':Format:Pogrubienie'
$Italic{'Polish'} = ':Format:Kursywa'
$Shadow{'Polish'} = ':Format:Cień'
$ConvertToTable{'Polish'} = ':Tabela:Konwertuj do Tabeli'
$MergeCells{'Polish'} = ':Tabela:Scal Komórki'
$AlignCellsCenter{'Polish'} = ':Tabela:Wyrównaj Komórki:Środek'
$AlignCellsMiddle{'Polish'} = ':Tabela:Wyrównaj Komórki:Środek'

$SmallCaps{'Spanish'} = ':Formato:Mayúsculas/minúsculas:Mostrar como versalitas'
$Bold{'Spanish'} = ':Formato:Negrita'
$Italic{'Spanish'} = ':Formato:Cursiva'
$Shadow{'Spanish'} = ':Formato:Sombra'
$ConvertToTable{'Spanish'} = ':Tabla:Convertir a tabla'
$MergeCells{'Spanish'} = ':Tabla:Fundir celdas'
$AlignCellsCenter{'Spanish'} = ':Tabla:Alinear celdas:Centrar'
$AlignCellsMiddle{'Spanish'} = ':Tabla:Alinear celdas:Mitad'

Insert Attributed Text $calData
Menu $ConvertToTable{$lproj}
Menu $AlignCellsCenter{$lproj}
Menu $AlignCellsMiddle{$lproj}

$tableSel = $doc.tableSelection
$table = $tableSel.table

# Set style attibutes of the first row, e.g. July 2009
$1stRow = Range.new 0, 1
$1stRowSel = TableSelection.new $table, $1stRow
$doc.setSelection $1stRowSel
Menu $MergeCells{$lproj}
Menu $Bold{$lproj}
Menu $Shadow{$lproj}
$sel = TextSelection.active
$attr = $sel.text.displayAttributesAtIndex $sel.location
$kern = $attr.fontSize / 12
Set Kerning $kern

# Set style attibutes of the second row (Sun Mon Tue Wed Thr Fri Sat)
$2ndRow = Range.new 1, 1
$2ndRowSel = TableSelection.new $table, $2ndRow
$doc.setSelection $2ndRowSel
Menu $Bold{$lproj}
Menu $Italic{$lproj}
Menu $SmallCaps{$lproj}
$dataRows = Range.new 1, $table.rowCount - 1

# Set Sunday color
#$1stCol = Range.new 0, 1
#$Sundays = TableSelection.new $table, $dataRows, $1stCol
#$doc.setSelection $Sundays
#Set Text Color $SundayColor

$7thCol = Range.new 6, 1
$Sundays = TableSelection.new $table, $dataRows, $7thCol
$doc.setSelection $Sundays
Set Text Color $SundayColor


# Set Saturday color
#$7thCol = Range.new 6, 1
#$Saturdays = TableSelection.new $table, $dataRows, $7thCol
#$doc.setSelection $Saturdays
#Set Text Color $SaturdayColor

$6thCol = Range.new 5, 1
$Saturdays = TableSelection.new $table, $dataRows, $6thCol
$doc.setSelection $Saturdays
Set Text Color $SaturdayColor



$doc.setSelection $origSel  # move the caret to the original location

### end of macro ###


2017-09-25 05:52:07
Profile
User avatar

Joined: 2007-02-07 00:58:12
Posts: 876
Location: Japan
Hello Þorvarður,
I have not tried running the macro myself, but of course you are likely to get such an error, considering this code.

The variable $lproj will be set at the following line:
Code:
$lproj = Application Property 'localization'

and while the macro documentation says that you might get a value like 'English', I generally would much more likely expect a value like 'en'. And the following code will of course fail if the $lproj is not one of those written out language names specified in the following code. This is why the error message says "$dayNames{?}". The question mark tells you that the key you are using to access the hash is not defined.

To avoid the error message you should include some code like this:
Code:
if ! $dayNames.definesKey($lproj)
    exit
end

This will allow the macro to terminate "gracefully". But then this macro will still not work in the majority of all cases. More usefully you will need to provide some way for it to work with the appropriate codes ('en', 'da', 'jp', etc.)

_________________
philip


2017-09-25 06:39:59
Profile
User avatar

Joined: 2007-02-07 00:58:12
Posts: 876
Location: Japan
You might be able to use code like this:
Code:
$lproj = Application Property 'localization'
if $lproj == 'en'
   $lproj = 'English'
else
   $lang = Language.languageWithCode($lproj)
   $lproj = $lang.unlocalizedName
end

$dayNames = Hash.new
$dayNames{'Danish'} = Array.new 'ma', 'ti', 'on', 'to', 'fr', 'lø', 'sø'
$dayNames{'English'} = Array.new 'Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat', 'Sun'
$dayNames{'French'} = Array.new 'dim','lun','mar','mer','jeu','ven','sam'
$dayNames{'German'} = Array.new 'Son','Mon','Die','Mit','Don','Fre','Sam'
$dayNames{'Italian'} = Array.new 'dom', 'lun', 'mar', 'mer', 'gio', 'ven', 'sab'
$dayNames{'Japanese'} = Array.new '日','月','火','水','木','金','土'
$dayNames{'Polish'} = Array.new 'Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'So', 'N'
$dayNames{'Spanish'} = Array.new 'dom','lun','mar','mié','jue','vie','sm'

if ! $dayNames.definesKey($lproj)
   exit 'Invalid Language'
end
$dayNamesText = $dayNames{$lproj}.join "\t"

_________________
philip


2017-09-25 07:16:47
Profile

Joined: 2012-12-19 05:02:52
Posts: 226
Yes, now it's running, thanks to your help, Philip, but the calculation isn't correct. Thursday 28 Sept. is output as Thursday 27 Sept., that is 1 day behind the correct date.

I suppose the error is in this part. Your sharp eyes miss nothing. Do you see anything that could possibly be accountable for the miscalculation?

Code:
$calData = undefined

begin Perl
   $calData = `/usr/bin/cal`;
end

$calData.replaceAll '^\x20+|\n+\z', '', 'E'
$calData = $calData.split "\n"
foreach $i, $data in $calData
   if $i == 0  # overwrite the 1st row (month, year)
      $now = Date.now
      $month = Date.nameOfMonth $now.month
      $data = $month & "\x20"
      $data &= $now.year
   elsif $i == 1  # overwrite the 2nd row (day names)
      $data = $dayNamesText
      #$data = $dayNames{$lproj}.join "\t"
   else
      $data.replaceAll '\x20+', '\t', 'E'
      if $i == 2  # 3rd row: first week
         $n = 13 - $data.length
         $n = $n / 2
         $leadingTab = undefined
         while $n
            $leadingTab &= "\t"
            $n -= 1
         end
         $data = $leadingTab & $data
      end
   end
   $calData[$i] = $data
end

$calData = $calData.join "\n"
$calData = $calData & "\n"
$calData = Cast to String $calData
$calData = Cast to Attributed String $calData


2017-09-27 23:57:48
Profile
User avatar

Joined: 2007-02-07 00:58:12
Posts: 876
Location: Japan
Well this code is using a calendar output from perl. Presumably the format (Sun first vs. Mon first) may depend on your local settings?
Anyhow for me this
Code:
begin Perl
   $calData = `/usr/bin/cal`;
end

creates a Sun first calendar. The rest of the code ignores this fact and just puts a Mon first heading over it. So the days are all wrong.

Overall this code was written by Kino a long time ago. At the time Nisus macro language didn't have any date object. But now it does. So it would be much easier to write one's own code, rather than using a perl output.

_________________
philip


2017-09-28 01:35:41
Profile
User avatar

Joined: 2007-02-07 00:58:12
Posts: 876
Location: Japan
Here is a macro that creates a calendar for the current month. (No perl required)

Code:
# Create a Calandar for the current month
#
# Get the current date, and month and limit dates for calendar
$date = Date.now
$year = $date.year
$month = Date.nameOfMonth($date.month)
$firstDate = Date.newWithYearMonthDay($year,$date.month,1)
$lastDate = Date.newWithYearMonthDay($year,$date.month + 1,1)
$lastDate = $lastDate.dateByAddingSeconds(-60)
$lastDay = $lastDate.day

# Create a title for the calendar
$calData = Array.new $month & ' ' & $year

# Create a list of weekdays
$r = Range.new 0,3
$dayNames = Array.new
for $w = 1 to 7
   $dayNames.push Date.nameOfWeekday($w).substringInRange($r)
end
$calData.push $dayNames.join("\t")

# Run through the weeks of the calendar
$week = Array.new
# Pad the first week if necessary
for $d = 1 to ($firstDate.weekday - 1)
   $week.push ''
end
# Fill a week and output and start over
for $d = 1 to $lastDay
   $week.push $d
   if $week.count >= 7
      $calData.push $week.join("\t")
      $week = Array.new
   end
end
# Output any remaining days
if $week.count > 0
   $calData.push $week.join("\t")
end

# Combine everything into a calendar and output into a new document
Document.newWithText $calData.join("\n")

_________________
philip


2017-09-28 02:17:32
Profile

Joined: 2012-12-19 05:02:52
Posts: 226
Quote:
Overall this code was written by Kino a long time ago.

I had not used this macro for quite a while, but as far as I can remember, it used to work fine. What I found particularly irritating was that I had even assigned it a keyboard shortcut, which for me was an indication that I had been using it successfully.

Assuming it was working and that I'm not mistaken, what might have changed in the meantime to prevent it from working?


2017-10-02 13:54:44
Profile

Joined: 2012-12-19 05:02:52
Posts: 226
phspaelti wrote:
Here is a macro that creates a calendar for the current month. (No perl required)

Yes, this works well. Thanks a lot.
I use this now as a glossary. :-)

Attachment:
1.png
1.png [ 54.98 KiB | Viewed 975 times ]


2017-10-02 14:00:10
Profile
User avatar

Joined: 2007-02-07 00:58:12
Posts: 876
Location: Japan
Þorvarður wrote:
Quote:
Overall this code was written by Kino a long time ago.

I had not used this macro for quite a while, but as far as I can remember, it used to work fine. What I found particularly irritating was that I had even assigned it a keyboard shortcut, which for me was an indication that I had been using it successfully.

Assuming it was working and that I'm not mistaken, what might have changed in the meantime to prevent it from working?

Since Kino wrote it, I think we can assume that at some time it certainly worked. :)

But generally there isn't anything really wrong with the code itself. The problems are entirely with the assumptions made about the environment. So perhaps in the past the $lproj variable returned something like "English" as a value. Also the perl calendar might have a setting that ensures that it returns a Monday first calendar. Maybe some of this changed. I just wouldn't know.

One thing about Kino's original macro is that it has a lot of code just to deal with different languages. And the different languages are just to accommodate users with different localizations. These aren't even user choices; I can't use this macro to make a Polish calendar, unless I restart Nisus on a mac set to use Polish. So Kino clearly intended this macro for user distribution. The vast majority of users use only one localization, and so most users will need only a small subset of the entire code.

_________________
philip


2017-10-02 19:53:09
Profile
Official Nisus Person
User avatar

Joined: 2002-07-11 17:14:10
Posts: 4251
Location: San Diego, CA
phspaelti wrote:
Since Kino wrote it, I think we can assume that at some time it certainly worked. :)

Very true! Kino is a real wizard.

Quote:
But generally there isn't anything really wrong with the code itself. The problems are entirely with the assumptions made about the environment. So perhaps in the past the $lproj variable returned something like "English" as a value.

This is exactly what caused the error. The localization property used by the macro isn't guaranteed to return a full language name. From the macro language guide:
Quote:
Returns the name of the localization (.lproj folder) that the application is using. This folder name is most likely a normalized code like "en" or "pt_BR" but could also be the language name, eg: "English".

The full language names have fallen out of favor. It's more likely that a normalized language code will be returned.


2017-10-03 10:51:01
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 10 posts ] 

Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software