تالار گفتگوی پارسی‌لاتک

عمومی => انجمن تازه‌کاران => نويسنده: danialbehzadi در آوریل 02, 2012, 09:18:58 pm

عنوان: عوض کردن رفتار بخشی از یک کلاس بدون تغییر فایل اصلی آن {حل شد}
رسال شده توسط: danialbehzadi در آوریل 02, 2012, 09:18:58 pm
سلام. چه طور می‌شه رفتار یه قسمت از کلاس رو عوض کرد، ولی خود فایل اصلی اون رو تغییر نداد؟
 مثلا من می‌خوام برای یک پروژه این بخش از کلاس ریپورت (report.cls)
\newcommand\chapter{\if@openright\cleardoublepage\else\clearpage\fi
                    \thispagestyle{plain}%
                    \global\@topnum\z@
                    \@afterindentfalse
                    \secdef\@chapter\@schapter}
\def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne
                         \refstepcounter{chapter}%
                         \typeout{\@chapapp\space\thechapter.}%
                         \addcontentsline{toc}{chapter}%
                                   {\protect\numberline{\thechapter}#1}%
                    \else
                      \addcontentsline{toc}{chapter}{#1}%
                    \fi
                    \chaptermark{#1}%
                    \addtocontents{lof}{\protect\addvspace{10\p@}}%
                    \addtocontents{lot}{\protect\addvspace{10\p@}}%
                    \if@twocolumn
                      \@topnewpage[\@makechapterhead{#2}]%
                    \else
                      \@makechapterhead{#2}%
                      \@afterheading
                    \fi}
\def\@makechapterhead#1{%
  \vspace*{50\p@}%
  {\parindent \z@ \raggedright \normalfont
    \ifnum \c@secnumdepth >\m@ne
        \huge\bfseries \@chapapp\space \thechapter
        \par\nobreak
        \vskip 20\p@
    \fi
    \interlinepenalty\@M
    \Huge \bfseries #1\par\nobreak
    \vskip 40\p@
  }}
رو با چینین چیزی عوض کنم
\newcommand\chapter{\if@openright\cleardoublepage\else\clearpage\fi
                    \thispagestyle{plain}%
                    \global\@topnum\z@
                    \@afterindentfalse
                    \secdef\@chapter\@schapter}
\def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne
                         \refstepcounter{chapter}%
                         \typeout{\@chapapp\space\thechapter.}%
                         \addcontentsline{toc}{chapter}%
                                   {\@chapapp\numberline{\thechapter:}#1}%
                    \else
                      \addcontentsline{toc}{chapter}{#1}%
                    \fi
                    \chaptermark{#1}%
                    \addtocontents{lof}{\protect\addvspace{10\p@}}%
                    \addtocontents{lot}{\protect\addvspace{10\p@}}%
                    \if@twocolumn
                      \@topnewpage[\@makechapterhead{#2}]%
                    \else
                      \@makechapterhead{#2}%
                      \@afterheading
                    \fi}
\def\@makechapterhead#1{%
  \thispagestyle{plain}%
  \if@twocolumn
    \onecolumn
    \@tempswatrue
  \else
    \@tempswafalse
  \fi
  \null\vfil
  {\centering
     \interlinepenalty \@M
     \normalfont
     \ifnum \c@secnumdepth >-2\relax
       \huge\bfseries \chaptername\nobreakspace\thechapter
       \par
       \vskip 20\p@
     \fi
     \Huge \bfseries #1\par}
     \newpage
     \vspace*{50\p@}%
     \par}
طوری که به بقیه‌ی پروژه‌ها دست نخوره.
عنوان: پاسخ : عوض کردن رفتار بخشی از یک کلاس بدون تغییر فایل اصلی آن
رسال شده توسط: وحید دامن‌افشان در آوریل 03, 2012, 01:23:07 am
**اگه تغییراتی  که می‌خواین توی یه کلاس انجام بدین، کم باشه، می‌تونین این تغییرات رو توی  preamble  فایل اصلی‌تون قرار بدین. در ضمن، اگه حفظ نظم فایل اصلی‌تون براتون اهمیت داره، می‌تونین مثل قالب پایان‌نامه (http://www.parsilatex.com/joomla/index.php?option=com_content&view=article&id=71:1388-08-29-22-40-34&catid=41:1388-06-28-10-27-50&Itemid=74) من، یه فایل تک مثل commands درست کنین و این تغییرات رو توش قرار بدین و بعدش اونو با دستور input توی فایل اصلی‌تون فراخوانی کنین. نکته‌ای که باید بهش دقت کنین اینه که اگه دستوری توی یه کلاس با \newcommad شروع شده، هنگام تغییر باید اونو به \renewcommand تغییر بدین چون در غیر این صورت، با خطای «این دستور از قبل تعریف شده است» مواجه می‌شین. اما  دستوراتی که با \def شروع می‌شن، اینطور نیستن. چون اگه دستوری رو با \def تعریف کنین، TeX بدون توجه به اینکه آیا این دستور از قبل وجود داشته یا نه، تعریف شمارو جایگزین تعریف قبل می‌کنه. به عبارت دیگه، تک دیگه اهمیت نمی‌ده که آیا دستور شما از قبل تعریف شده یا نه و بنابراین دیگه با خطای بالا مواجه نمی‌شین.
نکته دیگه‌ای که باید بهش توجه کنین اینه که اگه می‌خواین دستوراتی که داخلشون از کاراکتر @ استفاده شده، رو تغییر بدین، باید اونا رو بین دو دستور
‎\makeatletter‎
...
‎‎\makeatother‎‎
قرار بدین. مثلاً در مورد تغییرات شما، چون از کاراکتر @ استفاده شده، باید اولش دستور ‎\makeatletter‎ و آخرش، دستور ‎‎\makeatother‎‎ رو قرار بدین و حالا همه رو قبل از ‎\begin{document}‎ قرار بدین. در ضمن یادتون نره که دستور \newcommand رو هم به  \renewcommand تغییر بدین.

** اما اگه تغییراتی که می‌خواین توی یه کلاس انجام بدین، زیاد هستش (مثلاً ۵۰٪ به بالا)، به نظر من بهتره که قبل از هر چی، فایل کلاس رو داخل پوشه‌ای که فایل اصلیتون قرار داره، کپی کنی و بعدش تغییرات رو توی همین فایل انجام بدی و بعدش (بخاطر رعایت کردن قوانین مجوز LPPL) اسمشو مثلاً به myreport تغییر بدین و بعدش توی فایل اصلی بجای دستور ‎\documentclass{report}‎ از دستور ‎\documentclass{myreport}‎ استفاده کنین.
نکته دیگه‌ای که بد نیست بدونین اینه که زمانی که از کلاس یا بسته خاصی توی فایل اصلی‌تون استفاده می‌کنین، TeX ابتدا توی همون پوشه‌ خودتون دنبال فایل اون کلاس یا بسته می‌گرده و اگه پیداش نکنه، میره سراغ پوشه‌ای که توزیع تک‌تون اونجا نصب شده. ضمناً همیشه اولویت با پوشه خودتون هستش. یعنی اگه  توی پوشه خودتون و توی پوشه توزیع‌ تک‌تون، یه  فایل همنام با پسوند sty وجود داشته باشه، TeX فقط محتویات فایلی که توی پوشه خودتون هستش رو می‌خونه و کاری با فایل داخل توزیع تک نداره.
امیدوارم که جواب سوال‌تون رو گرفته باشین‎.‎
عنوان: پاسخ : عوض کردن رفتار بخشی از یک کلاس بدون تغییر فایل اصلی آن
رسال شده توسط: danialbehzadi در آوریل 03, 2012, 01:48:55 am
بله. خیلی ممنون. خودم هم تو این فاصله یه کارهایی کردم. ولی مشکل اصلی همون makeatletter\ و makeatother\ بودن که خوشبختانه درست شد.