#!/usr/bin/awk #### ◇日記ファイル構築スクリプト mkd.awk V2.10 #### Copyright 1998,1999,2000 GORRY. #### mailto: gorry@hauN.org #### #### History: #### 2000/11/06 ISBNpatch @/isbn/ オンライン書店への自動リンク処理を追加(hachi) #### 2000/08/25 V2.10 @s1・@s2を追加。 #### 2000/04/06 V2.02 @footを追加。 #### PiloWeb対応。 #### 2000/03/12 V2.02 chmod 666をchmod o+wに変更。 #### 2000/01/12 V2.01 LASTMODIFIEDFORMATの書式をRFC形式に変更。 #### GETDIRに対応。 #### 1〜9月にhttpdサーバ用installすると正常動作しないバグを修正。 #### 1999/09/30 V2.00 リニューアル。 #### 1999/08/24 V1.14 @fの出力形式をちょいと変更。 #### 更新時刻を出力する@lastmodifiedを追加。 #### 1999/08/20 V1.13 記述のない日の出力を抑制するPRINTNOEXISTDAYを追加。 #### @f・@*を追加。 #### 1999/06/13 V1.12 が余計に出力されるバグを修正。 #### 1999/02/23 V1.11 公開ファイルの出力ディレクトリを変更可能に。 #### 1999/01/28 V1.10 タイトルの表示環境を変更。 ####
環境下で空行がスキップされるbugのfix。 
#### 1999/01/27 V1.09 タイトルの表示環境を変更。 
#### 1999/01/25 V1.08 Win環境で動作のときはS-JISを吐くよう修正。 
#### 1999/01/07 V1.07 @monthが正しく置換されないbugのfix。 
#### 1999/01/04 V1.06 @prevfile・@nextfileが正しく置換されないbugのfix。 
#### 1999/01/04 V1.05 31日が最終旬に追加されないbugのfix。 
#### 1999/01/02 V1.05 mawkで月や日に01などの値を与えると動作しないbugのfix。 
#### 1998/12/16 V1.03 prev/today/next対応。 
#### 1998/12/15 V1.02 URLデータベース置換高速化。 
#### 1998/12/14 V1.01 URLデータベースで、"\r"が置換結果に混入するbugのfix。 
####                  URLデータベース置換の高速化。 
####                  ソース整理。 
####                  Windows自動検知追加。 
#### 1998/12/13 V1.00 新規作成。 

########################################################################
### 初期設定 
#
function Setup(       fin )
{
	DIGESTHEADERNAME = "10.html"				# ダイジェストヘッダファイル名 
	DIGESTPREMEMONAME = "11.html"				# ダイジェスト本文前挿入ファイル名 
	DIGESTPOSTMEMONAME = "20.html"				# ダイジェスト本文後挿入ファイル名 
	DIGESTFOOTERNAME = "21.html"				# ダイジェストフッタファイル名 
	BASEHEADERNAME = "30.html"					# ベースファイルヘッダファイル名 
	BASEFOOTERNAME = "40.html"					# ベースファイルフッタファイル名 
	ITEMNAME = "98.html"						# 挿入アイテムファイル名 
	REPLACENAME = "99.html";					# URL置換データベース名 
	ISBNFNAME = "ISBN.html"; # ISBN output format定義ファイル名

	LASTMODIFIEDFORMAT = "%a, %d %b %Y %H:%M:%S %Z";				# 更新時刻出力フォーマット(@/lastmodified/) 
}

########################################################################
### 最初の区切りを表示 
#
function PrintStart( fout )
{
	print "">fout;
	print "">fout;
}

########################################################################
### 日付タグ表示 
#
function PrintDiaryDate( fout, year, month, date, wday, part )
{
	s = sprintf( "%04d/%02d/%02d (%s) %s %s", date, year, month, PARTS[part], date, year, month, date, WDAYS[wday], PARAM_WEATHER, PARAM_TOPIC );
	sub( /[ ]+$/, "", s );
	printf( "

%s

\n", s )>fout; } ######################################################################## ### 日の区切りを表示 # function PrintInterval( fout ) { print "">fout; print "">fout; print "
">fout; print "">fout; } ######################################################################## ### 最後の区切りを表示 # function PrintTerminate( fout ) { print "">fout; print "">fout; print "">fout; } ######################################################################## ### 1日分の本文を表示 # function PrintDiary( fout, year, month, date, part, istoday ,wday, i ) { YMD2DAYS( year, month, date ); wday = WDAY; GetDiary( year, month, date, wday, part ); if ( istoday ) { print "">fout; } PrintDiaryDate( fout, year, month, date, wday, part ); FOOTNOTE_REFER = 0; for ( i=0; ifout; } if ( NTITLE ) { print "">fout; }; if ( PARAM_FOOT ) { printf( "

%s%s%s

\n", FOOTSTARTMARK, PARAM_FOOT, FOOTENDMARK )>fout; } if ( istoday ) { print "">fout; } } ######################################################################## ### セクションを閉じる # function CloseSection( sectionmode , line ) { line = DIARYLINE[DIARYLINES-1]; if ( sectionmode == 0 ) { line = line "

"; } else if ( sectionmode == 1 ) { DIARYLINE[DIARYLINES++] = ""; line = "
"; } else if ( sectionmode == 2 ) { DIARYLINE[DIARYLINES++] = ""; line = ""; } else if ( sectionmode == 3 ) { DIARYLINE[DIARYLINES++] = ""; line = ""; } else if ( sectionmode == 4 ) { DIARYLINE[DIARYLINES++] = ""; line = ""; } else if ( sectionmode == 5 ) { DIARYLINE[DIARYLINES++] = ""; line = ""; } else if ( sectionmode == 6 ) { line = line "

"; } DIARYLINE[DIARYLINES-1] = line; } ######################################################################## ### マスタファイル名を返す # function MakeMasterFileName( year, month, date ) { return ( sprintf( GETDIR SLASH "%04d" SLASH "%02d%02d.html", year, month, date ) ); } ######################################################################## ### 1日分のマスタファイルを得る ## 同時に段落タグ置換作業を行なう # function GetDiary( year, month, date, wday, part , line, sectionmode, nsection, fin, sections ) { PARAM_WEATHER = ""; PARAM_TOPIC = ""; PARAM_FOOT = ""; DIARYLINES = 0; sectionmode = -1; NTITLE = 0; nsection = 0; nfootnote = 0; fin = MakeMasterFileName( year, month, date ); sections="abcdefghijklmnopqrstuvwxyz"; # print fin; while ( (getline line 0 ) { sub( "\r", "", line ); if ( length(line) <= 0 ) { if ( sectionmode == 1 ) { } else if ( sectionmode == 2 ) { } else { continue; } } else if ( sub( /^@weather /, "", line ) ) { PARAM_WEATHER = line; continue; } else if ( sub( /^@topic /, "", line ) ) { PARAM_TOPIC = line; continue; } else if ( sub( /^@foot /, "", line ) ) { PARAM_FOOT = line; continue; } if ( sub( /^@title /, "", line ) ) { CloseSection( sectionmode ); if ( NTITLE ) { DIARYLINE[DIARYLINES++] = ""; } NTITLE++; DIARYLINE[DIARYLINES++] = ""; DIARYLINE[DIARYLINES++] = sprintf("

%s%s

", date, NTITLE, year, month, PARTS[part], date, NTITLE, TITLEMARK, line ); line = "
"; nsection = 0; sectionmode = -1; } else if ( match( line, /^@s1/ ) ) { CloseSection( sectionmode ); nsection++; line = "

"; sectionmode = 0; } else if ( match( line, /^@s2/ ) ) { s = substr( sections, nsection, 1 ) line = sprintf( "%s", date, NTITLE, s, year, month, PARTS[part], date, NTITLE, s, SENTENSEMARK ); } else if ( match( line, /^@s/ ) ) { CloseSection( sectionmode ); nsection++; s = substr( sections, nsection, 1 ) line = sprintf( "

%s", date, NTITLE, s, year, month, PARTS[part], date, NTITLE, s, SENTENSEMARK ); sectionmode = 0; } else if ( match( line, /^@qcode/ ) ) { CloseSection( sectionmode ); line = "

";
			sectionmode = 1;
		} else if ( match( line, /^@q/  ) ) {
			CloseSection( sectionmode );
			line = "
";
			sectionmode = 2;
		} else if ( match( line, /^@p/  ) ) {
			CloseSection( sectionmode );
			line = "

"; sectionmode = 0; } else if ( match( line, /^@close/ ) ) { CloseSection( sectionmode ); sectionmode = -1; continue; } else if ( match( line, /^@c/ ) ) { CloseSection( sectionmode ); line = "

"; sectionmode = 3; } else if ( match( line, /^@ul/ ) ) { CloseSection( sectionmode ); line = "
    "; sectionmode = 4; } else if ( match( line, /^@ol/ ) ) { CloseSection( sectionmode ); line = "
      "; sectionmode = 5; } else if ( match( line, /^@f/ ) ) { CloseSection( sectionmode ); nfootnote++; line = ""; if ( sectionmode != 6 ) { line = ""; # "
      \n"; } line = line sprintf( "

      %s%d:", date, nfootnote, year, month, PARTS[part], date, nfootnote, FOOTNOTEMARK, nfootnote ); sectionmode = 6; } else { if ( sectionmode == -1 ) { line = "

      " line; sectionmode = 0; } } DIARYLINE[DIARYLINES++] = line; } CloseSection( sectionmode ); close( fin ); } ######################################################################## ### 表示アイテムの初期化 # function Setup_ITEMS( fin, line, i ) { if ( WDAYS[0] == "" ) { fin = KEEPDIR SLASH ITEMNAME; i = 0; while ( (getline line 0 ) { gsub( "\r", "", line ); WDAYS[i++] = line; } close( fin ); TITLEMARK = WDAYS[7]; SENTENSEMARK = WDAYS[8]; FOOTNOTEMARK = WDAYS[9]; FOOTSTARTMARK = WDAYS[10]; FOOTENDMARK = WDAYS[11]; } } ######################################################################## ### 旬名の初期化 # function Setup_PARTS() { PARTS[0] = "a"; PARTS[1] = "b"; PARTS[2] = "c"; } ######################################################################## ### URL置換データベースの初期化 # function MakeReplaceDatabase( fin ) { FS = "[ \t]+"; NREPLACE = 0; while ( ( getline 0 ) { if ( match( $1, "^#" ) ) { continue; } if ( length( $0 ) < 1 ) { continue; } REPLACE_Key[ NREPLACE ] = $1; REPLACE_Name[ $1 ] = $2; REPLACE_Obj[ $1 ] = $3; gsub( "\r", "", REPLACE_Obj[ $1 ] ); NREPLACE++; } close( fin ); } ######################################################################## ### ISBN置換データベースの初期化 # ISBN output patch add. 2000.11.6 by hachi@hauN.org # function MakeReplaceISBN( fin ) { REPLACEISBN = ""; while ( ( getline 0 ) { if ( match( $1, "^#" ) ) { continue; } gsub( "\r", "", $0 ); REPLACEISBN = REPLACEISBN $0 "\n"; } close( fin ); } ######################################################################## ### 固定置換およびURL置換データベースによる置換 # function Replace( line, year, month, part, date , y, m, p, s, i, pt, le, s1, s2, key, name ) { if ( !match( line, "@" ) ) { return line; } gsub( "@/lastmodified/", LASTMODIFIED, line ); s = sprintf( "%04d", year ); gsub( "@/year/", s, line ); s = sprintf( "%02d", month ); gsub( "@/month/", s, line ); gsub( "@/part/", PARTS[part], line ); gsub( "@/PART/", part+1, line ); if ( match( line, "@/prevfile/" ) ) { y = year; m = month; p = part; p--; if ( p < 0 ) { p = 2; m--; if ( m < 1 ) { m = 12; y--; } } s = sprintf( "%04d%02d%s.html", y, m, PARTS[p] ); gsub( "@/prevfile/", s, line ); } if ( match( line, "@/nextfile/" ) ) { y = year; m = month; p = part; p++; if ( p > 2 ) { p = 0; m++; if ( m > 12 ) { m = 1; y++; } } s = sprintf( "%04d%02d%s.html", y, m, PARTS[p] ); gsub( "@/nextfile/", s, line ); } do { if ( !match( line, "@[*]" ) ) { break; } FOOTNOTE_REFER++; s = sprintf( "%s%d", year, month, PARTS[part], date, FOOTNOTE_REFER, FOOTNOTEMARK, FOOTNOTE_REFER ); sub( "@[*]", s, line ); } while (!0); # ISBN output patch . 2000.11.6 by hachi@hauN.org do { pt = match( line, "@/isbn/[ \t]*[Xx0-9\-]*" ); if ( pt == 0 ) { break; } le = RLENGTH; s1 = substr( line, 1, pt-1 ); s = substr( line, pt, le ); s2 = substr( line, pt+le, length( line )-pt-le+1 ); isbn=s; sub( "@/isbn/[ \t]*", "", isbn ); isbn2=isbn; gsub( "-", "", isbn2 ); rep=REPLACEISBN; gsub( "@replace_isbn1", isbn, rep); gsub( "@replace_isbn2", isbn2, rep); gsub( "@/isbn/", "\\@/isbn/", rep); line = s1 rep s2; } while (!0); do { pt = match( line, "@/[^/]*/[^/]*/" ); if ( pt == 0 ) { break; } le = RLENGTH; s1 = substr( line, 1, pt-1 ); s = substr( line, pt, le ); s2 = substr( line, pt+le, length( line )-pt-le+1 ); # print "["s1"]", "["s"]", "["s2"]"; key = s; sub( "@/", "", key ); sub( "/[^/]*/", "", key ); # print "["key"]"; if ( !(key in REPLACE_Name) ) { # print "No Key [" key "]."; sub( "@", "\\@", s ); line = s1 s s2; continue; } name = s; sub( "@/[^/]*/", "", name ); sub( "/", "", name ); # print "["name"]"; if ( name == "" ) { name = REPLACE_Name[key]; } line = s1 ""name"" s2; } while (!0); return line; } ######################################################################## ### ファイル内容を置換しながらcat # function CatFile( fout, fin, year, month, part , line ) { while ( ( getline line 0 ) { sub( "\r", "", line ); print Replace( line, year, month, part, 0 )>fout; } close( fin ); } ######################################################################## ### 日付から旬を得る # function GetDiaryPart( year, month, date ,days, i ) { STARTDATE = 1; PART = 0; days = 10; if ( date >= STARTDATE+days ) { STARTDATE += days; PART++; } if ( date >= STARTDATE+days ) { STARTDATE += days; PART++; days++; # 31日 } ENDDATE = STARTDATE+days; YMD2DAYS( year, month, STARTDATE ); if ( ENDDATE > DAYS[month]+1 ) { ENDDATE = DAYS[month]+1; } } ######################################################################## ### ベースファイルを作成 # function BindDiaryBase( year, month, date ,startdate, enddate, part, i, fout, fout2, cmd, fin, line, needinterval ) { GetDiaryPart( year, month, date ); needinterval = 0; startdate = STARTDATE; enddate = ENDDATE; part = PART; fout = TMPDIR SLASH "%tmp1.out"; CatFile( fout, KEEPDIR SLASH BASEHEADERNAME, year, month, part ); PrintStart( fout ); for ( i=startdate; i 0 ) ) { close( fin ); if ( needinterval ) { PrintInterval( fout ); } PrintDiary( fout, year, month, i, part, 0 ); needinterval = !0; } } PrintTerminate( fout ); CatFile( fout, KEEPDIR SLASH BASEFOOTERNAME, year, month, part ); close( fout ); cmd = CHMODCMD " " fout; system( cmd ); fout2 = sprintf( PUTDIR SLASH "%04d%02d%s.html", year, month, PARTS[part] ); cmd = NKFCMD " " NKFCODE " " fout ">" fout2; # print cmd; system( cmd ); cmd = CHMODCMD " " fout2; system( cmd ); } ######################################################################## ### ダイジェストファイルを作成 # function BindDiaryDigest( totaldays , days, year, month, date, part, i, fout, fout2, cmd, fin, line, needinterval, istoday ) { needinterval = 0; fout = TMPDIR SLASH "%tmp2.out"; CatFile( fout, KEEPDIR SLASH DIGESTHEADERNAME, year, month, part ); CatFile( fout, KEEPDIR SLASH DIGESTPREMEMONAME, year, month, part ); PrintStart( fout ); for ( i=0; i 0 ) ) { close( fin ); if ( needinterval ) { PrintInterval( fout ); } istoday = 0; if ( i == 0 ) { istoday = 1; } PrintDiary( fout, year, month, date, part, istoday ); needinterval = !0; } } PrintTerminate( fout ); CatFile( fout, KEEPDIR SLASH DIGESTPOSTMEMONAME, year, month, part ); CatFile( fout, KEEPDIR SLASH DIGESTFOOTERNAME, year, month, part ); close( fout ); cmd = CHMODCMD " " fout; system( cmd ); fout2 = PUTDIR SLASH DIGESTNAME; cmd = NKFCMD " " NKFCODE " " fout ">" fout2; # print cmd; system( cmd ); cmd = CHMODCMD " " fout2; system( cmd ); } ######################################################################## ### テストファイルを作成 # function BindDiaryTest( totaldays , days, year, month, date, part, i, fout, fout2, cmd ) { fout = TMPDIR SLASH "%tmp2.out"; PrintStart( fout ); for ( i=0; i<1; i++ ) { days = totaldays-i; if ( days < 0 ) break; DAYS2YMD( days ); year = YEAR; month = MONTH; date = DATE; GetDiaryPart( year, month, date ); part = PART; PrintDiary( fout, year, month, date, part, 0 ); } PrintTerminate( fout ); close( fout ); fout2 = TMPDIR SLASH "test.html"; cmd = NKFCMD " " NKFCODE " " fout ">" fout2; # print cmd; system( cmd ); cmd = CHMODCMD " " fout2; system( cmd ); } ######################################################################## ### 月の日数を初期化 # function Setup_DAYS( year ) { DAYS[1] = 31; DAYS[2] = 28; DAYS[3] = 31; DAYS[4] = 30; DAYS[5] = 31; DAYS[6] = 30; DAYS[7] = 31; DAYS[8] = 31; DAYS[9] = 30; DAYS[10] = 31; DAYS[11] = 30; DAYS[12] = 31; if ( (((year%4) == 0) && ((year%100) != 0)) || ((year%400) == 0) ) { DAYS[2] = 29; } } ######################################################################## ### 年の日数を初期化 # function Setup_DAYS1( year ) { DAYS1 = 365; if ( (((year%4) == 0) && ((year%100) != 0)) || ((year%400) == 0) ) { DAYS1++; } } ######################################################################## ### 年月日から「1980/01/01からの積算日付」を求める # function YMD2DAYS( year, month, date ,days, i ) { if ( date < 1 ) { error_arg("date<1"); } Setup_DAYS( year ); days = DAYS[month]; if ( date > days ) { error_arg("date>end " date ">" days); } TOTALDAYS = 0; for ( i=1980; iSAT } ######################################################################## ### 「1980/01/01からの積算日付」から年月日を求める # function DAYS2YMD( totaldays ) { WDAY = (TOTALDAYS+2) % 7; # SUN->SAT for ( YEAR=1980; YEAR<2100; YEAR++ ) { Setup_DAYS1( YEAR ); if ( DAYS1 > totaldays ) { break; } totaldays -= DAYS1; } Setup_DAYS( YEAR ); for ( MONTH=1; MONTH<=12; MONTH++ ) { if ( DAYS[MONTH] > totaldays ) { break; } totaldays -= DAYS[MONTH]; } DATE = totaldays+1; } function error_arg(s) { print "error_arg " s; exit; } ######################################################################## ### 「最新更新日付」を読み出す # function ReadLastUpload( fin ) { fin = KEEPDIR SLASH LASTUPLOADNAME; while ( ( getline 0 ) { YEAR = $1; MONTH = $2; DATE = $3; } close( fin ); } ######################################################################## ### 「最新更新日付」を記録する # function WriteLastUpload( year, month, date ,fout, cmd ) { fout = KEEPDIR SLASH LASTUPLOADNAME; print year, month, date >fout; close( fout ); cmd = CHMODCMD " " fout; system( cmd ); } ######################################################################## ### BEGIN # BEGIN { Setup(); if ( ARGC < 4 ) { error_arg("4"); } if ( ARGC >= 5 ) { command = ARGV[4]; } year_today = ARGV[1]+0; month_today = ARGV[2]+0; date_today = ARGV[3]+0; if ( year_today < 1980 ) { error_arg("year<1980"); } if ( year_today > 2099 ) { error_arg("year>2099"); } if ( month_today < 1 ) { error_arg("month<1"); } if ( month_today > 12 ) { error_arg("month>12"); } LASTMODIFIED = strftime( LASTMODIFIEDFORMAT, systime() ); YEAR = 1980; MONTH = 1; DATE = 1; ReadLastUpload(); year_last = YEAR+0; month_last = MONTH+0; date_last = DATE+0; YMD2DAYS( year_today, month_today, date_today ); totaldays_today = TOTALDAYS; if ( command == "prev" ) { command = "test"; totaldays_today -= 1; } if ( command == "next" ) { command = "test"; totaldays_today += 1; } if ( command == "today" ) { command = "test"; } DAYS2YMD( totaldays_today ); year_today = YEAR+0; month_today = MONTH+0; date_today = DATE+0; YMD2DAYS( year_last, month_last, date_last ); totaldays_last = TOTALDAYS; if ( totaldays_last < totaldays_today ) { totaldays_last = totaldays_today; year_last = year_today; month_last = month_today; date_last = date_today; } Setup_PARTS(); Setup_ITEMS(); MakeReplaceDatabase( KEEPDIR SLASH REPLACENAME ); MakeReplaceISBN( KEEPDIR SLASH ISBNFNAME ); if ( command == "test" ) { BindDiaryTest( totaldays_today ); } else { WriteLastUpload( year_last+0, month_last+0, date_last+0 ); BindDiaryBase( year_today, month_today, date_today ); if ( (totaldays_last-totaldays_today) < DIGESTDAYS ) { BindDiaryDigest( totaldays_last ); } } } # [EOF]