diff --git a/cs_capstone_documents/spring_final_report/01-introduction/introduction.tex b/cs_capstone_documents/spring_final_report/01-introduction/introduction.tex new file mode 100644 index 0000000..87c45ea --- /dev/null +++ b/cs_capstone_documents/spring_final_report/01-introduction/introduction.tex @@ -0,0 +1,30 @@ +\section{Introduction} +\subsection{Who Requested the Project?} +This project was requested by the Oregon State University Robotics Club's (OSURC) Mars Rover team. + +\subsection{Why Was the Project Requested?} +This project was requested due to the Mars Rover team's need for a complete and functional ground station in a time frame that the existing software team may not have been able to accomplish. Additionally, new requirements for the ground station meant that the increased complexity was most likely going to require a more dedicated team to complete than the volunteers the club normally has working on the Mars Rover project. + +\subsection{What is the Importance of the Project?} +This project solves some of the most common problems for the Mars Rover team in previous competition years. Historically, the team is allowed a 10-15 minute set up time during competition where the Rover must be turned on, ground station connected, and core systems tested before actually competing in a task. In previous years, the Rover's ground station has normally been a laptop with a handful of random pieces of hardware plugged into it over USB. Many times, this hardware has been damaged during transit and caused problems during the setup phase. Additionally, previous software has often been command line driven and extremely specialized meaning the software is difficult to use, difficult to teach, and has ended up getting re-written with each new Rover competition year. + +\subsection{Our Client and Their Role} +Our client was Nick McComb, team lead and electrical lead of the Mars Rover team for the 2017-2018 competition year. His role was mainly supervisory, helping our group set up the initial requirements for the software, and occasionally making requests for additional features as the year progressed. + +\subsection{Our Team Members and Roles} +\begin{itemize} +\item Chris Pham + \begin{itemize} + \item Rover mapping systems + \end{itemize} +\item Ken Steinfeldt + \begin{itemize} + \item Rover status systems + \end{itemize} +\item Corwin Perren + \begin{itemize} + \item Team Manager + \item Rover video systems + \item Program structure / startup + \end{itemize} +\end{itemize} diff --git a/cs_capstone_documents/spring_final_report/02-requirementsdoc/cs_group30_design_requirements_revision1_1.pdf b/cs_capstone_documents/spring_final_report/02-requirementsdoc/cs_group30_design_requirements_revision1_1.pdf new file mode 100644 index 0000000..0983082 Binary files /dev/null and b/cs_capstone_documents/spring_final_report/02-requirementsdoc/cs_group30_design_requirements_revision1_1.pdf differ diff --git a/cs_capstone_documents/spring_final_report/02-requirementsdoc/final_gantt.pdf b/cs_capstone_documents/spring_final_report/02-requirementsdoc/final_gantt.pdf new file mode 100644 index 0000000..f816298 Binary files /dev/null and b/cs_capstone_documents/spring_final_report/02-requirementsdoc/final_gantt.pdf differ diff --git a/cs_capstone_documents/spring_final_report/02-requirementsdoc/group-design-requirements.pdf b/cs_capstone_documents/spring_final_report/02-requirementsdoc/group-design-requirements.pdf new file mode 100644 index 0000000..1ce7299 Binary files /dev/null and b/cs_capstone_documents/spring_final_report/02-requirementsdoc/group-design-requirements.pdf differ diff --git a/cs_capstone_documents/spring_final_report/02-requirementsdoc/requirementsdoc.tex b/cs_capstone_documents/spring_final_report/02-requirementsdoc/requirementsdoc.tex new file mode 100644 index 0000000..6f5c6d8 --- /dev/null +++ b/cs_capstone_documents/spring_final_report/02-requirementsdoc/requirementsdoc.tex @@ -0,0 +1,97 @@ +\section{Requirements Document} +\subsection{Original Document} +\includepdf[pages=-, frame=true, scale=0.95]{02-requirementsdoc/group-design-requirements.pdf} + +\subsection{Additions} +\subsubsection{Final Revision Document} +\includepdf[pages=-, frame=true, scale=0.95]{02-requirementsdoc/cs_group30_design_requirements_revision1_1.pdf} + +\subsubsection{Description of Changes} +Version 1.1 of document was approved by all team members and stakeholder on 4/26/2018. + +\begin{itemize} +\item Edited descriptions of competition from University Rover Challenge to Canadian International Rover Challenge + \begin{itemize} + \item The Mars Rover team changed competitions, so we updated the document to reflect this + \end{itemize} + +\item Removed user story for manual video quality adjustment + \begin{itemize} + \item Our team implemented automatic quality adjustment, so manual adjustment was no longer necessary + \end{itemize} + +\item Removed user story about easily seeing when an autonomous run has completed + \begin{itemize} + \item The new Rover competition does not require this display element + \end{itemize} + +\item Removed user story about needing to view live logs + \begin{itemize} + \item Log viewing was determined to not be needed as there would be too many logs to sort through in a short amount of time + \end{itemize} + +\item Removed user story about seeing network latency (round trip time) + \begin{itemize} + \item The network connection percentage was determined to be correlated with this value enough that this redundant element was not needed + \end{itemize} + +\item Added constraint that the GUI software must have placeholder for GUI elements and software features that can not be completed due to waiting on Rover team progress + \begin{itemize} + \item Our team encountered many situations where we could not continue development due to lack of hardware/software on Rover + \item This new constraint allows us to still meet requirements if the bottleneck is the Rover team + \end{itemize} + +\item Changed functional requirement for joystick statuses so that the SpaceNav mouse had its own requirement + \begin{itemize} + \item The team changed to a SpaceNav mouse earlier in the year and it was determined that an individual readout for this input device would be convenient + \end{itemize} + +\item Changed functional requirement for battery status to battery voltage + \begin{itemize} + \item The battery status value was determined to be most useful as a voltage, rather than a percentage estimate + \end{itemize} + +\item Removed functional requirement for Rover voltage statuses + \begin{itemize} + \item The Rover design changed so that only the battery voltage is measured + \end{itemize} + +\item Changed functional requirement for bogie connection statuses to be individual wheel statuses + \begin{itemize} + \item The Rover software team got individual status information for each wheel, rather than a two wheel bogie group, and requested this change + \end{itemize} + +\item Removed functional requirement for Rover network round trip time + \begin{itemize} + \item The network connection percentage was determined to be correlated with this value enough that this redundant element was not needed + \end{itemize} + +\item Changed functional requirement for Rover arm joystick control to SpaceNav mouse control + \begin{itemize} + \item The team changed to a SpaceNav mouse over a second joystick for arm control + \end{itemize} + +\item Removed functional requirement for way-point navigation path + \begin{itemize} + \item Expectations for how autonomy on the Rover would work would not easily give our team this information to display + \end{itemize} + +\item Changed functional requirement for the autonomy indicator so that it shows whether autonomy is active rather than when autonomy is finished + \begin{itemize} + \item Changing to the Canadian International Rover Challenge made the old requirement unnecessary + \end{itemize} + +\item Removed functional requirement for video FPS counters + \begin{itemize} + \item FPS counters would have been useful for manual video quality adjustment, but are no longer needed with automatic quality adjustment + \end{itemize} + +\item Removed functional requirement for log file viewing + \begin{itemize} + \item Log files were too large to usefully sort through in a short amount of time + \end{itemize} + +\end{itemize} + +\subsection{Final Gantt Chart} +\includepdf[pages=-, frame=true, landscape, scale=0.95]{02-requirementsdoc/final_gantt.pdf} \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/03-designdoc/designdoc.tex b/cs_capstone_documents/spring_final_report/03-designdoc/designdoc.tex new file mode 100644 index 0000000..a91b546 --- /dev/null +++ b/cs_capstone_documents/spring_final_report/03-designdoc/designdoc.tex @@ -0,0 +1,5 @@ +\section{Design Document} +\subsection{Original Document} +\includepdf[pages=-, frame=true, scale=0.95]{03-designdoc/group-design-document.pdf} +\subsection{Additions} +There were no additions to our original design document. \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/03-designdoc/group-design-document.pdf b/cs_capstone_documents/spring_final_report/03-designdoc/group-design-document.pdf new file mode 100644 index 0000000..34f3324 Binary files /dev/null and b/cs_capstone_documents/spring_final_report/03-designdoc/group-design-document.pdf differ diff --git a/cs_capstone_documents/spring_final_report/04-techreviewdocs/chris.tex b/cs_capstone_documents/spring_final_report/04-techreviewdocs/chris.tex new file mode 100644 index 0000000..7479ef8 --- /dev/null +++ b/cs_capstone_documents/spring_final_report/04-techreviewdocs/chris.tex @@ -0,0 +1,2 @@ +\subsubsection{Chris Pham} +\includepdf[pages=-, frame=true, scale=0.95]{04-techreviewdocs/phamchr-tech-review.pdf} \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/04-techreviewdocs/corwin.tex b/cs_capstone_documents/spring_final_report/04-techreviewdocs/corwin.tex new file mode 100644 index 0000000..c5da739 --- /dev/null +++ b/cs_capstone_documents/spring_final_report/04-techreviewdocs/corwin.tex @@ -0,0 +1,2 @@ +\subsubsection{Corwin Perren} +\includepdf[pages=-, frame=true, scale=0.95]{04-techreviewdocs/tech_review_perrenc.pdf} \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/04-techreviewdocs/ken.tex b/cs_capstone_documents/spring_final_report/04-techreviewdocs/ken.tex new file mode 100644 index 0000000..8e04974 --- /dev/null +++ b/cs_capstone_documents/spring_final_report/04-techreviewdocs/ken.tex @@ -0,0 +1,2 @@ +\subsubsection{Ken Steinfeldt} +\includepdf[pages=-, frame=true, scale=0.95]{04-techreviewdocs/steinfek-tech-report.pdf} \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/04-techreviewdocs/phamchr-tech-review.pdf b/cs_capstone_documents/spring_final_report/04-techreviewdocs/phamchr-tech-review.pdf new file mode 100644 index 0000000..6e9b45f Binary files /dev/null and b/cs_capstone_documents/spring_final_report/04-techreviewdocs/phamchr-tech-review.pdf differ diff --git a/cs_capstone_documents/spring_final_report/04-techreviewdocs/steinfek-tech-report.pdf b/cs_capstone_documents/spring_final_report/04-techreviewdocs/steinfek-tech-report.pdf new file mode 100644 index 0000000..f84f84e Binary files /dev/null and b/cs_capstone_documents/spring_final_report/04-techreviewdocs/steinfek-tech-report.pdf differ diff --git a/cs_capstone_documents/spring_final_report/04-techreviewdocs/tech_review_perrenc.pdf b/cs_capstone_documents/spring_final_report/04-techreviewdocs/tech_review_perrenc.pdf new file mode 100644 index 0000000..ad92c8f Binary files /dev/null and b/cs_capstone_documents/spring_final_report/04-techreviewdocs/tech_review_perrenc.pdf differ diff --git a/cs_capstone_documents/spring_final_report/04-techreviewdocs/techreviewdocs.tex b/cs_capstone_documents/spring_final_report/04-techreviewdocs/techreviewdocs.tex new file mode 100644 index 0000000..619232c --- /dev/null +++ b/cs_capstone_documents/spring_final_report/04-techreviewdocs/techreviewdocs.tex @@ -0,0 +1,5 @@ +\section{Tech Review Document} +\subsection{Original Documents} +\input{04-techreviewdocs/chris} +\input{04-techreviewdocs/ken} +\input{04-techreviewdocs/corwin} diff --git a/cs_capstone_documents/spring_final_report/05-blogposts/blogposts.tex b/cs_capstone_documents/spring_final_report/05-blogposts/blogposts.tex new file mode 100644 index 0000000..219b410 --- /dev/null +++ b/cs_capstone_documents/spring_final_report/05-blogposts/blogposts.tex @@ -0,0 +1,4 @@ +\section{Individual Blog Posts} +\input{05-blogposts/chris} +\input{05-blogposts/ken} +\input{05-blogposts/corwin} \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/05-blogposts/chris.tex b/cs_capstone_documents/spring_final_report/05-blogposts/chris.tex new file mode 100644 index 0000000..9e098b7 --- /dev/null +++ b/cs_capstone_documents/spring_final_report/05-blogposts/chris.tex @@ -0,0 +1,448 @@ +\subsection{Chris Pham} +\subsubsection{Fall} +\begin{itemize} +\item Week 1 +\begin{itemize} +\item Activities +\begin{itemize} +\item Talked to the client to see if I can get into the OSURC Project +\end{itemize} +\item Summary +\begin{itemize} +\item I went ahead and looked through projects and then found a project that I liked, and then I emailed the stakeholder, Nick McComb, into adding me into his project. +\end{itemize} +\end{itemize} +\item Week 2 +\begin{itemize} +\item Activities +\begin{itemize} +\item Emailed client when deciding to meet +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Client happened to be in California +\end{itemize} +\item Summary +\begin{itemize} +\item After being given our projects, we emailed our client and talked to our client over Slack to decide when to do our meeting about the project. We decided on Sunday for meeting up, while we think about the time schedule for the next assignments. +\end{itemize} +\end{itemize} +\item Week 3 +\begin{itemize} +\item Activities +\begin{itemize} +\item Finishing Problem Statement +\item Started on Python Mastery 1 +\end{itemize} +\item Summary +\begin{itemize} +\item I started working on my personal Problem Statement and was told from our client that we should do the Python Masteries. The client wanted to use it to prove that someone has enough understanding of the subject. +\end{itemize} +\end{itemize} +\item Week 4 +\begin{itemize} +\item Activities +\begin{itemize} +\item Finished Problem Statement +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Python Mastery 1 is taking forever +\item Looking into alternatives to Code Academy. +\end{itemize} +\item Summary +\begin{itemize} +\item We worked on our collaborated Problem Statement and I started work on the Python 1 Mastery as suggested, but the actual website is expecting us to be completely new to coding. So in the end, I stopped because I was suffering while doing it. +\end{itemize} +\end{itemize} +\item Week 5 +\begin{itemize} +\item Activities +\begin{itemize} +\item Start on rough draft of the Requirements Document +\item Finished the draft, and it is uploaded to GitHub +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Ended up being sick +\item Could not finish the mastery program yet +\end{itemize} +\item Summary +\begin{itemize} +\item We worked on our rough draft of the Requirements Document and that is now submitted to GitHub. Client was wanting some changes on the Problem Statement, but we changed the document to reflect those changes. +\end{itemize} +\end{itemize} +\item Week 6 +\begin{itemize} +\item Activities +\begin{itemize} +\item Finish the final draft of the Requirements Document +\item Sent to client for approval +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Issues with making the Gantt chart +\item Might need to start coding soon because the Mechanical team needs code +\end{itemize} +\item Summary +\begin{itemize} +\item We finished the Requirement Document and now I am thinking we are going to start on the project soon because we need to build parts of it for the mechanical engineering capstone group. +\end{itemize} +\end{itemize} +\item Week 7 +\begin{itemize} +\item Activities +\begin{itemize} +\item Divide up the section of the Tech Review Document into coherent sections +\end{itemize} +\item Summary +\begin{itemize} +\item After submitting our assignment last week about the Requirements document, we went ahead after our meeting to build our skeleton for the tech review. After build that, I could not do anything else because was finishing other homework and plan on starting more of the assignment during the weekend. +\end{itemize} +\end{itemize} +\item Week 8 +\begin{itemize} +\item Activities +\begin{itemize} +\item Finish up rough draft of Tech Review Document +\item Gave our document to other people to review +\end{itemize} +\item Summary +\begin{itemize} +\item On Monday, I went ahead a my rough draft for the personal tech review. Then on Tuesday, we went ahead and reviewed someone else's document and got ours back on Thursday. Will probably finish final draft on Sunday. +\end{itemize} +\end{itemize} +\item Week 9 +\begin{itemize} +\item Activities +\begin{itemize} +\item Finished final draft of Tech Review Document +\item Design document going to be started soon after +\end{itemize} +\item Summary +\begin{itemize} +\item On Monday, went and finished most of my tech review substance wise. On Tuesday, went ahead and tried to make it more readable. +\end{itemize} +\end{itemize} +\item Week 10 +\begin{itemize} +\item Activities +\begin{itemize} +\item Finish working on Design Document in parts +\item Finish working on recording +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Everything ended up being due on Friday +\item Had to save this for last +\end{itemize} +\item Summary +\begin{itemize} +\item We started working on our design document on Thursday and then completed most of it during Friday because of lack of time and things like that. The video was done around that time too, couldn't do it in my house early in the day because of noises. +\end{itemize} +\end{itemize} +\end{itemize} +\subsubsection{Winter} +\begin{itemize} +\item{Week 1} +\begin{itemize} +\item Activities +\begin{itemize} +\item Created a working schedule because we have to work on campus for direct access +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item When thinking about implementing my area, was thinking of live tiling, or pre-stitched image after. +\end{itemize} +\item Summary +\begin{itemize} +\item After everyone got back from break, after class on Tuesday, we make a work schedule for us to work on the Rover. I was assigned the Mapping functionality of the ground station and some of the design decisions are up to me to choose. +\end{itemize} +\end{itemize} +\item{Week 2} +\begin{itemize} +\item Activities +\begin{itemize} +\item Start on turning last year's code into Object-oriented instead of procedural for ROS +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Issues with big functions and converting them into stateful functions +\item Issues with downloading and speed of combining images into a single image +\end{itemize} +\item Summary +\begin{itemize} +\item I started on working the mapping core but I need to make the UI element and then try to make some speed improvements against PIL +\end{itemize} +\end{itemize} +\item{Week 3} +\begin{itemize} +\item Activities +\begin{itemize} +\item Working on adjusting maps in ways (Zoom/Scaling, Movement) +\item A smaller image can be cut out of the bigger image now +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item PIL zoom does not work like I expected, might have to use QT's zoom +\end{itemize} +\item Summary +\begin{itemize} +\item Mapping is working mostly now with now a moving bounding box that goes in the big image and cuts what is needed. +\end{itemize} +\end{itemize} +\item{Week 4} +\begin{itemize} +\item Activities +\begin{itemize} +\item Map stitching works up to 3 miles before skew happens +\item Got items to place correctly onto the map and display correctly +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Somehow got issues with converting latitude and longitude into x, y coordinates gave me extreme values but got solved by pasting it again with a different name... +\item I was not able to do much work during the week because of the issue above +\end{itemize} +\item Summary +\begin{itemize} +\item In the end, I got mapping to work correctly to around 3 miles before my projection becomes skewed enough to become really inaccurate. I also got a way to map waypoints to a system, however that is my next problem because I actually have no way of removing them from the map itself. I think I might make another image to lay on top of the map and then clear out the box by doing the same command but making it transparent instead of coloring it. +\end{itemize} +\end{itemize} +\item{Week 5} +\begin{itemize} +\item Activities +\begin{itemize} +\item Implemented my mapping to work with the Qt interface +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Had issues with signals and slots for my listener because it would stall out when trying to paste the image, had to create another thread to handle that. +\item Had slight issues with trying to merge my branch because the repository's folder structure had changed so much +\end{itemize} +\item Summary +\begin{itemize} +\item This week I was trying to setup my class to properly implement with my Qt Application. That was real questionable but I think I can fix it using some type of class constructor call in an Qobject instead of instantiating it from the map object itself. Another thing I did was integrated my fork/branch into the main branch and it looks way better now. Feels pretty good actually. +\end{itemize} +\end{itemize} +\item{Week 6} +\begin{itemize} +\item Activities +\begin{itemize} +\item Worked on displaying the map correctly without massive hangups +\item Worked on our capstone paper and video +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Issues with scheduling for working, but in the end we worked on our own mostly and then worked online when we needed to. +\end{itemize} +\item Summary +\begin{itemize} +\item Worked on the poster, video, and displaying images on the GUI. Productive I say. +\end{itemize} +\end{itemize} +\item{Week 7} +\begin{itemize} +\item Activities +\begin{itemize} +\item Nothing +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Was way too busy with midterms +\end{itemize} +\item Summary +\begin{itemize} +\item I did nothing at all. Feels bad man. +\end{itemize} +\end{itemize} +\item{Week 8} +\begin{itemize} +\item Activities +\begin{itemize} +\item Worked on some GPS/Waypoint handling for the map +\item Helped with recording for the club +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Overlay not working correctly, need to fix paste functionality +\end{itemize} +\item Summary +\begin{itemize} +\item Worked on the GPS and waypoint system, and for the club itself, I helped with filming and recording for the system reviews report needed. +\end{itemize} +\end{itemize} +\item{Week 9} +\begin{itemize} +\item Activities +\begin{itemize} +\item Worked on an correctly producing my indicator +\item Fixed on pasting the overlay image +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Was busy during Monday-Wends with plumber issues needing me to be home +\end{itemize} +\item Summary +\begin{itemize} +\item Fixed up my mapping and started working on integrating a waypoint system +\end{itemize} +\end{itemize} +\item{Week 10} +\begin{itemize} +\item Activities +\begin{itemize} +\item Built a intermediate system to handle button presses for way-point lists. +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item QT is really finicky with some function names and changes from Qt4 to Qt5 made some things harder to find +\end{itemize} +\item Summary +\begin{itemize} +\item During the start of the term, I personally did not work on much because of issues with registration +However, we did work out when we are expecting to work and meet up this term, which would be on Thursdays around 10 o'clock in the morning. +\end{itemize} +\end{itemize} +\end{itemize} +\subsubsection{Spring} +\begin{itemize} +\item Week 1 +\begin{itemize} +\item Activities +\begin{itemize} +\item Meet up with the group to plan meetup times +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Issues in trying to get into classes +\end{itemize} +\item Summary +\begin{itemize} +\item After meeting up and trying to find +\end{itemize} +\end{itemize} +\item Week 2 +\begin{itemize} +\item Activities +\begin{itemize} +\item Finish integrating the GUI elements like buttons +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Issues with DMS conversions +\end{itemize} +\item Summary +\begin{itemize} +\item This week, I worked on completing the integration of the GUI. It turned out last term, that the East/West portion of the DMS conversion was not being set correctly. I spent a bit of time trying to get the correct float value to go down but then my minutes was completely off to the calculated DMS of the GPS location. Turns out that the box that contained the DMS location, would be limited to 0, 90, which actually needs to be 180 because it needs to span a half circle. Once that value was changed, the values were being set correctly. +\end{itemize} +\end{itemize} +\item Week 3 +\begin{itemize} +\item Activities +\begin{itemize} +\item Finish up linking up buttons and interactions in the GUI +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item More issues with trying to get into the negative values of the DMS portion +\end{itemize} +\item Summary +\begin{itemize} +\item Turns out that I forgot to set the sign of the longitude and latitude to their corresponding North/South and East/West values. That was easily done using with many possible implementations like equalities, sign function in python, and other things like that. +\end{itemize} +\end{itemize} +\item Week 4 +\begin{itemize} +\item Activities +\begin{itemize} +\item Finish up and submitting the poster +\item Edit documents to fit new the new competition +\end{itemize} +\item Summary +\begin{itemize} +\item This week, I was too busy to actually do much, and instead we worked on updating our documents to the new competition that we're going to now. And when that was done, we all just signed it and gave it to our client to sign. Also finished poster and it was sent to student media services. +\end{itemize} +\end{itemize} +\item Week 5 +\begin{itemize} +\item Activities +\begin{itemize} +\item Finish working on multithreading and inputs. +\item Work on Midterm Report +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Was getting rate limited, needed to use a semaphore to limit thread usage. +\end{itemize} +\item Summary +\begin{itemize} +\item During Week 5, I worked on two important things, multi-threading the downloading of the image files from Google and integration of inputs into my mapping system. I was hitting issues with trying to use a pool but could not do it, in the end I needed to use processes. This in the ended up needing to be limited with semaphores so downloads could be regulated. +\item I also have started on integrating the GPS data that we are getting and applying that onto the map system that I've created. One problem is I forget how the data is formatted in the system and I need direct access to view the data that is being sent by the rover to parse correctly. +\end{itemize} +\end{itemize} +\item Week 6 +\begin{itemize} +\item Activities +\begin{itemize} +\item Did not plan to do anything for Capstone at all. +\end{itemize} +\item Summary +\begin{itemize} +\item Did not do anything pertaining to Capstone at all. +\end{itemize} +\end{itemize} +\item Week 7 +\begin{itemize} +\item Activities +\begin{itemize} +\item Present at Expo +\item Hunt for items that we need for Expo +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item Someone actually destroyed some motor nodes, so only 4 or the 6 wheel positions only move. +\item Corwin in the end, converted the connectors to USB and then connected those via USB. +\end{itemize} +\item Summary +\begin{itemize} +\item We met up on Thursday to find out what we actually need for Expo and what will be provided for Expo or not. It turned out that a Electrical team member blew a series of driver nodes, and had to build something to replace it. One method was making an emulator, or just run a newer number of nodes if the complete system cannot boot. It only turned out the controller boards only got fried, and so it had to get rigged to run off of USB. The day of Expo, we went to our position, and realized that we only had one table shared with the other Mars Rover Team Capstone project, and had to find the coordinator to get us another table. That was resolved, and then we went ahead and got all the stuff from the club room, and brought it to our table and presented. +\end{itemize} +\end{itemize} +\item Week 8 +\begin{itemize} +\item Activities +\begin{itemize} +\item Nothing at all +\end{itemize} +\item Problems / Solutions +\begin{itemize} +\item With nothing working correctly, because of the blown electronics, other interfaces could not be used like the GPS information. +\end{itemize} +\item Summary +\begin{itemize} +\item Nothing could be done, with the lack of integrating parts from the rest of the rover team. +\end{itemize} +\end{itemize} +\item Week 9 +\begin{itemize} +\item Activities +\begin{itemize} +\item Nothing at all +\end{itemize} +\item Summary +\begin{itemize} +\item Did nothing, because of other homework assignments taking my time. +\end{itemize} +\end{itemize} +\item Week 10 +\begin{itemize} +\item Activities +\begin{itemize} +\item Started and finished the final video report and started on the final paper. +\end{itemize} +\item Summary +\begin{itemize} +\item We started our video on Thursday and finished on Friday, and then started working on this paper over the weekend. We are expecting to finish this whole document around Tuesday afternoon. +\end{itemize} +\end{itemize} +\end{itemize} \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/05-blogposts/corwin.tex b/cs_capstone_documents/spring_final_report/05-blogposts/corwin.tex new file mode 100644 index 0000000..043f0b6 --- /dev/null +++ b/cs_capstone_documents/spring_final_report/05-blogposts/corwin.tex @@ -0,0 +1,590 @@ +\subsection{Corwin Perren} +\subsubsection{Fall} +\begin{itemize} +\item Week 1 + \begin{itemize} + \item Week 1.3 + \begin{itemize} + \item Looked at and selected projects for my preference submission. + \end{itemize} + + \item Summary + \begin{itemize} + \item Looked through potential projects and submitted project preferences. I also contacted and got a positive confirmation from Nick McComb, the stakeholder for the OSURC Mars Rover capstone project, that myself and Christopher Pham were requested to work on the project via an email to McGrath. + \end{itemize} + \end{itemize} + +\item Week 2 + \begin{itemize} + \item Week 2.2 + \begin{itemize} + \item Took class notes + \end{itemize} + \item Week 2.3 + \begin{itemize} + \item Group wrote an email to send to our client, Nick + \item Sent said email to Nick + \end{itemize} + \item Week 2.7 + \begin{itemize} + \item Had a meeting with Nick McComb, Kenneth, and Chris to covered the design guidelines document + \end{itemize} + + \item Summary + \begin{itemize} + \item Met with group members Chris and Kenneth, where we exchanged contact information and coordinated contacting our client to set up a meeting. We made contact and set up a video conference call for Sunday to cover project details. We also were added to the rover team's slack, which we'll use for primary communication in the future. For future use, we were also added to the club's GitHub account. + \end{itemize} + \end{itemize} + +\item Week 3 + \begin{itemize} + \item Week 3.1 + \begin{itemize} + \item Worked on and completed the rough draft problem statement + \item Did some initial research on the tools and frameworks our team will be using for this project + \end{itemize} + \item Week 3.2 + \begin{itemize} + \item Started communication as a group with our TA to set up a weekly meeting time. + \end{itemize} + + \item Summary + \begin{itemize} + \item After communicating with our client on Sunday, I took Sunday night and Monday to work on and complete the problem statement document. I also began to look more into the tools and frameworks we will be using on this project. Our group also started emailing our TA, Andrew, to set up a weekly meeting time, which is still not set in stone as Andrew is having a hard time scheduling so many groups at once. So far, it looks like they'll probably be on Tuesday afternoons as a remote session. + \end{itemize} + \end{itemize} + +\item Week 4 + \begin{itemize} + \item Week 4.4 + \begin{itemize} + \item Made revisions to the problem statement document + \end{itemize} + \item Week 4.5 + \begin{itemize} + \item Uploaded the final version of the document to the Github rep + \item Emailed client asking for revisions, and an approval email once ready + \item Embedded PDF in the group OneNote + \end{itemize} + + \item Summary + \begin{itemize} + \item Our group used overleaf to group edit a join problem statement document, made revisions, and then emailed our client the final version. We're currently waiting for the approval email. I also embedded our PDF into the group OneNote per the follow-up email from Kirsten + \end{itemize} + \end{itemize} + +\item Week 5 + \begin{itemize} + \item Week 5.2 + \begin{itemize} + \item Had TA Meeting + \end{itemize} + \item Week 5.4 + \begin{itemize} + \item Worked on design requirements document with Chris and Ken + \end{itemize} + + \item Summary + \begin{itemize} + \item We had a general meeting with our TA, the first of the term. Covered what the TA's role will be in our group. Covered that we seem to have a good plan on what our group will be doing. On Thursday, worked on the design requirements rough draft. + \end{itemize} + \end{itemize} + +\item Week 6 + \begin{itemize} + \item Week 6.2 + \begin{itemize} + \item Had an update meeting with the TA + \end{itemize} + \item Week 6.3 + \begin{itemize} + \item Worked on design requirements document with Chris and Ken + \end{itemize} + \item Week 6.4 + \begin{itemize} + \item Continued working on design requirements document with Chris and Ken + \item Sent the semi-final draft to the client for potential edits + \end{itemize} + \item Week 6.5 + \begin{itemize} + \item Made client edits to requirements document + \item Sent approval request email to client + \end{itemize} + + \item Summary + \begin{itemize} + \item We had a general meeting with our TA and otherwise spent the week working on our requirements document. We sent a semi-final draft to our client Nick, who requested some minor edits, which we made and then sent him a final draft for approval. + \end{itemize} + \end{itemize} + +\item Week 7 + \begin{itemize} + \item Week 7.2 + \begin{itemize} + \item Decided on projects to work on + \item Had TA meeting + \end{itemize} + \item Week 7.4 + \begin{itemize} + \item Set up the ground station hardware in Graf 306 + \end{itemize} + + \item Summary + \begin{itemize} + \item Last week, we had a short quick meeting with our TA and then worked with each other to determine who would take what technologies for the tech review document. On Thursday, I set up the hardware our team will be running the ground station on set up in Graf 306. This included an Intel NUC, two joysticks, and two 1080p monitors. For now, it's connected via and ethernet switch to a desktop emulating the Rover. + \end{itemize} + \end{itemize} + +\item Week 8 + \begin{itemize} + \item Week 8.1 + \begin{itemize} + \item Worked on rough draft for the tech review document + \end{itemize} + \item Week 8.2 + \begin{itemize} + \item Did peer revisions on tech review documents in class + \item Turned in tech review + \item Met with TA + \end{itemize} + \item Week 8.5 + \begin{itemize} + \item Worked on setting up the ROS framework on ground station software + \item Got simple rover drive control data sending to the rover + \item Got three video streams showing on the gui from the rover + \end{itemize} + + \item Summary + \begin{itemize} + \item Last week, I finished my peer review, did an in class peer review, and turned it in. Our group also had another short meeting with our TA to make sure we were doing fine. On Friday, I began writing some initial ground station code. I got simple rover drive data sending over the network to the Rover. I also got three camera streams displaying in the GUI. + \end{itemize} + \end{itemize} + +\item Week 9 + \begin{itemize} + \item Week 9.1 + \begin{itemize} + \item Worked on the final draft for the tech review + \end{itemize} + + \item Summary + \begin{itemize} + \item I finished the final draft of my tech review on Monday night and submitted it mid-day Tuesday. + \end{itemize} + \end{itemize} + +\item Week 10 + \begin{itemize} + \item Week 10.2 + \begin{itemize} + \item Meeting with TA + \end{itemize} + \item Week 10.3 + \begin{itemize} + \item Created latex template doc on overleaf + \item Added initial content + \end{itemize} + \item Week 10.4 + \begin{itemize} + \item Worked on final draft of the design document + \end{itemize} + \item Week 10.5 + \begin{itemize} + \item Worked on final draft of the design document + \item Turned in the final draft of the design document + \end{itemize} + + \item Summary + \begin{itemize} + \item I worked on and finished the final draft of our group design document and turned it int. We also had a 60 second meeting with our TA this week. + \end{itemize} + \end{itemize} + +\end{itemize} + + + + +\subsubsection{Winter} +\begin{itemize} +\item Week 1 + \begin{itemize} + \item Week 1.2 + \begin{itemize} + \item We went and checked out our lab space in Graf 306 + \item A work schedule was made to work at least five hours on Tuesday, Thursdays, and Saturdays, with the Saturday work overlapping with the Mars Rover weekly meetings + \item Planned to start actual development work Thursday + \end{itemize} + \item Week 1.4 + \begin{itemize} + \item I filled out Asana with the core tasks that our software need to produce + \item Initial tasks were divvied up + \item I began continuing my work on processing and displaying video data + \end{itemize} + + \item Summary + \begin{itemize} + \item Chris, Ken, and I met up after class on Tuesday so I could show them our lab space in Graf 306. We then came up with a work schedule for the term where we work on Tuesdays, Thursdays, and Saturdays for five hours a day at minimum. Then on Thursday, we all began actual work starting with creating tasks to complete and assigning initial tasks to everyone. I then continued working on the video display systems. I made the processing and display code slightly more efficient, and also added stream labels and fps counters directly on the video stream. On Saturday, I plan to add in auto adjustment of the stream quality based on whether the fps values are too low. Conversely, if the fps is pegged at the maximum, the quality will be increased until it starts to drop. + \end{itemize} + \end{itemize} + +\item Week 2 + \begin{itemize} + \item Week 2.2 + \begin{itemize} + \item Continued working on video systems + \end{itemize} + \item Week 2.4 + \begin{itemize} + \item Began refactoring video receiving class after verifying that the core class worked well. + \end{itemize} + \item Week 2.6 + \begin{itemize} + \item Began refactoring the core of the ground station launcher file and restructured the program folder to have a cleaner layout. + \end{itemize} + + \item Summary + \begin{itemize} + \item Over that week, I mainly worked on the video receiving class, testing it to make sure it was reliable and could show enough video streams at a smooth frame rate. Once that was verified, I began refactoring the class into a new version that would be able to include turning on and off video streams and adjusting what streams were shown in what display box. Later in the week, I began refactoring the ground station launcher file and folder structure so we'll have a cleaner base to work with as the project progresses. + \end{itemize} + \end{itemize} + +\item Week 3 + \begin{itemize} + \item Week 3.2 + \begin{itemize} + \item Finished refactor of the launcher for the ground station + \item Added in check for if the rover is on the network when the software starts + \item Continued refactor of the video classes + \end{itemize} + \item Week 3.4 + \begin{itemize} + \item Worked on adding advanced features of the video class refactor. + \item Added sleeping of video streams + \item Made number of cameras and resolutions dynamic + \item Can handle smart changing of what video displays are in each GUI element + \end{itemize} + + \item Summary + \begin{itemize} + \item Over this week, I finished the refactor of the launcher for the ground station software. This included an addition to keep the program from launching if the Rover is not present on the network. Also, there is now a shared object that can be passed to all the important classes in the program to allow for easy interfacing with signals from other classes and the GUI. I also made significant progress on the Video class refactoring. At the moment, the GUI can now display a dynamic number of video streams, and also allows for dynamically changing which stream is displayed in each video display element. I've also added the ability to disable video streams where it now actually stops pulling in the video data to lower bandwidth usage. This includes "sleeping" video streams that aren't explicitly disabled, but are not actively being shown. Lastly, I finished the core of the GUI layout using QT Designer so the core widget modules now match the layouts defined in our documents from last term. + \end{itemize} + \end{itemize} + +\item Week 4 + \begin{itemize} + \item Week 4.2 + \begin{itemize} + \item Continued work on video systems + \item Assisted main software team with their GPS and IMU firmware, as well as creating a ROS node to broadcast said data. Goal is to get GPS data sooner so Chris has that data to work with. + \end{itemize} + \item Week 4.4 + \begin{itemize} + \item Assisted with firmware programming for drive control micro-controllers + \item Assisted on work on the motor controllers drive nodes for ROS so our team can have a node to send drive commands to. + \end{itemize} + + \item Summary + \begin{itemize} + \item This week was mostly spent helping with development on software packages that will help support the ground station software on the Rover. Our group is getting to the point where having working ROS nodes on the Rover and hardware to control is getting more important, so I decided to help speed up the process. I worked on firmware for the micro-controllers that processed raw GPS and IMU data as well as the motor controller. I then also helped write the ROS nodes to interact with these micro-controllers so they could be controller using normal ROS topics. + \end{itemize} + \end{itemize} + +\item Week 5 + \begin{itemize} + \item Week 5.2 + \begin{itemize} + \item Took a break from capstone software to assemble revision 1 of the Mars Rover Iris control board + \item Spent 10 hours assembling Iris + \end{itemize} + \item Week 5.4 + \begin{itemize} + \item Spend 7 hours testing and fixing electrical problems with the Iris board + \item Ending board had full functionality on the 12 communication ports + \end{itemize} + + \item Summary + \begin{itemize} + \item This week was pretty light for capstone as I had midterms. Additionally, I decided to take some time to help the Mars Rover electrical team, and assembled their Iris central control board. Further development of the ground station will be greatly helped by having missing hardware finally connected to the Rover to talk to, so I figured spending some extra time helping this to happen would be useful for the team overall, and then by proxy, our capstone team. Assembly, testing, and modifications took 17 hours. I also wrote a simple motor driver node for ROS so the motor driver board could be tested using control from ROS topics. + \end{itemize} + \end{itemize} + +\item Week 6 + \begin{itemize} + \item Week 6.2 + \begin{itemize} + \item Worked on and completed rough draft of expo poster + \item Helped Chris with mapping integration + \item Wrote simple joystick control file to be run on ground station + \item Added UI elements + \end{itemize} + \item Week 6.4 + \begin{itemize} + \item Worked on midterm report + \end{itemize} + + \item Summary + \begin{itemize} + \item This week was spent mostly working on administrative stuff for the capstone project. A rough draft of the expo poster was made, and the later part of the week was spent working on the midterm report and video. However, I also did create a simple test file that takes in joystick data on the ground station, and broadcasts it to a ROS topic, allowing for remote driving of the motor connected to the Rover through Iris. + \end{itemize} + \end{itemize} + +\item Week 7 + \begin{itemize} + \item Week 7.4 + \begin{itemize} + \item Helped with SAR work + \item Made multi-threaded controller code. + \item Tested nimbo\_sender / receiver + \end{itemize} + + \item Summary + \begin{itemize} + \item This week I helped out getting things ready for the Rover systems acceptance review, one of the pivotal turning points for the rover team. This involved cleaning up code and getting remote drive systems working. As part of this, I re-wrote the joystick control test file to be multi-threaded and also got drive working with nimbro\_transport, which allows for UDP sending / receiving of ROS topics for packet loss allowable topics such as drive and video. + \end{itemize} + \end{itemize} + +\item Week 8 + \begin{itemize} + \item Week 8.2 + \begin{itemize} + \item Continued work for SAR deadline + \item Wrote drive sender so that sent control data matched the refactored drive\_receiver on the Rover + \item Joystick control speed limiting using throttle axis, shows speed limit and tank output on GUI. + \item Tuned drive sender until remote drive over radio was smooth + \item Helped with refactor of whole GitHub structure + \item Needed for easy access to shared ROS packages due to nimbro addition + \item Made major updates to GUI design, moved closer to matching design document. + \item Arm joint position placeholders + \item Rover status placeholders + \item Added pause feature to drive controller, starts in pause by default + \item Added mock compass image to the GUI, for show during SAR video + \item Tested remote drive and video with no tether! Drove around parking lot from ground station. + \end{itemize} + \item Week 8.3 + \begin{itemize} + \item Helped create videos for SAR demo + \end{itemize} + + \item Summary + \begin{itemize} + \item Due to the SAR deadline being March 2, I put in extra time this week to make systems work as well as they could for the demo video made on Wednesday. For the demo, we wanted at minimum remote Rover drive working, video systems buttoned up and working well. On this note, wrote a joystickcontrolsender class to match the new rover\_drive system implemented on the rover. This code was the finalized version of the testing joystick code I'd written. I also added the ability to use the throttle stick on the joystick to act as a speed limit for the drive commands sent. So a setting of 50\% would scale the full joystick range to only 50\% speed. Additionally, a pause feature was added so that the rover cannot be accidentally controlled when the GUI first starts up. A button on the joystick disables pause state, and can be used to toggle the state while the gui is running. Also, gui elements on the right monitor were updated to show the speed limit value and the current power output to each of the sides of the rover in tank drive form. After making these changes, I tuned update rates and nimbro transport rates to get driving smooth again. + +Due to the addition of nimbro\_network, I refactored the GitHub software repository to make it easier to share packages between the rover and ground station software. This was needed so that both had access to custom designed message formats in ROS. I also worked a lot this week to update the look of the GUI to match our design document. Placeholders images or Qt GUI elements for arm joint positions, rover statuses, and the compass were all added. + +On Tuesday night, I and the team's mechanical lead, Ben, tested actual real remote drive of the Rover. We placed the rover in the Graf parking lot where he followed it with a kill switch tether, and I drove the rover over the remote radio link from the 3rd floor of Graf with the antenna sticking out the window. Tests showed that overall everything worked well! Driving was mostly smooth and video responsive enough to feel comfortable driving. Then on Wednesday, we remotely drove the rover on the catwalk of 3rd floor Graf and took videos of both the Rover driving, and of me controlling it at a now largely flushed out looking ground station. + \end{itemize} + \end{itemize} + +\item Week 9 + \begin{itemize} + \item Week 9.2 + \begin{itemize} + \item Tuned some parameters of the drive controller so that driving was a bit smoother after remote drive testing the previous week. + \item Rewrote video\_receiver and coordinator to include new topic to control which video resolution is enabled, side effect of nimbro + \item Added auto resolution adjustment of video\_receivers + \item Tested new end effector video stream + \end{itemize} + \item Week 9.4 + \begin{itemize} + \item Added joystick control sending and receiving for selection of cameras in GUI + \item Helped Chris integrate full map system into master branch + \item Added the ability to move compass, just spinning never-ending in one direction. + \end{itemize} + + \item Summary + \begin{itemize} + \item After testing real remote driving the previous week, I tuned parameters on the rover and the ground station to get remote drive working just a little bit smoother and with no dropouts. After that, I worked on rewriting my video\_receiver and video\_coordinator threads so that instead of simply opening the designed video stream, the ground station would tell the rover which stream to send. This was a side effect of using the UDP nimbro\_network transports. Because UDP continually spams data at the ground station, it was in effect sending all the different resolution steams to the ground station all the time. This extra bandwidth was definitely something the team didn't want. During the rewrite, I also added automatic resolution adjustment of the video\_receivers based on averages of the received frame rates. + +I also tested and integrated receiving and showing the fourth and final video stream from the end\_effector, which worked as intended. Receiving of rover\_statuses was also integrated into the roslaunch file and I tested receiving those statuses from command line. I ended up adding and additional manual update message for that package on the rover so the ground station could request and initial state when the software first starts up, and tested this via rostopic publish from the command line. + +As I'd gotten the joystick controlclass cleaned up the previous week, I also wrote and tested joystick control of which video streams were shown on the three gui elements while I was rewriting the receivers and video coordinators. Two sets of two buttons each on the joystick now cyclically change which element is selected via an orange ring around the outside as well as what camera stream is current shown. The trigger on the joystick disables the currently selected stream. + +I also helped integrate Chris' mapping system into the master branch of the rover software before ending the week by writing the threaded class needed to make the compass spin. I ended by making the compass spin in one direction indefinitely. + +I sat down in the middle of the week and helped the mechanical team lead determine the final design for the quick deployment ground station box, which he then began fabricating. + \end{itemize} + \end{itemize} + +\item Week 10 + \begin{itemize} + \item Week 10.2 + \begin{itemize} + \item Made nice new compass image asset as vector image in Inkscape, exported as PNG + \item Compass now can respond to heading updates (once we get them). For now, left/right clicks change heading + \item Heading and next goal heading update + \item Arm joint positions spin/stop when clicked. Placeholders. + \item Help Ken integrate his system statuses with the GUI + \item Placeholders for waypoint entry/editing + \item Wrote test code to get info from the M2 radios, set channel + \item Refactored M2 radio test code into one module to set radio channel from GUI, added GUI button and setting. Tested and works. + \item Helped Ken debug thread context issues updating GUI + \item Added pitch and roll indicators for Rover for when we get that data + \end{itemize} + \item Week 10.4 + \begin{itemize} + \item Made minor changes to statuses so that it looked nicer + \item Added OSURC logo to top left corner of GUI per Nick's request + \item Made numerous UI changes to help clean up look. + \item Refactored joysticksystems to inputsystems + \item Added spacenavsystems to read in spacenav mouse data + \end{itemize} + + \item Summary + \begin{itemize} + \item This final week was spent mostly dealing with non-critical updates to the look and feel and glue logic for the GUI. I made a brand new compass asset in inkscape that looks like a real compass and exported it as a high resolution PNG to be imported in the GUI. I then finished off the compass class allowing for the compass to rotate to a heading if one is received from the Rover. As the rover is not currently broadcasting this data, left and right clicking on the GUI element causes it to add or subtract five degrees from a mock heading, whose update is then shown. Additionally, I also made the textual readouts show the current heading to prove we have control of them. I did something similar with the arm joint positions by making them all spin when left clicked and stop spinning when right clicked. These are placeholders until we get arm data later next term. + +Ken got his system statuses class ready to integrate into the main GUI and launcher, so I helped him do that and make the minor changes needed to make his thread start and stop properly. I also helped him debug a thread context issue that was causing weird flickering on the status display elements. Afterwards, I added the gui elements for manually entering GPS coordinates for adding to the waypoints listings. + +I wrote test code to interact with the Rocket M2 radios we're using to get the status data we'll end up needing, such as signal strength, channel, and throughput. I also got test code working to set the 2.4GHz channel that the radios are set to. Afterwards, I wrote a class to handle the channel updates, made gui elements to control it, added this class to the GUI, and tested it. Now, a channel from 1-11 can be set from the GUI. After pressing the button, radios are reconnected and data returns after 4-10 seconds. + +Near the end of the week, I made mostly graphical changes to the GUI such as adding and OSURC logo to the top left corner, and adjusting spacing and layouts to be more pleasing. I ended this week by refactoring the joysticsystems package into inputsystems before adding the spacenavsysystem class. I currently have this class reading in and storing SpaceNav mouse data in a class variable, waiting to be broadcast to appropriate systems once they're ready to accept the control data. + +The mechanical team also showed us the assembled quick-deployment box, which should be ready for painting and then hardware install in the next few days. + \end{itemize} + \end{itemize} + +\end{itemize} + + + + +\subsubsection{Spring} +\begin{itemize} +\item Week 1 + \begin{itemize} + \item Week 1.2 + \begin{itemize} + \item Talked with group mates over slack about what needs to be completed this term + \item Generally talked about the fact that the team was changing competitions + \item Didn't work on the project as everyone was busy + \end{itemize} + + \item Summary + \begin{itemize} + \item Chris, Ken, and I chatted over slack about what needs to be done over the term. Not much is left, and a lot of the work is waiting on Rover hardware. Also, we talked about the fact that the Rover team has switched to the Canadian International Rover Challenge. + \end{itemize} + \end{itemize} + +\item Week 2 + \begin{itemize} + \item Week 2.4 + \begin{itemize} + \item Did a work day on Thursday, I worked on SpaceNav mouse integration. + \item I registered the team for EXPO + \item I also dealt with sending in expo release forms + \item We made a list of all tasks left to be completed + \item Went over design requirements and found a few that need to be modified due to Rover design changes over the year. + \end{itemize} + + \item Summary + \begin{itemize} + \item We all met on Thursday for a work day. I worked on continued integration of the SpaceNav mouse, getting values normalized and broadcasting to Chris could use it to pan the map. I also registered the team for EXPO and dealt with sending in the media release forms for our team. I also went over the design requirements document with Chris and Ken and found some elements that need to be changed as they're either no longer pertinent, or have changed enough that it would be better to update their descriptions. We'll be making these changes in the following week. Part of this was looking at the differences in the rules for University Rover Challenge vs the Canadian competition the team is now going to. + \end{itemize} + \end{itemize} + +\item Week 3 + \begin{itemize} + \item Week 3.4 + \begin{itemize} + \item Worked on Rover side software to help get more statuses for Ken + \item Made new and worked on new rover package rover\_arm to get rover arm integrated with ROS + \end{itemize} + + \item Summary + \begin{itemize} + \item This week I worked on Rover code rather than ground station code as we're now mostly waiting on features of the Rover to be finished before we can implement the appropriate ground station side code. This involved me getting rover battery status monitoring working and sending to the ground station as well as helping another member get GPS statuses doing the same. I also made and began work on the Rover's rover\_arm package to interface with the IONI motor controllers used to move the arm. I got a simple package compiling with both the ROS packages and simplemotion library and got an arm motor moving with it. + \end{itemize} + \end{itemize} + +\item Week 4 + \begin{itemize} + \item Week 4.2 + \begin{itemize} + \item Finished final draft of poster + \end{itemize} + \item Week 4.6 + \begin{itemize} + \item Worked on and submitted a revised version of our design requirements document. + \end{itemize} + + \item Summary + \begin{itemize} + \item This week, I worked with my team to make the final changes to our poster for expo. I then submitted the poster for printing. I also worked with my team to make modifications to our design requirements document to reflect the team's change to the Canadian International Rover Challenge. We got the revised document signed off by all group members and the stakeholder and emailed it to the professor, TA, and stakeholder. + \end{itemize} + \end{itemize} + +\item Week 5 + \begin{itemize} + \item Week 5.6 + \begin{itemize} + \item Worked on midterm progress report + \end{itemize} + + \item Summary + \begin{itemize} + \item This was a busy midterm week, so I just worked on the midterm report and presentation. + \end{itemize} + \end{itemize} + +\item Week 6 + \begin{itemize} + \item Summary + \begin{itemize} + \item No work was done this week + \end{itemize} + \end{itemize} + +\item Week 7 + \begin{itemize} + \item Week 7.5 + \begin{itemize} + \item Went to expo! + \end{itemize} + + \item Summary + \begin{itemize} + \item Our team was at expo! Things went well! The demo was smooth. + \end{itemize} + \end{itemize} + +\item Week 8 + \begin{itemize} + \item Week 8.6 + \begin{itemize} + \item Got the ground station controlling the pan/tilt node + \end{itemize} + + \item Summary + \begin{itemize} + \item I finished the firmware for a prototype pan/tilt node and wrote the code for the GUI to control it using the joystick. Tested and worked! + \end{itemize} + \end{itemize} + +\item Week 9 + \begin{itemize} + \item Summary + \begin{itemize} + \item No work was done this week + \end{itemize} + \end{itemize} + +\item Week 10 + \begin{itemize} + \item Week 10.2 + \begin{itemize} + \item Started final report document + \end{itemize} + \item Week 10.4 + \begin{itemize} + \item Worked on final video presentation. + \item Recorded my portion of presentation. + \end{itemize} + + \item Summary + \begin{itemize} + \item This week, I've worked on the final video and started the final report document to finish off capstone. + \end{itemize} + \end{itemize} + +\end{itemize} \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/05-blogposts/ken.tex b/cs_capstone_documents/spring_final_report/05-blogposts/ken.tex new file mode 100644 index 0000000..518ada6 --- /dev/null +++ b/cs_capstone_documents/spring_final_report/05-blogposts/ken.tex @@ -0,0 +1,355 @@ +\subsection{Ken Steinfeldt} +\subsubsection{Fall} +\begin{longtable}{ | l | l | p{14cm} | } +\hline +Week & Day & Post \\ +\hline +1 & Tuesday & Learned about capstone. \\ + & Wednesday & Considered capstone projects. \\ + & Friday & Decided on a capstone project. \\ +\cline{2-3} + & Summary & Introduction to Capstone. + I spent most of the week getting my feet wet and understanding the project ahead of me. \\ + \hline +2 & Tuesday & Learned of project assignment. Met group members. Got the project I wanted. Very excited. \\ + & Sunday & Met with client 2:30 - 3:30 to discuss requirements and scope of project. \\ +\cline{2-3} + & Summary & + Struggled with \LaTeX makefile. Still don't really understand how to make it go. + + Big part of this week was learning about capstone project assignment. + Met with client for first time. \\ +\hline +3 & Monday & Wrote and submitted project problem statement document. \\ +\cline{2-3} + & Summary & +Wrote Problem Statement. + +It was difficult to grasp the entire project so early but with help from the client and group members it went smoothly enough. + +Good learning experience for getting to know the project and what we were getting ourselves into. Going forward we will need to become more acquainted. \\ +\hline +4 & Summary & Weekly meeting set for Tuesdays at 3:50 starting next week. \\ +\hline +5 & Tuesday & First meeting with TA Andrew Fielding at 3:50. \\ +\hline +6 & Tuesday & Weekly meeting with TA Andrew. \\ +\hline +7 & Tuesday & Weekly meeting with TA Andrew. \\ +\cline{2-3} + & Summary & Requirement document individual assignments made and agreed upon. \\ +\hline +8 & Tuesday & Weekly meeting with Andrew. \\ +\cline{2-3} + & Summary & Worked on requirements document rough draft. \\ +\hline +9 & Tuesday & Weekly meeting with Andrew. \\ +\cline{2-3} + & Summary & This week is defined by the requirements document final draft. \\ +\hline +10 & Tuesday & Weekly meeting with Andrew. Short meeting, we don't have much to discuss. Everything is well. \\ + & Wednesday & Design document is created on Overleaf for group to work on. \\ + & Thursday & Work on design document, research and some writing. \\ + & Friday & Finish up design document. \\ +\cline{2-3} + & Summary & This is the final week of classes. Thursday class is an optional workshop. + On Friday the design document is due. Team works on document all day. The document feels rushed and we're a little overwhelmed with it. We also have a difficult time figuring out roles and ownership as no code has yet been written. \\ + \hline +\end{longtable} +\subsubsection{Winter} +\begin{longtable}{ | l | l | p{14cm} | } +\hline +Week & Day & Post \\ +\hline +1 & Tuesday & First day of class. + +First time group meets since winter break +\begin{itemize} +\item We meet in our lab +\item Discuss current state of code base +\item Discuss rover progress +\begin{itemize} +\item Current state +\item Issues, etc. +\end{itemize} +\item We set group work times for the term +\begin{itemize} +\item Tuesday and Thursday all day (more or less) +\item First group work day will be Thursday 1/11/18 +\end{itemize} +\item Group needs to complete ROS tutorial before next work day +\item Winter term TA meeting time has not yet been determined +\begin{itemize} +\item Will likely be on Tuesday or Thursday as group will be together on those days +\end{itemize} +\end{itemize} +\\ +\cline{2-3} + & Summary & +First week of class after winter break. + +Group reviews state of current code base for the project. +Group meeting times are determined by group. These are Tuesdays and Thursdays. \\ +\hline +2 & Tuesday & +Meet with group to work on project all day. +Begin writing StatusCore module that will grab system status information from the rover and display it to the user. +The rover will create publishers for the necessary statuses. +StatusCore module creates subscribers that read from the rover publishers. +Minimal processing should be done on the information coming from the rover.\\ +\cline{2-3} + & Summary & Week spent primarily getting started with coding. Met with group at OSURC club meeting on Saturday. \\ +\hline +3 & Tuesday & Met team at 10:00AM to work on system statuses \\ + & Thursday & We reach out to project leader Nick McComb for approval of our capstone documents. +Nick responds later in the day with approval. \\ + & Friday & Hear from TA Andrew to setup this terms weekly meetings. +Corwin responds with the preferred group meeting times which are 9-11 and 1-4 on Tuesdays. \\ + & Saturday & +Unable to make the OSURC Mars Rover team meeting this Saturday due to not feeling well. + +Work on system statuses from home. I am unable to finish SensorCore.py this week like I had hoped. However, I get a basic mockup going and generally make progress. + +Repository is cleaned up and reorganized for clarity between different rover teams. This is much needed and well done but causes me difficulty as my branch becomes significantly diverged from the main branch. I am unable to quickly fix the divergence and will have to do so next week. \\ +\cline{2-3} + & Summary & + Goal is to finish system statuses by the end of this week. + +Not feeling well this week. \\ +\hline +4 & Tuesday & TA meeting with Andrew + +Learn about PyQt framework in order to create UI layout. It is more complicated than I thought it was. \\ + & Thursday & Implemented clock into StatusCore and tested that it worked - this was one of the ways I attempted to learn the PyQT + +Began working on the stopwatch module for the ground station. This is not as trivial as I thought it would be. \\ + & Saturday & Went to Corvallis for OSURC Rover team meeting. + +Worked with team in lab after meeting. Got stop watch working as an individual module, but not integrated with StatusCore. Includes push buttons, but needs to be left - right mouse clicks for the final product.\\ +\hline +5 & Tuesday & TA meeting with Andrew + +Midterms galore this week. I manage to design a very basic visual framework for the UI.\\ + & Thursday & Visual framework is shown to team members and is not liked. I agree with the criticism and the UI for SensorCore is redesigned with the group. Instead of being text based it is now boxed labels that are either red, orange, or green depending on the values that are given. For simple on/off alerts, such as various module connectivity, the box is simply red or green. + +Red - something is wrong - usually ~80\% and greater (if applicable) or a False boolean value +Orange - warning, approaching read usually ~70\%-80\% (if applicable) +Green - everything is great or a True boolean value \\ +\hline +6 & Tuesday & TA meeting with Andrew. + +Meet with team in Corvallis to work in lab. Group picture is taken and poster rough draft is created. We are happy with the poster and don't foresee a large redesign in the future.\\ + & Thursday & Group works on midterm report for the class. Report is written together and videos are recorded. Videos are then stiched together. \\ +\hline +7 & Tuesday & TA meeting with Andrew. Nothing of note +\begin{itemize} +\item Team gives status update +\item Nothing of concern +\item Team gets back to work on ground station software +\item Code base cleanup +\end{itemize} +\\ + & Thursday & A little stymied by system status module on the rover side. + +I help out with some random things while waiting for rover team. It's not a big deal. \\ +\cline{2-3} + & Summary & This week is primarily dominated by the need to produce the SAR video for the competition. If this video doesn't get done the rover cannot compete. + +This takes up a lot of the group's work time but work still gets done on the ground station. + +Work is done on the joystick and Corwin integrates the nimbro packages to cutdown on latency between the ground station and rover. \\ +\hline +8 & Tuesday & TA meeting - All is well. Project is progressing. + +Work with rover team to get system values from rover + +StatusCore values (green, orange, red) decided. \\ + & Thursday & Meet team in Corvallis to work in lab. + +Corwin has created scripts to ease the build process of the ground station. I sit down with Corwin to learn how to use these new scripts. + +Work on StatusCore now that rover statuses are available for final integration. \\ +\cline{2-3} + & Summary & A lot happens in week 8 + \begin{itemize} + \item Repository is reorganized + \item New startup script is written for ground station + \begin{itemize} + \item This greatly helps development + \end{itemize} + \item Create some more placeholders for statuses in the UI + \item Rover drives! + \end{itemize} \\ + \hline +9 & Tuesday & TA meeting. All is well and progressing. + +Do not work from lab, will meet with team on Thursday. + +StatusCore: +\begin{itemize} +\item Work on callback functions +\begin{itemize} +\item pickup rover statuses, evaluate their return functions +\end{itemize} +\item New system statuses added to rover +\begin{itemize} +\item System statuses are still likely to change +\end{itemize} +\item Needs to ask for update from rover on startup +\begin{itemize} +\item Peripheral systems, such as cameras, will not automatically update until a change has happened. I will need to poll the rover at startup to get initial status +\item This requires a subscriber on rover and a publisher in StatusCore +\end{itemize} +\end{itemize} +\\ + & Thursday & Met with team in lab. + +Begin push to meet Beta by week 10. + +StatusCore work: +\begin{itemize} +\item Finalize UI look in QT designer +\item Properly lable/organize UI elements +\item Prepare for main branch integration +\end{itemize} +\\ +\cline{2-3} + & Summary & I make some serious progress on StatusCore this week, plan to fully integrate into ground station next week to meet beta requirement. + \begin{itemize} + \item StatusCore look is (somewhat) finalized + \item Rover team gets their status module sending signals I can use + \item I clean up StatusCore in preparation for integration next week + \end{itemize} + \\ +\hline +10 & Tuesday & Worked late to finally integrate StatusCore with main branch. +StatusCore module hit beta status and, with the help of Corwin, integrated into the project. +Some bugs were noticed, namely some flickering in the status alerts. The source of the bug was identified but not fixed. +\begin{itemize} +\item Problem: Did not think StatusCore would require the use of Slots +\item Solution: StatusCore needs to use QT slots in order to refresh nicely +\end{itemize} +\\ + & Thursday & Last class of the term + +After class we worked in the lab. +I hooked up the clock and fixed the StatusCore bugs that were identified on Tuesday \\ +\cline{2-3} + & Summary & Final week of the term +\begin{itemize} +\item No TA meeting this week +\item Finally got StatusCore integrated into ground station +\begin{itemize} +\item Very successful, only a few bugs +\end{itemize} +\item Some bugs exist in StatusCore and are squashed (as far as we know) +\item Ground station hits beta! +\end{itemize} +All in all a very exciting week. Everyone is happy with our progress. \\ +\hline +\end{longtable} +\subsubsection{Spring} +\begin{longtable}{ | l | l | p{14cm} | } +\hline +Week & Day & Post \\ +\hline +1 & Tuesday & Code review of Spring break work on Rover and Ground Station.\\ + & Wednesday & Class Meeting. \\ + & Thursday & Team meets and goes over project. Change in venue discussed and new meeting times and requirements are discussed and agreed upon. \\ +\cline{2-3} + & Summary & + This is the first week of Spring term. + +First class meeting. + +First week after Spring break so the team meets to go over the status of the project and any of the changes that occurred during the last two weeks. + +The Rover team is no longer going to compete in the University Mars Rover Challenge, but instead will now compete in the Canadian International Rover Challenge. + +Change in competition means that that some minor changes in requirements are needed, these changes are discussed. + +The team also reviews the general status and progress of the project. New meeting times are discussed and agreed upon for the coming term. +\\ +\hline +2 & Tuesday & Code review. \\ + & Thursday & +Team meets. + +Changes to design document are discussed. Work will need to be finalized and signed off on by TA Andrew. + +StatusCore module changes will be small. Mostly subscribing to new publishers. Will need to wait for Rover team to get publishers up and running. May be most beneficial for me to do as much as I can to help Rover team. +\\ +\cline{2-3} + & Summary & + Group deals with EXPO bureaucracy. This entails registering, requesting necessary equipment/power and signing the proper release forms. + +Changes in competition requirements again discussed as they will require that the design document be amended to match the changes in software. The changes are minor but are changes none the less. + +Changes to StatusCore module look to be minor. \\ +\hline +3 & Tuesday & +Code review. Rover and Ground Station. + +Work on stubbing out subscribers. \\ + & Wednesday & Wired Article due. \\ + & Thursday & Team meets. + +Rover team expected to be ready to broadcast new statuses by the end of the week. Will work on them on Saturday. \\ +\cline{2-3} + & Summary & + Beginning of week three the Rover team is still not ready for new statuses. This is not unexpected considering the quick change of design requirements. + +Despite the lack of broadcasted statuses I can and do begin working on the foundational subscribers, etc. so that when the Rover team is ready I can pick them up in StatusCore. + +Some Statuses are also deprecated as they will no longer be used. This includes Bogies. New subscribers are stubbed out. + +WIRED! Article is due this week. +\\ +\hline +4 & Tuesday & Code Review. StatusCore work. \\ + & Thursday & Team meets. + +EXPO poster is finalized, approved, and submitted. + +Final changes to requirements document made and approved. +\\ +\cline{2-3} + & Summary & + Continue to work on changes to StatusCore. + +Final poser is due this week so it is finalized and submitted after being approved. + +By the end of this week we deem software to be EXPO ready. + +Amendments to project requirements are made, agreed upon, and signed-off on. This includes all team members as well as client/stakeholder. +\\ +\hline +5 & Wednesday & Class meets. \\ + & Thursday & Team meets, works on Spring midterm report/presentation. \\ +\cline{2-3} + & Summary & This is week 5 and is mid-term season. Every member of the team is swamped with work. + +I am not able to get very much done on the ground station software. + +Team meets and works on Spring midterm report. Report and presentation are finished by the end of the week (of course). +\\ +\hline +6 & Summary & Not much capstone work. Midterms and projects in other classes. \\ +\hline +7 & Wednesday & Class meeting to prepare for EXPO. \\ + & Friday & EXPO! Goes great. Our team does really well and has a lot of fun. \\ +\cline{2-3} + & Summary & Expo happens this week. \\ +\hline +8 & Summary & Did not work on ground station. \\ +\hline +9 & Summary & Did not work on ground station. \\ +\hline +10 & Thursday & Final video work begins. \\ + & Friday & Final video presentation completed and submitted. \\ + \cline{2-3} + & Summary & Team is all busy with finals and final projects. + +Final presentation is due and completed by the team.\\ +\hline +\end{longtable} \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/06-poster/poster.tex b/cs_capstone_documents/spring_final_report/06-poster/poster.tex new file mode 100644 index 0000000..508840a --- /dev/null +++ b/cs_capstone_documents/spring_final_report/06-poster/poster.tex @@ -0,0 +1,2 @@ +\section{Poster} +\includepdf[pages=-, scale=1.04, landscape]{06-poster/poster_undergrad_expo_48x36_eecs.pdf} \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/06-poster/poster_undergrad_expo_48x36_eecs.pdf b/cs_capstone_documents/spring_final_report/06-poster/poster_undergrad_expo_48x36_eecs.pdf new file mode 100644 index 0000000..16223a4 Binary files /dev/null and b/cs_capstone_documents/spring_final_report/06-poster/poster_undergrad_expo_48x36_eecs.pdf differ diff --git a/cs_capstone_documents/spring_final_report/07-documentation/Ground_Station_Quickstart.pdf b/cs_capstone_documents/spring_final_report/07-documentation/Ground_Station_Quickstart.pdf new file mode 100644 index 0000000..b9f0bde Binary files /dev/null and b/cs_capstone_documents/spring_final_report/07-documentation/Ground_Station_Quickstart.pdf differ diff --git a/cs_capstone_documents/spring_final_report/07-documentation/Rover_Ground_Station_Block_Diagram.pdf b/cs_capstone_documents/spring_final_report/07-documentation/Rover_Ground_Station_Block_Diagram.pdf new file mode 100644 index 0000000..e708b3d Binary files /dev/null and b/cs_capstone_documents/spring_final_report/07-documentation/Rover_Ground_Station_Block_Diagram.pdf differ diff --git a/cs_capstone_documents/spring_final_report/07-documentation/documentation.tex b/cs_capstone_documents/spring_final_report/07-documentation/documentation.tex new file mode 100644 index 0000000..a45abd3 --- /dev/null +++ b/cs_capstone_documents/spring_final_report/07-documentation/documentation.tex @@ -0,0 +1,79 @@ +\section{Documentation} +\subsection{How the Project Works} +\subsubsection{Overview} +This project works by combining the power of Robot Operating System (ROS), the Qt framework, and Python to make a simple (for what it is), fast, easy to modify, and easier to understand piece of software to act as the front end for the Mars Rover. PyQt is used to load and show the UI and give the software programmatic access to GUI elements. It also provides intelligent multi-threading with easy to use cross-thread communication pipelines. The use of python has allowed our team to write this code in a fraction of the time it would have taken in another language such as C++. ROS is the framework that the Rover is running and is based around the concept of abstracting everything into ROS topics. These topics allow for easy sending and receiving of control and status information in a way that is standardized instead of having to use a custom network control protocol. + +\subsubsection{Low bandwidth communications} +As the Rover is going to be at long range at many times, having as small of communication packets as possible is a priority. This helps keep control, video, and status information smooth and consistent. In order to facilitate this, the ground station and Rover both are using a package called nimbro\_network that allows for compression of ROS topics and also allows for us to choose between a TCP and UDP transport layer. Non-critical data that we want fast gets sent with compression over UDP and includes video data from the Rover and live drive commands from the ground station. Important and/or infrequent data is sent with or without compression depending and using the TCP transport. Data sent using TCP includes status information from the Rover and, in the future, waypoints and autonomy control. + +\subsubsection{Program Logical Structuring} +To make the ground station software easier to modify and understand, it has been broken down into logical hierarchies. At the core of the ground station source folder are the Framework and Resources folders. The Resources folder contains all of the static assets for the application such as image files and the UI files that determine how the GUI visually looks. The Framework folder contains all of the logical sub-systems of the software such as VideoSystems, InputSystems, and MappingSystems. By separating all systems out like this, it makes it easy to know which files need to be looked at when fixing or adding to the ground station. At the root of the source folder is "ground\_station.py", the launcher file for the whole application. Under normal conditions, this file only needs to be modified if a new threaded class is being added for additional functionality. This file handles launching of the software, displaying the GUI, and management of the startup and shutdown of all running threads. + +\subsubsection{Threading \& Adding Classes} +As this is a very large program with many systems running concurrently it has required the use of many threaded classes. To abstract away many of the complexities of this, the ground station main launcher file contains a method called add\_thread used to spin up a new threaded class from the Framework folder when one is made. This method also handles the graceful shutdown of the software when quit. In order for graceful shutdown, all of the program's child threads must not be running when the main launcher thread exits. If this is not the case, the application may hang or maintain unwanted connections in the background after it seems like it has exited. Anyone wishing to add new functionality to the GUI in a new file should copy an existing threaded class to use as a baseline. + +\subsubsection{ROS in Python} +ROS is a large part of why this software has been much easier to write than it could have been. In Python, the ROS subsystem can be accessed by importing rospy and calling rospy.init to tell ROS that we have a new node running. At this point, topics can be subscribed to by giving it the topic path and a the data type of the topic. Conversely, to broadcast a new topic message, a publisher is made by providing the topic path, data type, and queue size. To actually broadcast a message, you create a new instance of the data type, fill it with the desired data, and use the publisher's ".publish()" method to send it. In our software, these topics are used for all communications to and from the Rover. Absolutely no custom communication methods are used to interface between the Rover and ground station. An important note about the ROS messages used are that most of these messages are custom defined. In order for rospy and python to know the required information about a custom message, the ROS package containing the message define must be built as part of the local catkin workspace. This is the reason that the ground station's setup script includes many packages other than for just launching the ground station. The extra packages give us access to custom messages needed for understanding status messages and sending drive commands. + +\subsubsection{ROS Topic / Classes Block Diagram} +\includepdf[pages=-, scale=0.98]{07-documentation/Rover_Ground_Station_Block_Diagram.pdf} + + +\subsection{System Requirements} +\subsubsection{Hardware} +\begin{itemize} +\item 1x Computer running Ubuntu 16.04 LTS + \begin{itemize} + \item Intel core i5 or i7 equivalent processor + \item 4GB+ Ram + \item Minimum two display outputs + \end{itemize} +\item 2x 1080p Monitors +\item 1x USB Joystick +\item 1x SpaceNav Mouse +\item 1x USB Keyboard +\item 1x USB Mouse +\end{itemize} + +\subsubsection{Software / OS} +\begin{itemize} +\item \href{http://wiki.ros.org/kinetic/Installation}{ROS Kinetic} +\item \href{https://www.python.org/}{Python 2.X} with the following packages: + \begin{itemize} + \item PyQt5 + \item qdarkstyle + \item inputs + \item spnav + \item Pillow + \item paramiko + \item OpenCV 2 + \item qimage2ndarray + \item numpy + \end{itemize} +\item Set the computer to an IP address of 192.168.1.15 +\end{itemize} + + +\subsection{How to Install} +\begin{enumerate} +\item Create and \href{http://wiki.ros.org/catkin/Tutorials/create_a_workspace}{setup a catkin workspace} at "$\sim$/catkin\_workspace" +\item Add "source /home/[username]/catkin\_workspace/devel/setup.bash" to the end of your ".bashrc" file, replacing "[username]" with your account's username +\item Create the directory "$\sim$/Github" and clone the \href{https://github.com/OSURoboticsClub/Rover_2017_2018}{Rover\_2017\_2018} repository into it +\item Run the setup script at "$\sim$/Github/Rover\_2017\_2018/software/ground\_station\_setup.sh" to have the proper packages symbolically linked into your new catkin environment and for catkin\_make to be run automatically against it +\item If the catkin\_make process at the end of the script completes with no errors, you're ready to launch the ground station +\end{enumerate} + + +\subsection{How to Run} +\begin{enumerate} +\item Ensure all hardware from the requirements section above is plugged in +\item Ensure there is a network connection between the ground station computer and Rover +\item Open a terminal and run "roslaunch rover\_main ground\_station.launch" +\item The ground station should launch in full screen across both monitors +\item Press "ctrl-q" at any time to quit the application +\end{enumerate} + + +\subsection{User Guides} +\subsubsection{Client Requested Quickstart Guide} +\includepdf[pages=-, frame=true, scale=0.95]{07-documentation/Ground_Station_Quickstart.pdf} \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/08-technicalresources/technicalresources.tex b/cs_capstone_documents/spring_final_report/08-technicalresources/technicalresources.tex new file mode 100644 index 0000000..6f9e5f4 --- /dev/null +++ b/cs_capstone_documents/spring_final_report/08-technicalresources/technicalresources.tex @@ -0,0 +1,5 @@ +\section{Technical Resources} +\begin{itemize} +\item \href{http://wiki.ros.org/}{ROS Documentation} +\item \href{http://doc.qt.io/}{QT Documentation} +\end{itemize} \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/09-conclusions/chris.tex b/cs_capstone_documents/spring_final_report/09-conclusions/chris.tex new file mode 100644 index 0000000..aca6a9c --- /dev/null +++ b/cs_capstone_documents/spring_final_report/09-conclusions/chris.tex @@ -0,0 +1,28 @@ +\subsection{Chris Pham} +\subsubsection{Technical Knowledge Gained} +From this project, I learned quite a bit of technical knowledge doing this project over the year. +I learned how to use Qt and ROS enough to build a system using it, do not think I can do it well though. +After working with a large code base, I've learned to link projects in a tried grouped faction, close to the next object. +I think I know how to remove very stateful code, and breaking it into helper functions and the main class. +With the use of image manipulation, I feel that I know how to exactly how to use PIL, OpenCV, and other image software to stitch a bunch of files. +\subsubsection{Non-Technical Knowledge Gained} +For this project, I think I gained more of a time regulating skill, where I would have to say, I could not contribute to a project for a period of time, instead of doing half time on both projects or more. +Another point, is learning to ask for expectations and goals, and then slightly passing them because extra work would be unnoticed, and/or unused by the team, but too little would produce an incomplete product. +\subsubsection{Knowledge Gained of Project Work} +From this project, I learned that when you expect that something will take a period of time, expect truly to take double that. +Another take from this project is that, with some other projects that rely in other parts by other people, try to make something, and you could always try to fix it later. +Goals will always change, and be ready to change on a dime. +And in the end, without any type of leader or management, time will always be hard to come by, and everything will possibly be late. +\subsubsection{Knowledge Gained of Project Management} +For our group, there was not much of a need to police what someone did or did not do. +In the end, our biggest problem was the time commitments from having a group member in Hillsboro and only down Tuesday or Thursday which made some activities like weekend meetings near impossible. +\subsubsection{Knowledge Gained of Working in Teams} +For the group, we all had fun with each other and everyone else in the team and that made communications very easy to do. +Everyone was free form, and we did whatever we needed and the others would be accommodating in trying to fit that schedule. +When we could not meetup, we could at least use other means of communications like Slack to talk about expectations and code, which allowed for us do to whatever we need to do. +\subsubsection{Changes to Make if Starting Over} +If we were to start this over, I would like to some things to allow us to succeed further. +I think we would all make better plans at the start to allow for missteps of the team, and allow for easier prototyping. +That prototyping can allow for delays in the team, and then can be built with expected values instead of waiting for the system to be built. +Another thing would be getting testing data that we can use for integrated tests like GPS, Video, and Statuses, so we can just build a system using that data then it should be the same on the complete system. +I think for my section, I would actually use OpenGL instead of the PIL mapping system, because translating numbers randomly feels very weird, compared to my graphics history. \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/09-conclusions/conclusions.tex b/cs_capstone_documents/spring_final_report/09-conclusions/conclusions.tex new file mode 100644 index 0000000..e48f56c --- /dev/null +++ b/cs_capstone_documents/spring_final_report/09-conclusions/conclusions.tex @@ -0,0 +1,4 @@ +\section{Conclusions and Reflections} +\input{09-conclusions/chris} +\input{09-conclusions/ken} +\input{09-conclusions/corwin} diff --git a/cs_capstone_documents/spring_final_report/09-conclusions/corwin.tex b/cs_capstone_documents/spring_final_report/09-conclusions/corwin.tex new file mode 100644 index 0000000..778fc8a --- /dev/null +++ b/cs_capstone_documents/spring_final_report/09-conclusions/corwin.tex @@ -0,0 +1,38 @@ +\subsection{Corwin Perren} +\subsubsection{Technical Knowledge Gained} +\begin{itemize} +\item Real-world ROS usage +\item Multi-monitor PyQt interfaces +\item Some nuances of low-bandwidth networking +\item Multiple video steam coordination +\item Better organization of large software projects +\end{itemize} + +\subsubsection{Non-Technical Knowledge Gained} +\begin{itemize} +\item Better project time management skills +\end{itemize} + +\subsubsection{Knowledge Gained of Project Work} +\begin{itemize} +\item Projects almost always take longer than expected +\item Requirements almost always change, even if only a little bit +\item Lack of proper organization can make working on a project near impossible +\end{itemize} + +\subsubsection{Knowledge Gained of Project Management} +\begin{itemize} +\item Scheduling times to do things like project work where everyone can show up can be difficult +\end{itemize} + +\subsubsection{Knowledge Gained of Working in Teams} +\begin{itemize} +\item Continuous communication makes working in teams much much easier +\item So long as everyone is on the same page teams can get as much done when in the same room as they can separately +\end{itemize} + +\subsubsection{Changes to Make if Starting Over} +\begin{itemize} +\item Make better plans at the beginning for handling delays in the Rover side of the project +\item Work out a more empirical way of testing how much bandwidth is needed / can be handled by the radio links so we would have known what we had to work with +\end{itemize} \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/09-conclusions/ken.tex b/cs_capstone_documents/spring_final_report/09-conclusions/ken.tex new file mode 100644 index 0000000..8e6d0c2 --- /dev/null +++ b/cs_capstone_documents/spring_final_report/09-conclusions/ken.tex @@ -0,0 +1,39 @@ +\subsection{Ken Steinfeldt} +\subsubsection{Technical Knowledge Gained} +I gained a lot of technical knowledge and experience from the project. +First and foremost I learned how to use frameworks that I had never experienced before in ROS and PyQT5. +Not only had I never used Qt before, but I had never worked with any real UI framework before this project. +The ROS framework was also a unique challenge. +This project was an example of a very real use case for ROS, doing exactly what it was designed to do. +The framework was more complicated than I had anticipated, and required a significant learning curve. +Using both ROS and PyQt5 on a project such as this required using the frameworks according to best practice, and was fairly complicated at first, but simpler as time went on. +\subsubsection{Non-Technical Knowledge Gained} +I think that the most important non-technical knowledge I gained was the experience of working on a large, complicated project. +As the ground station was only a small portion of the of the Mars Rover project, it relied on many modules in many different locations. +As a group we were forced to manage these problems as they arose. +Even the organization of the repository was a challenge and had to be redone multiple times. +Development was also a problem as it could be a challenge to set up a functional development and testing environment. +This was alleviated with the development of a startup script that Corwin wrote. +\subsubsection{Knowledge Gained of Project Work} +Software engineering is notorious for delays and missed deadlines, and I am beginning to understand why. +At the beginning of the project many modules seemed to have a clear path to completion and simple solutions. +We thought that it would be easy for us to learn the two frameworks and then just start working with them, after all, that's what frameworks are for. +As it turns out, both ROS and Qt have not insignificant learning curves. +Learning how to use these frameworks took me much longer than I thought it would, and that hampered me throughout the process. +I also learned to trust my teammates, which is not something that someone expects to learn from a group project. +My teammates were great at always came through, even when I was not always able to. +By the end of the project I had learned that I could trust them completely. +\subsubsection{Knowledge Gained of Project Management} +The biggest thing that I learned about project management was how much easier it is to do when the project is well defined and planned at the beginning. +The work that we were required to do at the beginning of the year defined the scope of the project, the goals, the problems, and their planned solutions. +Having this already done due to the requirements of the class was hugely beneficial in implementing our solutions and a lesson in project management for the future. +\subsubsection{Knowledge Gained of Working in Teams} +Our group had great communication which was very beneficial to the team. +This open communication helped to make clear what was expected of each group member and helped our group to have fun and get along. +\subsubsection{Changes to Make if Starting Over} +\begin{itemize} +\item Take more time to understand the frameworks before trying to code with them. +\item Spend more time with the group personally. +\item Spend more time working with the rover team on rover stuff. +\item Take the time to create the testing environment before starting. +\end{itemize} \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/10-codelistings/codelistings.tex b/cs_capstone_documents/spring_final_report/10-codelistings/codelistings.tex new file mode 100644 index 0000000..65144c3 --- /dev/null +++ b/cs_capstone_documents/spring_final_report/10-codelistings/codelistings.tex @@ -0,0 +1,214 @@ +\lstset{ % + backgroundcolor=\color{white}, % choose the background color + basicstyle=\footnotesize, % size of fonts used for the code + breaklines=true, % automatic line breaking only at whitespace + captionpos=b, % sets the caption-position to bottom + commentstyle=\color{gray}, % comment style + escapeinside={\%*}{*)}, % if you want to add LaTeX within your code + keywordstyle=\color{blue}, % keyword style + stringstyle=\color{purple}, % string literal style +} +\section{Appendix 1: Interesting Code Listings} +\subsection{Drive Test} +\subsubsection{Code} +\begin{lstlisting}[language=python] +class DriveTest(QtCore.QThread): + def __init__(self): + super(DriveTest, self).__init__() + + self.not_abort = True + + self.message = None + self.publisher = rospy.Publisher("/cmd_vel", Twist, queue_size=10) + + rospy.init_node("test") + + def run(self): + while self.not_abort: + self.message = Twist() + + self.message.linear.x = 1.0 + self.message.angular.z = 1.0 + + self.publisher.publish(self.message) + + self.msleep(100) +\end{lstlisting} + +\subsubsection{Description} +This QThread example class starts a ROS publishing node on the "/cmd\_vel" topic to send raw drive control commands to the Rover. +In this case, it is sending a command to drive the Rover forward and to the right, essentially causing it to drive in a never-ending circle. + +\subsection{Video Test} +\subsubsection{Code} +\begin{lstlisting}[language=python] +class VideoTest(QtCore.QThread): + image_ready_signal = QtCore.pyqtSignal() + + def __init__(self, screen_label, video_size=None, sub_path=None): + super(VideoTest, self).__init__() + + self.not_abort = True + + self.screen_label = screen_label + self.video_size = video_size + + self.message = None + self.publisher = rospy.Subscriber(sub_path, CompressedImage, self.__receive_message) + + self.raw_image = None + self.cv_image = None + self.pixmap = None + self.bridge = CvBridge() + + self.image_ready_signal.connect(self.__on_image_update_ready) + + def run(self): + while self.not_abort: + if self.raw_image: + self.cv_image = self.bridge.compressed_imgmsg_to_cv2(self.raw_image, "rgb8") + + if self.video_size: + self.cv_image = cv2.resize(self.cv_image, self.video_size) + + self.pixmap = QtGui.QPixmap.fromImage(qimage2ndarray.array2qimage(self.cv_image)) + self.image_ready_signal.emit() + self.msleep(20) + + def __on_image_update_ready(self): + self.screen_label.setPixmap(self.pixmap) + + def __receive_message(self, message): + self.raw_image = message +\end{lstlisting} +\subsubsection{Description} +This example subscribes to the ROS topic that is passed in under the sub\_path argument in order to get video stream data. +An example of this topic might be "/cam1/usb\_cam1/image\_raw/compressed". +Inside of the body of the thread, it checks if there is image data, and if so decompresses it into a raw 8-bit image using ROS's OpenCV bridge libraries. +Finally, it converts the OpenCV image into a QImage and then into a QPixmap before broadcasting an update signal so the main GUI thread can show the image on the QLabel. +It is important to note that any direct GUI updates must happen in the main GUI thread, otherwise the QApplication will crash. + +\subsection{Joystick ROS Drive Test} +\subsubsection{Code} +\begin{lstlisting}[language=python] +rospy.init_node("drive_tester") +self.pub = rospy.Publisher("/drive/motoroneandtwo", RoverMotorDrive, queue_size=1) + +def __get_controller_data(self): + if (self.controller_aquired): + events = self.gamepad.read() + + for event in events: + if event.code in self.raw_mapping_to_class_mapping: + self.controller_states[self.raw_mapping_to_class_mapping[event.code]] = event.state + # print "Logitech: %s" % self.controller_states + + +def __broadcast_if_ready(self): + drive = RoverMotorDrive() + + axis = self.controller_states["left_stick_y_axis"] + + drive.first_motor_direction = 1 if axis <= 512 else 0 + drive.first_motor_speed = min(abs(self.controller_states["left_stick_y_axis"] - 512) * 128, 65535) + + self.pub.publish(drive) +\end{lstlisting} + +\subsubsection{Description} +These two methods and supporting lines above, taken from the testing class LogitechJoystick, contained in the file joystick\_drive\_test.py are the core of what is needed to get joystick data and broadcast it to the rover over a ROS topic. +These two methods are called on after another in a QThread. \_\_get\_controller\_data() reacts to motion events from the joystick and stores the current value of all axes and buttons in self.controller\_states. Then, in \_\_broadcast\_if\_ready(), and instantiation of the custom ROS message type, RoverMotorDrive, is made and values set to a scaled version of the raw values provided by the joystick. Finally, this data is published to the motor drive node and causes the ROS receiving node to see the data, send a message to the motor driver, and cause the motor to spin. + +\subsection{Video Test} +\subsubsection{Code} +\begin{lstlisting}[language=python] +def toggle_video_display(self): + if self.video_enabled: + if self.video_subscriber: + self.video_subscriber.unregister() + self.new_frame = True + self.video_enabled = False + else: + new_topic = self.camera_topics[self.current_camera_settings["resolution"]] + self.video_subscriber = rospy.Subscriber(new_topic, CompressedImage, self.__image_data_received_callback) + self.video_enabled = True +\end{lstlisting} +\subsubsection{Description} +This very simple snippet is in the VideoReceiver class in VideoSystems. It is a demonstration of what is needed to properly disable the receiving of video data on a stream. Looking at the Subscriber line, you can see that there is an image callback associated with the subscription to a topic in ROS. This means that if you don't actually unsubscribe (or in this case, unregister) from a topic, as can be seen a few lines above, the data will continue being received even if you are not actively using it. Not doing this would cause unwanted bandwidth to be used. + +\subsection{Ubiquiti Channel Change} +\subsubsection{Code} +\begin{lstlisting}[language=python] +GET_CURRENT_CHANNEL_COMMAND = "iwlist ath0 channel" +SET_CHANNEL_COMMAND = "iwconfig ath0 channel" + +def setup_and_connect_ssh_client(self): + self.ssh_client = paramiko.SSHClient() + self.ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + self.ssh_client.connect(ACCESS_POINT_IP, username=ACCESS_POINT_USER, password=ACCESS_POINT_PASSWORD, + compress=True) + +def apply_channel_if_needed(self): + if self.channel_change_needed: + self.show_channel__signal.emit(0) + self.set_gui_elements_enabled__signal.emit(False) + self.ssh_client.exec_command(SET_CHANNEL_COMMAND + " %02d" % self.new_channel) + self.get_and_show_current_channel() + self.channel_change_needed = False + +def get_and_show_current_channel(self): + channel = 0 + + ssh_stdin, ssh_stdout, ssh_stderr = self.ssh_client.exec_command(GET_CURRENT_CHANNEL_COMMAND) + output = ssh_stdout.read() + + for line in output.split("\n"): + if "Current Frequency:" in line: + channel = line.strip("()").split("Channel ")[1] + break + + self.msleep(500) # From the gui, this helps show something is actually happening + + self.show_channel__signal.emit(int(channel)) + self.set_gui_elements_enabled__signal.emit(True) +\end{lstlisting} +\subsubsection{Description} +This code shows how we change the 2.4GHz radio channel on the Rocket M2 radios. In the first method, the class initializes an ssh connection to the access point radio. Then, in the thread's main loop, apply\_channel\_if\_needed runs on a regular basis waiting for a channel change to happen. Once it does, it executes an ssh command to change the channel via command line before running a second command via the third method to get the new channel from the radio, parse it, and show it in the GUI. This ensures that if the channel does not get set, the value shown in the GUI will alert the user to this fact. + +\subsection{Compass Rotation} +\subsubsection{Code} +\begin{lstlisting}[language=python] +ROTATION_SPEED_MODIFIER = 2.5 + +def rotate_compass_if_needed(self): + heading_difference = abs(int(self.shown_heading) - self.current_heading) + should_update = False + + if heading_difference > ROTATION_SPEED_MODIFIER: + self.shown_heading += self.rotation_direction * ROTATION_SPEED_MODIFIER + self.shown_heading %= 360 + should_update = True + elif heading_difference != 0: + self.shown_heading = self.current_heading + should_update = True + + if should_update: + self.current_heading_shown_rotation_angle = int(self.shown_heading) + + if self.current_heading_shown_rotation_angle != self.last_current_heading_shown: + new_compass_image = self.main_compass_image.rotate(self.current_heading_shown_rotation_angle, resample=PIL.Image.BICUBIC) + self.last_current_heading_shown = self.current_heading_shown_rotation_angle + + self.compass_pixmap = QtGui.QPixmap.fromImage(ImageQt(new_compass_image)) + self.show_compass_image__signal.emit() + +def update_heading_movement(self): + current_minus_shown = (self.current_heading - self.shown_heading) % 360 + + if current_minus_shown >= 180: + self.rotation_direction = -1 + else: + self.rotation_direction = 1 +\end{lstlisting} +\subsubsection{Description} +This code shows how movement updates to the compass are made. The second method gets called when a new heading change is made, setting whichever rotation direction is shorter to reach the desired goal. Then, in the main loop, the upper method calculates the difference between the current shown heading and the actual heading determining whether it should be moving or not. If it should, the main compass image that was loaded during init is rotated via a bicubic sampling algorithm to maintain image clarity, converted to a QPixmap, before an update signal is broadcast to the main thread to show the image. \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/11-miscellaneous/miscellaneous.tex b/cs_capstone_documents/spring_final_report/11-miscellaneous/miscellaneous.tex new file mode 100644 index 0000000..0cb0aa1 --- /dev/null +++ b/cs_capstone_documents/spring_final_report/11-miscellaneous/miscellaneous.tex @@ -0,0 +1,29 @@ +\section{Appendix 2} +\subsection{Ground Station Final Photos} +\begin{figure}[h!] + \centering + \captionsetup{justification=centering} + \includegraphics[width=0.9\textwidth]{misc_media/ground_station_framed} + \caption{Finished Ground Station Hardware} +\end{figure} + +\begin{figure}[h!] + \centering + \captionsetup{justification=centering} + \includegraphics[width=0.9\textwidth]{misc_media/ground_station_screenshot} + \caption{Finished Ground Station Screenshot} +\end{figure} + +\begin{figure}[h!] + \centering + \captionsetup{justification=centering} + \includegraphics[width=0.9\textwidth]{misc_media/ground_station_expo} + \caption{Finished Ground Station at Expo} +\end{figure} + +\begin{figure}[h!] + \centering + \captionsetup{justification=centering} + \includegraphics[width=0.9\textwidth]{misc_media/ground_station_expo_2} + \caption{Chatting with TA at Expo} +\end{figure} \ No newline at end of file diff --git a/cs_capstone_documents/spring_final_report/IEEEtran.cls b/cs_capstone_documents/spring_final_report/IEEEtran.cls new file mode 100644 index 0000000..8d2b1c6 --- /dev/null +++ b/cs_capstone_documents/spring_final_report/IEEEtran.cls @@ -0,0 +1,6347 @@ +%% +%% IEEEtran.cls 2015/08/26 version V1.8b +%% +%% This is the IEEEtran LaTeX class for authors of the Institute of +%% Electrical and Electronics Engineers (IEEE) Transactions journals and +%% conferences. +%% +%% Support sites: +%% http://www.michaelshell.org/tex/ieeetran/ +%% http://www.ctan.org/pkg/ieeetran +%% and +%% http://www.ieee.org/ +%% +%% Based on the original 1993 IEEEtran.cls, but with many bug fixes +%% and enhancements (from both JVH and MDS) over the 1996/7 version. +%% +%% +%% Contributors: +%% Gerry Murray (1993), Silvano Balemi (1993), +%% Jon Dixon (1996), Peter N"uchter (1996), +%% Juergen von Hagen (2000), and Michael Shell (2001-2014) +%% +%% +%% Copyright (c) 1993-2000 by Gerry Murray, Silvano Balemi, +%% Jon Dixon, Peter N"uchter, +%% Juergen von Hagen +%% and +%% Copyright (c) 2001-2015 by Michael Shell +%% +%% Current maintainer (V1.3 to V1.8b): Michael Shell +%% See: +%% http://www.michaelshell.org/ +%% for current contact information. +%% +%% Special thanks to Peter Wilson (CUA) and Donald Arseneau +%% for allowing the inclusion of the \@ifmtarg command +%% from their ifmtarg LaTeX package. +%% +%%************************************************************************* +%% Legal Notice: +%% This code is offered as-is without any warranty either expressed or +%% implied; without even the implied warranty of MERCHANTABILITY or +%% FITNESS FOR A PARTICULAR PURPOSE! +%% User assumes all risk. +%% In no event shall the IEEE or any contributor to this code be liable for +%% any damages or losses, including, but not limited to, incidental, +%% consequential, or any other damages, resulting from the use or misuse +%% of any information contained here. +%% +%% All comments are the opinions of their respective authors and are not +%% necessarily endorsed by the IEEE. +%% +%% This work is distributed under the LaTeX Project Public License (LPPL) +%% ( http://www.latex-project.org/ ) version 1.3, and may be freely used, +%% distributed and modified. A copy of the LPPL, version 1.3, is included +%% in the base LaTeX documentation of all distributions of LaTeX released +%% 2003/12/01 or later. +%% Retain all contribution notices and credits. +%% ** Modified files should be clearly indicated as such, including ** +%% ** renaming them and changing author support contact information. ** +%% +%% File list of work: IEEEtran.cls, IEEEtran_HOWTO.pdf, bare_adv.tex, +%% bare_conf.tex, bare_jrnl.tex, bare_conf_compsoc.tex, +%% bare_jrnl_compsoc.tex +%% +%% Major changes to the user interface should be indicated by an +%% increase in the version numbers. If a version is a beta, it will +%% be indicated with a BETA suffix, i.e., 1.4 BETA. +%% Small changes can be indicated by appending letters to the version +%% such as "IEEEtran_v14a.cls". +%% In all cases, \Providesclass, any \typeout messages to the user, +%% \IEEEtransversionmajor and \IEEEtransversionminor must reflect the +%% correct version information. +%% The changes should also be documented via source comments. +%%************************************************************************* +%% +% +% Available class options +% e.g., \documentclass[10pt,conference]{IEEEtran} +% +% *** choose only one from each category *** +% +% 9pt, 10pt, 11pt, 12pt +% Sets normal font size. The default is 10pt. +% +% conference, journal, technote, peerreview, peerreviewca +% determines format mode - conference papers, journal papers, +% correspondence papers (technotes), or peer review papers. The user +% should also select 9pt when using technote. peerreview is like +% journal mode, but provides for a single-column "cover" title page for +% anonymous peer review. The paper title (without the author names) is +% repeated at the top of the page after the cover page. For peer review +% papers, the \IEEEpeerreviewmaketitle command must be executed (will +% automatically be ignored for non-peerreview modes) at the place the +% cover page is to end, usually just after the abstract (keywords are +% not normally used with peer review papers). peerreviewca is like +% peerreview, but allows the author names to be entered and formatted +% as with conference mode so that author affiliation and contact +% information can be easily seen on the cover page. +% The default is journal. +% +% draft, draftcls, draftclsnofoot, final +% determines if paper is formatted as a widely spaced draft (for +% handwritten editor comments) or as a properly typeset final version. +% draftcls restricts draft mode to the class file while all other LaTeX +% packages (i.e., \usepackage{graphicx}) will behave as final - allows +% for a draft paper with visible figures, etc. draftclsnofoot is like +% draftcls, but does not display the date and the word "DRAFT" at the foot +% of the pages. If using one of the draft modes, the user will probably +% also want to select onecolumn. +% The default is final. +% +% letterpaper, a4paper, cspaper +% determines paper size: 8.5in X 11in, 210mm X 297mm or 7.875in X 10.75in. +% Changing the paper size in the standard journal and conference modes +% will not alter the typesetting of the document - only the margins will +% be affected. In particular, documents using the a4paper option will +% have reduced side margins (A4 is narrower than US letter) and a longer +% bottom margin (A4 is longer than US letter). For both cases, the top +% margins will be the same and the text will be horizontally centered. +% For the compsoc conference and draft modes, it is the margins that will +% remain constant, and thus the text area size will vary, with changes in +% the paper size. +% The cspaper option is the special ``trim'' paper size (7.875in x 10.75in) +% used in the actual publication of Computer Society journals. Under +% compsoc journal mode, this option does not alter the typesetting of the +% document. Authors should invoke the cspaper option only if requested to +% do so by the editors of the specific journal they are submitting to. +% For final submission to the IEEE, authors should generally use US letter +% (8.5 X 11in) paper unless otherwise instructed. Note that authors should +% ensure that all post-processing (ps, pdf, etc.) uses the same paper +% specificiation as the .tex document. Problems here are by far the number +% one reason for incorrect margins. IEEEtran will automatically set the +% default paper size under pdflatex (without requiring any change to +% pdftex.cfg), so this issue is more important to dvips users. Fix +% config.ps, config.pdf, or ~/.dvipsrc for dvips, or use the +% dvips -t papersize option instead as needed. For the cspaper option, +% the corresponding dvips paper name is "ieeecs". +% See the testflow documentation +% http://www.ctan.org/tex-archive/macros/latex/contrib/IEEEtran/testflow +% for more details on dvips paper size configuration. +% The default is letterpaper. +% +% oneside, twoside +% determines if layout follows single sided or two sided (duplex) +% printing. The only notable change is with the headings at the top of +% the pages. +% The default is oneside. +% +% onecolumn, twocolumn +% determines if text is organized into one or two columns per page. One +% column mode is usually used only with draft papers. +% The default is twocolumn. +% +% comsoc, compsoc, transmag +% Use the format of the IEEE Communications Society, IEEE Computer Society +% or IEEE Transactions on Magnetics, respectively. +% +% romanappendices +% Use the "Appendix I" convention when numbering appendices. IEEEtran.cls +% now defaults to Alpha "Appendix A" convention - the opposite of what +% v1.6b and earlier did. +% +% captionsoff +% disables the display of the figure/table captions. Some IEEE journals +% request that captions be removed and figures/tables be put on pages +% of their own at the end of an initial paper submission. The endfloat +% package can be used with this class option to achieve this format. +% +% nofonttune +% turns off tuning of the font interword spacing. Maybe useful to those +% not using the standard Times fonts or for those who have already "tuned" +% their fonts. +% The default is to enable IEEEtran to tune font parameters. +% +% +%---------- +% Available CLASSINPUTs provided (all are macros unless otherwise noted): +% \CLASSINPUTbaselinestretch +% \CLASSINPUTinnersidemargin +% \CLASSINPUToutersidemargin +% \CLASSINPUTtoptextmargin +% \CLASSINPUTbottomtextmargin +% +% Available CLASSINFOs provided: +% \ifCLASSINFOpdf (TeX if conditional) +% \CLASSINFOpaperwidth (macro) +% \CLASSINFOpaperheight (macro) +% \CLASSINFOnormalsizebaselineskip (length) +% \CLASSINFOnormalsizeunitybaselineskip (length) +% +% Available CLASSOPTIONs provided: +% all class option flags (TeX if conditionals) unless otherwise noted, +% e.g., \ifCLASSOPTIONcaptionsoff +% point size options provided as a single macro: +% \CLASSOPTIONpt +% which will be defined as 9, 10, 11, or 12 depending on the document's +% normalsize point size. +% also, class option peerreviewca implies the use of class option peerreview +% and classoption draft implies the use of class option draftcls + + + + + +\ProvidesClass{IEEEtran}[2015/08/26 V1.8b by Michael Shell] +\typeout{-- See the "IEEEtran_HOWTO" manual for usage information.} +\typeout{-- http://www.michaelshell.org/tex/ieeetran/} +\NeedsTeXFormat{LaTeX2e} + +% IEEEtran.cls version numbers, provided as of V1.3 +% These values serve as a way a .tex file can +% determine if the new features are provided. +% The version number of this IEEEtrans.cls can be obtained from +% these values. i.e., V1.4 +% KEEP THESE AS INTEGERS! i.e., NO {4a} or anything like that- +% (no need to enumerate "a" minor changes here) +\def\IEEEtransversionmajor{1} +\def\IEEEtransversionminor{8} + + +% hook to allow easy changeover to IEEEtran.cls/tools.sty error reporting +\def\@IEEEclspkgerror{\ClassError{IEEEtran}} + + +% These do nothing, but provide them like in article.cls +\newif\if@restonecol +\newif\if@titlepage + + +% class option conditionals +\newif\ifCLASSOPTIONonecolumn \CLASSOPTIONonecolumnfalse +\newif\ifCLASSOPTIONtwocolumn \CLASSOPTIONtwocolumntrue + +\newif\ifCLASSOPTIONoneside \CLASSOPTIONonesidetrue +\newif\ifCLASSOPTIONtwoside \CLASSOPTIONtwosidefalse + +\newif\ifCLASSOPTIONfinal \CLASSOPTIONfinaltrue +\newif\ifCLASSOPTIONdraft \CLASSOPTIONdraftfalse +\newif\ifCLASSOPTIONdraftcls \CLASSOPTIONdraftclsfalse +\newif\ifCLASSOPTIONdraftclsnofoot \CLASSOPTIONdraftclsnofootfalse + +\newif\ifCLASSOPTIONpeerreview \CLASSOPTIONpeerreviewfalse +\newif\ifCLASSOPTIONpeerreviewca \CLASSOPTIONpeerreviewcafalse + +\newif\ifCLASSOPTIONjournal \CLASSOPTIONjournaltrue +\newif\ifCLASSOPTIONconference \CLASSOPTIONconferencefalse +\newif\ifCLASSOPTIONtechnote \CLASSOPTIONtechnotefalse + +\newif\ifCLASSOPTIONnofonttune \CLASSOPTIONnofonttunefalse + +\newif\ifCLASSOPTIONcaptionsoff \CLASSOPTIONcaptionsofffalse + +\newif\ifCLASSOPTIONcomsoc \CLASSOPTIONcomsocfalse +\newif\ifCLASSOPTIONcompsoc \CLASSOPTIONcompsocfalse +\newif\ifCLASSOPTIONtransmag \CLASSOPTIONtransmagfalse + +\newif\ifCLASSOPTIONromanappendices \CLASSOPTIONromanappendicesfalse + + +% class info conditionals + +% indicates if pdf (via pdflatex) output +\newif\ifCLASSINFOpdf \CLASSINFOpdffalse + + +% V1.6b internal flag to show if using a4paper +\newif\if@IEEEusingAfourpaper \@IEEEusingAfourpaperfalse +% V1.6b internal flag to show if using cspaper +\newif\if@IEEEusingcspaper \@IEEEusingcspaperfalse + + +% IEEEtran class scratch pad registers +% dimen +\newdimen\@IEEEtrantmpdimenA +\newdimen\@IEEEtrantmpdimenB +\newdimen\@IEEEtrantmpdimenC +% count +\newcount\@IEEEtrantmpcountA +\newcount\@IEEEtrantmpcountB +\newcount\@IEEEtrantmpcountC +% token list +\newtoks\@IEEEtrantmptoksA + +% we use \CLASSOPTIONpt so that we can ID the point size (even for 9pt docs) +% as well as LaTeX's \@ptsize to retain some compatability with some +% external packages +\def\@ptsize{0} +% LaTeX does not support 9pt, so we set \@ptsize to 0 - same as that of 10pt +\DeclareOption{9pt}{\def\CLASSOPTIONpt{9}\def\@ptsize{0}} +\DeclareOption{10pt}{\def\CLASSOPTIONpt{10}\def\@ptsize{0}} +\DeclareOption{11pt}{\def\CLASSOPTIONpt{11}\def\@ptsize{1}} +\DeclareOption{12pt}{\def\CLASSOPTIONpt{12}\def\@ptsize{2}} + + + +\DeclareOption{letterpaper}{\setlength{\paperwidth}{8.5in}% + \setlength{\paperheight}{11in}% + \@IEEEusingAfourpaperfalse + \@IEEEusingcspaperfalse + \def\CLASSOPTIONpaper{letter}% + \def\CLASSINFOpaperwidth{8.5in}% + \def\CLASSINFOpaperheight{11in}} + + +\DeclareOption{a4paper}{\setlength{\paperwidth}{210mm}% + \setlength{\paperheight}{297mm}% + \@IEEEusingAfourpapertrue + \@IEEEusingcspaperfalse + \def\CLASSOPTIONpaper{a4}% + \def\CLASSINFOpaperwidth{210mm}% + \def\CLASSINFOpaperheight{297mm}} + +% special paper option for compsoc journals +\DeclareOption{cspaper}{\setlength{\paperwidth}{7.875in}% + \setlength{\paperheight}{10.75in}% + \@IEEEusingcspapertrue + \@IEEEusingAfourpaperfalse + \def\CLASSOPTIONpaper{ieeecs}% + \def\CLASSINFOpaperwidth{7.875in}% + \def\CLASSINFOpaperheight{10.75in}} + +\DeclareOption{oneside}{\@twosidefalse\@mparswitchfalse + \CLASSOPTIONonesidetrue\CLASSOPTIONtwosidefalse} +\DeclareOption{twoside}{\@twosidetrue\@mparswitchtrue + \CLASSOPTIONtwosidetrue\CLASSOPTIONonesidefalse} + +\DeclareOption{onecolumn}{\CLASSOPTIONonecolumntrue\CLASSOPTIONtwocolumnfalse} +\DeclareOption{twocolumn}{\CLASSOPTIONtwocolumntrue\CLASSOPTIONonecolumnfalse} + +% If the user selects draft, then this class AND any packages +% will go into draft mode. +\DeclareOption{draft}{\CLASSOPTIONdrafttrue\CLASSOPTIONdraftclstrue + \CLASSOPTIONdraftclsnofootfalse} +% draftcls is for a draft mode which will not affect any packages +% used by the document. +\DeclareOption{draftcls}{\CLASSOPTIONdraftfalse\CLASSOPTIONdraftclstrue + \CLASSOPTIONdraftclsnofootfalse} +% draftclsnofoot is like draftcls, but without the footer. +\DeclareOption{draftclsnofoot}{\CLASSOPTIONdraftfalse\CLASSOPTIONdraftclstrue + \CLASSOPTIONdraftclsnofoottrue} +\DeclareOption{final}{\CLASSOPTIONdraftfalse\CLASSOPTIONdraftclsfalse + \CLASSOPTIONdraftclsnofootfalse} + +\DeclareOption{journal}{\CLASSOPTIONpeerreviewfalse\CLASSOPTIONpeerreviewcafalse + \CLASSOPTIONjournaltrue\CLASSOPTIONconferencefalse\CLASSOPTIONtechnotefalse} + +\DeclareOption{conference}{\CLASSOPTIONpeerreviewfalse\CLASSOPTIONpeerreviewcafalse + \CLASSOPTIONjournalfalse\CLASSOPTIONconferencetrue\CLASSOPTIONtechnotefalse} + +\DeclareOption{technote}{\CLASSOPTIONpeerreviewfalse\CLASSOPTIONpeerreviewcafalse + \CLASSOPTIONjournalfalse\CLASSOPTIONconferencefalse\CLASSOPTIONtechnotetrue} + +\DeclareOption{peerreview}{\CLASSOPTIONpeerreviewtrue\CLASSOPTIONpeerreviewcafalse + \CLASSOPTIONjournalfalse\CLASSOPTIONconferencefalse\CLASSOPTIONtechnotefalse} + +\DeclareOption{peerreviewca}{\CLASSOPTIONpeerreviewtrue\CLASSOPTIONpeerreviewcatrue + \CLASSOPTIONjournalfalse\CLASSOPTIONconferencefalse\CLASSOPTIONtechnotefalse} + +\DeclareOption{nofonttune}{\CLASSOPTIONnofonttunetrue} + +\DeclareOption{captionsoff}{\CLASSOPTIONcaptionsofftrue} + +\DeclareOption{comsoc}{\CLASSOPTIONcomsoctrue\CLASSOPTIONcompsocfalse\CLASSOPTIONtransmagfalse} + +\DeclareOption{compsoc}{\CLASSOPTIONcomsocfalse\CLASSOPTIONcompsoctrue\CLASSOPTIONtransmagfalse} + +\DeclareOption{transmag}{\CLASSOPTIONtransmagtrue\CLASSOPTIONcomsocfalse\CLASSOPTIONcompsocfalse} + +\DeclareOption{romanappendices}{\CLASSOPTIONromanappendicestrue} + + +% default to US letter paper, 10pt, twocolumn, one sided, final, journal +\ExecuteOptions{letterpaper,10pt,twocolumn,oneside,final,journal} +% overrride these defaults per user requests +\ProcessOptions + + + +%% -- Command Argument Scanning Support Functions -- + +% Sets the category codes for punctuation to their normal values. +% For local use with argument scanning. +\def\IEEEnormalcatcodespunct{\catcode`\!=12 \catcode`\,=12 \catcode`\:=12 +\catcode`\;=12 \catcode`\`=12 \catcode`\'=12 \catcode`\"=12 \catcode`\.=12 +\catcode`\/=12 \catcode`\?=12 \catcode`\*=12 \catcode`\+=12 \catcode`\-=12 +\catcode`\<=12 \catcode`\>=12 \catcode`\(=12 \catcode`\)=12 \catcode`\[=12 +\catcode`\]=12 \catcode`\==12 \catcode`\|=12} +% Sets the category codes for numbers to their normal values. +% For local use with argument scanning. +\def\IEEEnormalcatcodesnum{\catcode`\0=12 \catcode`\1=12 \catcode`\2=12 +\catcode`\3=12 \catcode`\4=12 \catcode`\5=12 \catcode`\6=12 \catcode`\7=12 +\catcode`\8=12 \catcode`\9=12} +% combined action of \IEEEnormalcatcodespunct and \IEEEnormalcatcodesnum +\def\IEEEnormalcatcodes{\IEEEnormalcatcodespunct\IEEEnormalcatcodesnum} + + +% usage: \@IEEEextracttoken*{} +% \@IEEEextracttoken fully expands its argument (which it then stores in +% \@IEEEextracttokenarg) via \edef and then the meaning of the first +% nonbrace (but including the empty group) token found is assigned via \let +% to \@IEEEextractedtoken as well as stored in the macro +% \@IEEEextractedtokenmacro. Tokens that would otherwise be discarded during +% the acquisition of the first are stored in \@IEEEextractedtokensdiscarded, +% however their original relative brace nesting depths are not guaranteed to +% be preserved. +% If the argument is empty, or if a first nonbrace token does not exist (or +% is an empty group), \@IEEEextractedtoken will be \relax and +% \@IEEEextractedtokenmacro and \@IEEEextractedtokensdiscarded will be empty. +% +% For example: +% \@IEEEextracttoken{{{ab}{cd}}{{ef}g}} +% results in: +% +% \@IEEEextracttokenarg ==> a macro containing {{ab}{cd}}{{ef}g} +% \@IEEEextractedtoken ==> the letter a +% \@IEEEextractedtokenmacro ==> a macro containing a +% \@IEEEextractedtokensdiscarded ==> a macro containing bcd{ef}g +% +% the *-star form, \@IEEEextracttoken*, does not expand its argument +% contents during processing. +\def\@IEEEextracttoken{\@ifstar{\let\@IEEEextracttokendef=\def\@@IEEEextracttoken}{\let\@IEEEextracttokendef=\edef\@@IEEEextracttoken}} + +\def\@@IEEEextracttoken#1{\@IEEEextracttokendef\@IEEEextracttokenarg{#1}\relax +\def\@IEEEextractedtokensdiscarded{}\relax % initialize to empty +% if the macro is unchanged after being acquired as a single undelimited argument +% with anything after it being stripped off as a delimited argument +% we know we have one token without any enclosing braces. loop until this is true. +\let\@IEEEextracttokencurgroup\@IEEEextracttokenarg +\loop + % trap case of an empty argument as this would cause a problem with + % \@@@IEEEextracttoken's first (nondelimited) argument acquisition + \ifx\@IEEEextracttokencurgroup\@empty + \def\@IEEEextractedtokenmacro{}\relax + \else + \expandafter\@@@IEEEextracttoken\@IEEEextracttokencurgroup\@IEEEgeneralsequenceDELIMITER\relax + \fi + \ifx\@IEEEextractedtokenmacro\@IEEEextracttokencurgroup + \else + \let\@IEEEextracttokencurgroup=\@IEEEextractedtokenmacro +\repeat +% we can safely do a \let= here because there should be at most one token +% the relax is needed to handle the case of no token found +\expandafter\let\expandafter\@IEEEextractedtoken\@IEEEextractedtokenmacro\relax} + +\def\@@@IEEEextracttoken#1#2\@IEEEgeneralsequenceDELIMITER{\def\@IEEEextractedtokenmacro{#1}\relax +\def\@@IEEEextractedtokensdiscarded{#2}\expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter +\@IEEEextractedtokensdiscarded\expandafter\expandafter\expandafter +{\expandafter\@@IEEEextractedtokensdiscarded\@IEEEextractedtokensdiscarded}} +%% +%% -- End of Command Argument Scanning Support Functions -- + + + +% Computer Society conditional execution command +\long\def\@IEEEcompsoconly#1{\relax\ifCLASSOPTIONcompsoc\relax#1\relax\fi\relax} +% inverse +\long\def\@IEEEnotcompsoconly#1{\relax\ifCLASSOPTIONcompsoc\else\relax#1\relax\fi\relax} +% compsoc conference +\long\def\@IEEEcompsocconfonly#1{\relax\ifCLASSOPTIONcompsoc\ifCLASSOPTIONconference\relax#1\relax\fi\fi\relax} +% compsoc not conference +\long\def\@IEEEcompsocnotconfonly#1{\relax\ifCLASSOPTIONcompsoc\ifCLASSOPTIONconference\else\relax#1\relax\fi\fi\relax} + + +% comsoc verify that newtxmath, mtpro2, mt11p or mathtime has been loaded +\def\@IEEEcomsocverifymathfont{\typeout{-- Verifying Times compatible math font.}\relax + \@ifpackageloaded{newtxmath}{\typeout{-- newtxmath loaded, OK.}}{\@@IEEEcomsocverifymathfont}} +\def\@@IEEEcomsocverifymathfont{\@ifpackageloaded{mtpro2}{\typeout{-- mtpro2 loaded, OK.}}{\@@@IEEEcomsocverifymathfont}} +\def\@@@IEEEcomsocverifymathfont{\@ifpackageloaded{mt11p}{\typeout{-- mt11p2 loaded, OK.}}{\@@@@IEEEcomsocverifymathfont}} +\def\@@@@IEEEcomsocverifymathfont{\@ifpackageloaded{mathtime}{\typeout{-- mathtime loaded, OK.}}{\@IEEEcomsocenforcemathfont}} + +% comsoc, if a Times math font was not loaded by user, enforce it +\def\@IEEEcomsocenforcemathfont{\typeout{** Times compatible math font not found, forcing.}\relax +\IfFileExists{newtxmath.sty}{\typeout{-- Found newtxmath, loading.}\RequirePackage{newtxmath}}{\@@IEEEcomsocenforcemathfont}} +\def\@@IEEEcomsocenforcemathfont{\IfFileExists{mtpro2.sty}{\typeout{-- Found mtpro2, loading.}\RequirePackage{mtpro2}}{\@@@IEEEcomsocenforcemathfont}} +\def\@@@IEEEcomsocenforcemathfont{\IfFileExists{mt11p.sty}{\typeout{-- Found mt11p, loading.}\RequirePackage{mt11p}}{\@@@@IEEEcomsocenforcemathfont}} +\def\@@@@IEEEcomsocenforcemathfont{\IfFileExists{mathtime.sty}{\typeout{-- Found mathtime, loading.}\RequirePackage{mathtime}}{\@@@@@IEEEcomsocenforcemathfont}} +% if no acceptable Times math font package found, error with newtxmath requirement +\def\@@@@@IEEEcomsocenforcemathfont{\typeout{** No Times compatible math font package found. newtxmath is required.}\RequirePackage{newtxmath}} + + +\ifCLASSOPTIONcomsoc + % ensure that if newtxmath is used, the cmintegrals option is also invoked + \PassOptionsToPackage{cmintegrals}{newtxmath} + % comsoc requires a Times like math font + % ensure this requirement is satisfied at document start + \AtBeginDocument{\@IEEEcomsocverifymathfont} +\fi + + + +% The IEEE uses Times Roman font, so we'll default to Times. +% These three commands make up the entire times.sty package. +\renewcommand{\sfdefault}{phv} +\renewcommand{\rmdefault}{ptm} +\renewcommand{\ttdefault}{pcr} + +% V1.7 compsoc nonconference papers, use Palatino/Palladio as the main text font, +% not Times Roman. +\@IEEEcompsocnotconfonly{\renewcommand{\rmdefault}{ppl}} + +% enable the selected main text font +\normalfont\selectfont + + +\ifCLASSOPTIONcomsoc + \typeout{-- Using IEEE Communications Society mode.} +\fi + +\ifCLASSOPTIONcompsoc + \typeout{-- Using IEEE Computer Society mode.} +\fi + + +% V1.7 conference notice message hook +\def\@IEEEconsolenoticeconference{\typeout{}% +\typeout{** Conference Paper **}% +\typeout{Before submitting the final camera ready copy, remember to:}% +\typeout{}% +\typeout{ 1. Manually equalize the lengths of two columns on the last page}% +\typeout{ of your paper;}% +\typeout{}% +\typeout{ 2. Ensure that any PostScript and/or PDF output post-processing}% +\typeout{ uses only Type 1 fonts and that every step in the generation}% +\typeout{ process uses the appropriate paper size.}% +\typeout{}} + + +% we can send console reminder messages to the user here +\AtEndDocument{\ifCLASSOPTIONconference\@IEEEconsolenoticeconference\fi} + + +% warn about the use of single column other than for draft mode +\ifCLASSOPTIONtwocolumn\else% + \ifCLASSOPTIONdraftcls\else% + \typeout{** ATTENTION: Single column mode is not typically used with IEEE publications.}% + \fi% +\fi + + +% V1.7 improved paper size setting code. +% Set pdfpage and dvips paper sizes. Conditional tests are similar to that +% of ifpdf.sty. Retain within {} to ensure tested macros are never altered, +% even if only effect is to set them to \relax. +% if \pdfoutput is undefined or equal to relax, output a dvips special +{\@ifundefined{pdfoutput}{\AtBeginDvi{\special{papersize=\CLASSINFOpaperwidth,\CLASSINFOpaperheight}}}{% +% pdfoutput is defined and not equal to \relax +% check for pdfpageheight existence just in case someone sets pdfoutput +% under non-pdflatex. If exists, set them regardless of value of \pdfoutput. +\@ifundefined{pdfpageheight}{\relax}{\global\pdfpagewidth\paperwidth +\global\pdfpageheight\paperheight}% +% if using \pdfoutput=0 under pdflatex, send dvips papersize special +\ifcase\pdfoutput +\AtBeginDvi{\special{papersize=\CLASSINFOpaperwidth,\CLASSINFOpaperheight}}% +\else +% we are using pdf output, set CLASSINFOpdf flag +\global\CLASSINFOpdftrue +\fi}} + +% let the user know the selected papersize +\typeout{-- Using \CLASSINFOpaperwidth\space x \CLASSINFOpaperheight\space +(\CLASSOPTIONpaper)\space paper.} + +\ifCLASSINFOpdf +\typeout{-- Using PDF output.} +\else +\typeout{-- Using DVI output.} +\fi + + +% The idea hinted here is for LaTeX to generate markleft{} and markright{} +% automatically for you after you enter \author{}, \journal{}, +% \journaldate{}, journalvol{}, \journalnum{}, etc. +% However, there may be some backward compatibility issues here as +% well as some special applications for IEEEtran.cls and special issues +% that may require the flexible \markleft{}, \markright{} and/or \markboth{}. +% We'll leave this as an open future suggestion. +%\newcommand{\journal}[1]{\def\@journal{#1}} +%\def\@journal{} + + + +% pointsize values +% used with ifx to determine the document's normal size +\def\@IEEEptsizenine{9} +\def\@IEEEptsizeten{10} +\def\@IEEEptsizeeleven{11} +\def\@IEEEptsizetwelve{12} + + + +% FONT DEFINITIONS (No sizexx.clo file needed) +% V1.6 revised font sizes, displayskip values and +% revised normalsize baselineskip to reduce underfull vbox problems +% on the 58pc = 696pt = 9.5in text height we want +% normalsize #lines/column baselineskip (aka leading) +% 9pt 63 11.0476pt (truncated down) +% 10pt 58 12pt (exact) +% 11pt 52 13.3846pt (truncated down) +% 12pt 50 13.92pt (exact) +% + +% we need to store the nominal baselineskip for the given font size +% in case baselinestretch ever changes. +% this is a dimen, so it will not hold stretch or shrink +\newdimen\@IEEEnormalsizeunitybaselineskip +\@IEEEnormalsizeunitybaselineskip\baselineskip + + + +%% ******* WARNING! ******* +%% +%% Authors should not alter font sizes, baselineskip ("leading"), +%% margins or other spacing values in an attempt to squeeze more +%% material on each page. +%% +%% The IEEE's own typesetting software will restore the correct +%% values when re-typesetting/proofing the submitted document, +%% possibly resulting in unexpected article over length charges. +%% +%% ******* WARNING! ******* + + +% 9pt option defaults +\ifx\CLASSOPTIONpt\@IEEEptsizenine +\typeout{-- This is a 9 point document.} +\def\normalsize{\@setfontsize{\normalsize}{9}{11.0476pt}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{11.0476pt} +\normalsize +\abovedisplayskip 1.5ex plus 3pt minus 1pt +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 3pt +\belowdisplayshortskip 1.5ex plus 3pt minus 1pt +\def\small{\@setfontsize{\small}{8.5}{10pt}} +\def\footnotesize{\@setfontsize{\footnotesize}{8}{9pt}} +\def\scriptsize{\@setfontsize{\scriptsize}{7}{8pt}} +\def\tiny{\@setfontsize{\tiny}{5}{6pt}} +% sublargesize is the same as large - 10pt +\def\sublargesize{\@setfontsize{\sublargesize}{10}{12pt}} +\def\large{\@setfontsize{\large}{10}{12pt}} +\def\Large{\@setfontsize{\Large}{12}{14pt}} +\def\LARGE{\@setfontsize{\LARGE}{14}{17pt}} +\def\huge{\@setfontsize{\huge}{17}{20pt}} +\def\Huge{\@setfontsize{\Huge}{20}{24pt}} +\fi +% +% 10pt option defaults +\ifx\CLASSOPTIONpt\@IEEEptsizeten +\typeout{-- This is a 10 point document.} +\def\normalsize{\@setfontsize{\normalsize}{10}{12.00pt}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{12pt} +\normalsize +\abovedisplayskip 1.5ex plus 4pt minus 2pt +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 4pt +\belowdisplayshortskip 1.5ex plus 4pt minus 2pt +\def\small{\@setfontsize{\small}{9}{10pt}} +\def\footnotesize{\@setfontsize{\footnotesize}{8}{9pt}} +\def\scriptsize{\@setfontsize{\scriptsize}{7}{8pt}} +\def\tiny{\@setfontsize{\tiny}{5}{6pt}} +% sublargesize is a tad smaller than large - 11pt +\def\sublargesize{\@setfontsize{\sublargesize}{11}{13.4pt}} +\def\large{\@setfontsize{\large}{12}{14pt}} +\def\Large{\@setfontsize{\Large}{14}{17pt}} +\def\LARGE{\@setfontsize{\LARGE}{17}{20pt}} +\def\huge{\@setfontsize{\huge}{20}{24pt}} +\def\Huge{\@setfontsize{\Huge}{24}{28pt}} +\fi +% +% 11pt option defaults +\ifx\CLASSOPTIONpt\@IEEEptsizeeleven +\typeout{-- This is an 11 point document.} +\def\normalsize{\@setfontsize{\normalsize}{11}{13.3846pt}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{13.3846pt} +\normalsize +\abovedisplayskip 1.5ex plus 5pt minus 3pt +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 5pt +\belowdisplayshortskip 1.5ex plus 5pt minus 3pt +\def\small{\@setfontsize{\small}{10}{12pt}} +\def\footnotesize{\@setfontsize{\footnotesize}{9}{10.5pt}} +\def\scriptsize{\@setfontsize{\scriptsize}{8}{9pt}} +\def\tiny{\@setfontsize{\tiny}{6}{7pt}} +% sublargesize is the same as large - 12pt +\def\sublargesize{\@setfontsize{\sublargesize}{12}{14pt}} +\def\large{\@setfontsize{\large}{12}{14pt}} +\def\Large{\@setfontsize{\Large}{14}{17pt}} +\def\LARGE{\@setfontsize{\LARGE}{17}{20pt}} +\def\huge{\@setfontsize{\huge}{20}{24pt}} +\def\Huge{\@setfontsize{\Huge}{24}{28pt}} +\fi +% +% 12pt option defaults +\ifx\CLASSOPTIONpt\@IEEEptsizetwelve +\typeout{-- This is a 12 point document.} +\def\normalsize{\@setfontsize{\normalsize}{12}{13.92pt}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{13.92pt} +\normalsize +\abovedisplayskip 1.5ex plus 6pt minus 4pt +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 6pt +\belowdisplayshortskip 1.5ex plus 6pt minus 4pt +\def\small{\@setfontsize{\small}{10}{12pt}} +\def\footnotesize{\@setfontsize{\footnotesize}{9}{10.5pt}} +\def\scriptsize{\@setfontsize{\scriptsize}{8}{9pt}} +\def\tiny{\@setfontsize{\tiny}{6}{7pt}} +% sublargesize is the same as large - 14pt +\def\sublargesize{\@setfontsize{\sublargesize}{14}{17pt}} +\def\large{\@setfontsize{\large}{14}{17pt}} +\def\Large{\@setfontsize{\Large}{17}{20pt}} +\def\LARGE{\@setfontsize{\LARGE}{20}{24pt}} +\def\huge{\@setfontsize{\huge}{22}{26pt}} +\def\Huge{\@setfontsize{\Huge}{24}{28pt}} +\fi + + + +% V1.8a compsoc font sizes +% compsoc font sizes use bp "Postscript" point units (1/72in) +% rather than the traditional pt (1/72.27) +\ifCLASSOPTIONcompsoc +% -- compsoc defaults -- +% ** will override some of these values later ** +% 9pt +\ifx\CLASSOPTIONpt\@IEEEptsizenine +\def\normalsize{\@setfontsize{\normalsize}{9bp}{11bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{11bp} +\normalsize +\abovedisplayskip 1.5ex plus 3bp minus 1bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0bp plus 3bp +\belowdisplayshortskip 1.5ex plus 3bp minus 1bp +\def\small{\@setfontsize{\small}{8.5bp}{10bp}} +\def\footnotesize{\@setfontsize{\footnotesize}{8bp}{9bp}} +\def\scriptsize{\@setfontsize{\scriptsize}{7bp}{8bp}} +\def\tiny{\@setfontsize{\tiny}{5bp}{6bp}} +% sublargesize is the same as large - 10bp +\def\sublargesize{\@setfontsize{\sublargesize}{10bp}{12bp}} +\def\large{\@setfontsize{\large}{10bp}{12bp}} +\def\Large{\@setfontsize{\Large}{12bp}{14bp}} +\def\LARGE{\@setfontsize{\LARGE}{14bp}{17bp}} +\def\huge{\@setfontsize{\huge}{17bp}{20bp}} +\def\Huge{\@setfontsize{\Huge}{20bp}{24bp}} +\fi +% +% 10pt +\ifx\CLASSOPTIONpt\@IEEEptsizeten +\def\normalsize{\@setfontsize{\normalsize}{10bp}{12bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{12bp} +\normalsize +\abovedisplayskip 1.5ex plus 4bp minus 2bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 4bp +\belowdisplayshortskip 1.5ex plus 4bp minus 2bp +\def\small{\@setfontsize{\small}{9bp}{10bp}} +\def\footnotesize{\@setfontsize{\footnotesize}{8bp}{9bp}} +\def\scriptsize{\@setfontsize{\scriptsize}{7bp}{8bp}} +\def\tiny{\@setfontsize{\tiny}{5bp}{6bp}} +% sublargesize is a tad smaller than large - 11bp +\def\sublargesize{\@setfontsize{\sublargesize}{11bp}{13.5bp}} +\def\large{\@setfontsize{\large}{12bp}{14bp}} +\def\Large{\@setfontsize{\Large}{14bp}{17bp}} +\def\LARGE{\@setfontsize{\LARGE}{17bp}{20bp}} +\def\huge{\@setfontsize{\huge}{20bp}{24bp}} +\def\Huge{\@setfontsize{\Huge}{24bp}{28bp}} +\fi +% +% 11pt +\ifx\CLASSOPTIONpt\@IEEEptsizeeleven +\def\normalsize{\@setfontsize{\normalsize}{11bp}{13.5bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{13.5bp} +\normalsize +\abovedisplayskip 1.5ex plus 5bp minus 3bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 5bp +\belowdisplayshortskip 1.5ex plus 5bp minus 3bp +\def\small{\@setfontsize{\small}{10bp}{12bp}} +\def\footnotesize{\@setfontsize{\footnotesize}{9bp}{10.5bp}} +\def\scriptsize{\@setfontsize{\scriptsize}{8bp}{9bp}} +\def\tiny{\@setfontsize{\tiny}{6bp}{7bp}} +% sublargesize is the same as large - 12bp +\def\sublargesize{\@setfontsize{\sublargesize}{12bp}{14bp}} +\def\large{\@setfontsize{\large}{12bp}{14bp}} +\def\Large{\@setfontsize{\Large}{14bp}{17bp}} +\def\LARGE{\@setfontsize{\LARGE}{17bp}{20bp}} +\def\huge{\@setfontsize{\huge}{20bp}{24bp}} +\def\Huge{\@setfontsize{\Huge}{24bp}{28bp}} +\fi +% +% 12pt +\ifx\CLASSOPTIONpt\@IEEEptsizetwelve +\def\normalsize{\@setfontsize{\normalsize}{12bp}{14bp}}% +\setlength{\@IEEEnormalsizeunitybaselineskip}{14bp}% +\normalsize +\abovedisplayskip 1.5ex plus 6bp minus 4bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 6bp +\belowdisplayshortskip 1.5ex plus 6bp minus 4bp +\def\small{\@setfontsize{\small}{10bp}{12bp}} +\def\footnotesize{\@setfontsize{\footnotesize}{9bp}{10.5bp}} +\def\scriptsize{\@setfontsize{\scriptsize}{8bp}{9bp}} +\def\tiny{\@setfontsize{\tiny}{6bp}{7bp}} +% sublargesize is the same as large - 14bp +\def\sublargesize{\@setfontsize{\sublargesize}{14bp}{17bp}} +\def\large{\@setfontsize{\large}{14bp}{17bp}} +\def\Large{\@setfontsize{\Large}{17bp}{20bp}} +\def\LARGE{\@setfontsize{\LARGE}{20bp}{24bp}} +\def\huge{\@setfontsize{\huge}{22bp}{26bp}} +\def\Huge{\@setfontsize{\Huge}{24bp}{28bp}} +\fi +% +% -- override defaults: compsoc journals use special normalsizes -- +\ifCLASSOPTIONconference +% +% compsoc conferences +% 9pt +\ifx\CLASSOPTIONpt\@IEEEptsizenine +\def\normalsize{\@setfontsize{\normalsize}{9bp}{10.8bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{10.8bp} +\normalsize +\abovedisplayskip 1.5ex plus 3bp minus 1bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0bp plus 3bp +\belowdisplayshortskip 1.5ex plus 3bp minus 1bp +\fi +% 10pt +\ifx\CLASSOPTIONpt\@IEEEptsizeten +\def\normalsize{\@setfontsize{\normalsize}{10bp}{11.2bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{11.2bp} +\normalsize +\abovedisplayskip 1.5ex plus 4bp minus 2bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 4bp +\belowdisplayshortskip 1.5ex plus 4bp minus 2bp +\fi +% 11pt +\ifx\CLASSOPTIONpt\@IEEEptsizeeleven +\def\normalsize{\@setfontsize{\normalsize}{11bp}{13.2bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{13.2bp} +\normalsize +\abovedisplayskip 1.5ex plus 5bp minus 3bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 5bp +\belowdisplayshortskip 1.5ex plus 5bp minus 3bp +\fi +% 12pt +\ifx\CLASSOPTIONpt\@IEEEptsizetwelve +\def\normalsize{\@setfontsize{\normalsize}{12bp}{14.4bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{14.4bp} +\normalsize +\abovedisplayskip 1.5ex plus 6bp minus 4bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 6bp +\belowdisplayshortskip 1.5ex plus 6bp minus 4bp +\fi +% +% compsoc nonconferences +\else +% 9pt +\ifx\CLASSOPTIONpt\@IEEEptsizenine +\def\normalsize{\@setfontsize{\normalsize}{9bp}{10.8bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{10.8bp} +\normalsize +\abovedisplayskip 1.5ex plus 3bp minus 1bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0bp plus 3bp +\belowdisplayshortskip 1.5ex plus 3bp minus 1bp +\fi +% 10pt +\ifx\CLASSOPTIONpt\@IEEEptsizeten +% the official spec is 9.5bp with 11.4bp leading for 10pt, +% but measurements of proofs suggest upto 11.723bp leading +% here we'll use 11.54bp which gives 61 lines per column +% with the standard compsoc margins +\def\normalsize{\@setfontsize{\normalsize}{9.5bp}{11.54bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{11.54bp} +\normalsize +\abovedisplayskip 1.5ex plus 4bp minus 2bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 4bp +\belowdisplayshortskip 1.5ex plus 4bp minus 2bp +\fi +% 11pt +\ifx\CLASSOPTIONpt\@IEEEptsizeeleven +\def\normalsize{\@setfontsize{\normalsize}{11bp}{13.2bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{13.2bp} +\normalsize +\abovedisplayskip 1.5ex plus 5bp minus 3bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 5bp +\belowdisplayshortskip 1.5ex plus 5bp minus 3bp +\fi +% 12pt +\ifx\CLASSOPTIONpt\@IEEEptsizetwelve +\def\normalsize{\@setfontsize{\normalsize}{12bp}{14.4bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{14.4bp} +\normalsize +\abovedisplayskip 1.5ex plus 6bp minus 4bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 6bp +\belowdisplayshortskip 1.5ex plus 6bp minus 4bp +\fi +\fi\fi + + + + +% V1.6 The Computer Modern Fonts will issue a substitution warning for +% 24pt titles (24.88pt is used instead, but the default and correct +% Times font will scale exactly as needed) increase the substitution +% tolerance to turn off this warning. +% +% V1.8a, the compsoc bp font sizes can also cause bogus font substitution +% warnings with footnote or scriptsize math and the $\bullet$ itemized +% list of \IEEEcompsocitemizethanks. So, increase this to 1.5pt or more. +\def\fontsubfuzz{1.7bp} + + +% warn the user in case they forget to use the 9pt option with +% technote +\ifCLASSOPTIONtechnote% + \ifx\CLASSOPTIONpt\@IEEEptsizenine\else% + \typeout{** ATTENTION: Technotes are normally 9pt documents.}% + \fi% +\fi + + +% V1.7 +% Improved \textunderscore to provide a much better fake _ when used with +% OT1 encoding. Under OT1, detect use of pcr or cmtt \ttfamily and use +% available true _ glyph for those two typewriter fonts. +\def\@IEEEstringptm{ptm} % Times Roman family +\def\@IEEEstringppl{ppl} % Palatino Roman family +\def\@IEEEstringphv{phv} % Helvetica Sans Serif family +\def\@IEEEstringpcr{pcr} % Courier typewriter family +\def\@IEEEstringcmtt{cmtt} % Computer Modern typewriter family +\DeclareTextCommandDefault{\textunderscore}{\leavevmode +\ifx\f@family\@IEEEstringpcr\string_\else +\ifx\f@family\@IEEEstringcmtt\string_\else +\ifx\f@family\@IEEEstringptm\kern 0em\vbox{\hrule\@width 0.5em\@height 0.5pt\kern -0.3ex}\else +\ifx\f@family\@IEEEstringppl\kern 0em\vbox{\hrule\@width 0.5em\@height 0.5pt\kern -0.3ex}\else +\ifx\f@family\@IEEEstringphv\kern -0.03em\vbox{\hrule\@width 0.62em\@height 0.52pt\kern -0.33ex}\kern -0.03em\else +\kern 0.09em\vbox{\hrule\@width 0.6em\@height 0.44pt\kern -0.63pt\kern -0.42ex}\kern 0.09em\fi\fi\fi\fi\fi\relax} + + + + +% set the default \baselinestretch +\def\baselinestretch{1} +\ifCLASSOPTIONdraftcls + \def\baselinestretch{1.5}% default baselinestretch for draft modes +\fi + + +% process CLASSINPUT baselinestretch +\ifx\CLASSINPUTbaselinestretch\@IEEEundefined +\else + \edef\baselinestretch{\CLASSINPUTbaselinestretch} % user CLASSINPUT override + \typeout{** ATTENTION: Overriding \string\baselinestretch\space to + \baselinestretch\space via \string\CLASSINPUT.} +\fi + +\small\normalsize % make \baselinestretch take affect + + + + +% store the normalsize baselineskip +\newdimen\CLASSINFOnormalsizebaselineskip +\CLASSINFOnormalsizebaselineskip=\baselineskip\relax +% and the normalsize unity (baselinestretch=1) baselineskip +% we could save a register by giving the user access to +% \@IEEEnormalsizeunitybaselineskip. However, let's protect +% its read only internal status +\newdimen\CLASSINFOnormalsizeunitybaselineskip +\CLASSINFOnormalsizeunitybaselineskip=\@IEEEnormalsizeunitybaselineskip\relax +% store the nominal value of jot +\newdimen\IEEEnormaljot +\IEEEnormaljot=0.25\baselineskip\relax + +% set \jot +\jot=\IEEEnormaljot\relax + + + + +% V1.6, we are now going to fine tune the interword spacing +% The default interword glue for Times under TeX appears to use a +% nominal interword spacing of 25% (relative to the font size, i.e., 1em) +% a maximum of 40% and a minimum of 19%. +% For example, 10pt text uses an interword glue of: +% +% 2.5pt plus 1.49998pt minus 0.59998pt +% +% However, the IEEE allows for a more generous range which reduces the need +% for hyphenation, especially for two column text. Furthermore, the IEEE +% tends to use a little bit more nominal space between the words. +% The IEEE's interword spacing percentages appear to be: +% 35% nominal +% 23% minimum +% 50% maximum +% (They may even be using a tad more for the largest fonts such as 24pt.) +% +% for bold text, the IEEE increases the spacing a little more: +% 37.5% nominal +% 23% minimum +% 55% maximum + +% here are the interword spacing ratios we'll use +% for medium (normal weight) +\def\@IEEEinterspaceratioM{0.35} +\def\@IEEEinterspaceMINratioM{0.23} +\def\@IEEEinterspaceMAXratioM{0.50} + +% for bold +\def\@IEEEinterspaceratioB{0.375} +\def\@IEEEinterspaceMINratioB{0.23} +\def\@IEEEinterspaceMAXratioB{0.55} + + +% compsoc nonconference papers use Palatino, +% tweak settings to better match the proofs +\ifCLASSOPTIONcompsoc +\ifCLASSOPTIONconference\else +% for medium (normal weight) +\def\@IEEEinterspaceratioM{0.28} +\def\@IEEEinterspaceMINratioM{0.21} +\def\@IEEEinterspaceMAXratioM{0.47} +% for bold +\def\@IEEEinterspaceratioB{0.305} +\def\@IEEEinterspaceMINratioB{0.21} +\def\@IEEEinterspaceMAXratioB{0.52} +\fi\fi + + +% command to revise the interword spacing for the current font under TeX: +% \fontdimen2 = nominal interword space +% \fontdimen3 = interword stretch +% \fontdimen4 = interword shrink +% since all changes to the \fontdimen are global, we can enclose these commands +% in braces to confine any font attribute or length changes +\def\@@@IEEEsetfontdimens#1#2#3{{% +\setlength{\@IEEEtrantmpdimenB}{\f@size pt}% grab the font size in pt, could use 1em instead. +\setlength{\@IEEEtrantmpdimenA}{#1\@IEEEtrantmpdimenB}% +\fontdimen2\font=\@IEEEtrantmpdimenA\relax +\addtolength{\@IEEEtrantmpdimenA}{-#2\@IEEEtrantmpdimenB}% +\fontdimen3\font=-\@IEEEtrantmpdimenA\relax +\setlength{\@IEEEtrantmpdimenA}{#1\@IEEEtrantmpdimenB}% +\addtolength{\@IEEEtrantmpdimenA}{-#3\@IEEEtrantmpdimenB}% +\fontdimen4\font=\@IEEEtrantmpdimenA\relax}} + +% revise the interword spacing for each font weight +\def\@@IEEEsetfontdimens{{% +\mdseries +\@@@IEEEsetfontdimens{\@IEEEinterspaceratioM}{\@IEEEinterspaceMAXratioM}{\@IEEEinterspaceMINratioM}% +\bfseries +\@@@IEEEsetfontdimens{\@IEEEinterspaceratioB}{\@IEEEinterspaceMAXratioB}{\@IEEEinterspaceMINratioB}% +}} + +% revise the interword spacing for each font shape +% \slshape is not often used for IEEE work and is not altered here. The \scshape caps are +% already a tad too large in the free LaTeX fonts (as compared to what the IEEE uses) so we +% won't alter these either. +\def\@IEEEsetfontdimens{{% +\normalfont +\@@IEEEsetfontdimens +\normalfont\itshape +\@@IEEEsetfontdimens +}} + +% command to revise the interword spacing for each font size (and shape +% and weight). Only the \rmfamily is done here as \ttfamily uses a +% fixed spacing and \sffamily is not used as the main text of IEEE papers. +\def\@IEEEtunefonts{{\selectfont\rmfamily +\tiny\@IEEEsetfontdimens +\scriptsize\@IEEEsetfontdimens +\footnotesize\@IEEEsetfontdimens +\small\@IEEEsetfontdimens +\normalsize\@IEEEsetfontdimens +\sublargesize\@IEEEsetfontdimens +\large\@IEEEsetfontdimens +\LARGE\@IEEEsetfontdimens +\huge\@IEEEsetfontdimens +\Huge\@IEEEsetfontdimens}} + +% if the nofonttune class option is not given, revise the interword spacing +% now - in case IEEEtran makes any default length measurements, and make +% sure all the default fonts are loaded +\ifCLASSOPTIONnofonttune\else +\@IEEEtunefonts +\fi + +% and again at the start of the document in case the user loaded different fonts +\AtBeginDocument{\ifCLASSOPTIONnofonttune\else\@IEEEtunefonts\fi} + + + + + +% -- V1.8a page setup commands -- + +% The default sample text for calculating margins +% Note that IEEE publications use \scriptsize for headers and footers. +\def\IEEEdefaultsampletext{\normalfont\normalsize gT} +\def\IEEEdefaultheadersampletext{\normalfont\scriptsize T}% IEEE headers default to uppercase +\def\IEEEdefaultfootersampletext{\normalfont\scriptsize gT} + + + +% usage: \IEEEsettextwidth{inner margin}{outer margin} +% Sets \textwidth to allow the specified inner and outer margins +% for the current \paperwidth. +\def\IEEEsettextwidth#1#2{\@IEEEtrantmpdimenA\paperwidth +\@IEEEtrantmpdimenB#1\relax +\advance\@IEEEtrantmpdimenA by -\@IEEEtrantmpdimenB +\@IEEEtrantmpdimenB#2\relax +\advance\@IEEEtrantmpdimenA by -\@IEEEtrantmpdimenB +\textwidth\@IEEEtrantmpdimenA} + + + +% usage: \IEEEsetsidemargin{mode: i, o, c, a}{margin/offset} +% Sets \oddsidemargin and \evensidemargin to yield the specified margin +% of the given mode. +% The available modes are: +% i = inner margin +% o = outer margin +% c = centered, with the given offset +% a = adjust the margins using the given offset +% For the offsets, positive values increase the inner margin. +% \textwidth should be set properly for the given margins before calling this +% function. +\def\IEEEsetsidemargin#1#2{\@IEEEtrantmpdimenA #2\relax +\@IEEEextracttoken{#1}\relax +% check for mode errors +\ifx\@IEEEextractedtokenmacro\@empty + \@IEEEclspkgerror{Empty mode type in \string\IEEEsetsidemargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `i'}{Valid modes for \string\IEEEsetsidemargin\space are: i, o, c and a.}\relax + \let\@IEEEextractedtoken=i\relax + \def\@IEEEextractedtokenmacro{i}\relax +\else + \ifx\@IEEEextractedtokensdiscarded\@empty\else + \typeout{** WARNING: \string\IEEEsetsidemargin\space mode specifiers after the first in `\@IEEEextracttokenarg' ignored (line \the\inputlineno).}\relax + \fi +\fi +% handle each mode +\if\@IEEEextractedtoken a\relax + \advance\oddsidemargin by \@IEEEtrantmpdimenA\relax +\else +\if\@IEEEextractedtoken c\relax + \oddsidemargin\paperwidth + \advance\oddsidemargin by -\textwidth + \divide\oddsidemargin by 2\relax + \advance\oddsidemargin by -1in\relax + \advance\oddsidemargin by \@IEEEtrantmpdimenA\relax +\else +\if\@IEEEextractedtoken o\relax + \oddsidemargin\paperwidth + \advance\oddsidemargin by -\textwidth + \advance\oddsidemargin by -\@IEEEtrantmpdimenA + \advance\oddsidemargin by -1in\relax +\else + \if\@IEEEextractedtoken i\relax + \else + \@IEEEclspkgerror{Unknown mode type `\@IEEEextractedtokenmacro' in \string\IEEEsetsidemargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `i'}% + {Valid modes for \string\IEEEsetsidemargin\space are: i, o, c and a.}% + \fi + \oddsidemargin\@IEEEtrantmpdimenA + \advance\oddsidemargin by -1in\relax +\fi\fi\fi +% odd and even side margins both mean "inner" for single sided pages +\evensidemargin\oddsidemargin +% but are mirrors of each other when twosided is in effect +\if@twoside + \evensidemargin\paperwidth + \advance\evensidemargin by -\textwidth + \advance\evensidemargin by -\oddsidemargin + % have to compensate for both the builtin 1in LaTex offset + % and the fact we already subtracted this offset from \oddsidemargin + \advance\evensidemargin -2in\relax +\fi} + + + +% usage: \IEEEsettextheight[sample text]{top text margin}{bottom text margin} +% Sets \textheight based on the specified top margin and bottom margin. +% Takes into consideration \paperheight, \topskip, and (by default) the +% the actual height and depth of the \IEEEdefaultsampletext text. +\def\IEEEsettextheight{\@ifnextchar [{\@IEEEsettextheight}{\@IEEEsettextheight[\IEEEdefaultsampletext]}} +\def\@IEEEsettextheight[#1]#2#3{\textheight\paperheight\relax + \@IEEEtrantmpdimenA #2\relax + \advance \textheight by -\@IEEEtrantmpdimenA% subtract top margin + \@IEEEtrantmpdimenA #3\relax + \advance \textheight by -\@IEEEtrantmpdimenA% subtract bottom margin + \advance \textheight by \topskip% add \topskip + % subtract off everything above the top, and below the bottom, baselines + \settoheight{\@IEEEtrantmpdimenA}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance \textheight by -\@IEEEtrantmpdimenA + \settodepth{\@IEEEtrantmpdimenA}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance \textheight by -\@IEEEtrantmpdimenA} + + + +\newdimen\IEEEquantizedlength +\IEEEquantizedlength 0sp\relax +\newdimen\IEEEquantizedlengthdiff +\IEEEquantizedlengthdiff 0sp\relax +\def\IEEEquantizedlengthint{0} + +% usage: \IEEEquantizelength{mode: d, c, i}{base unit}{length} +% Sets the length \IEEEquantizedlength to be an integer multiple of the given +% (nonzero) base unit such that \IEEEquantizedlength approximates the given +% length. +% \IEEEquantizedlengthdiff is a length equal to the difference between the +% \IEEEquantizedlength and the given length. +% \IEEEquantizedlengthint is a macro containing the integer number of base units +% in \IEEEquantizedlength. +% i.e., \IEEEquantizedlength = \IEEEquantizedlengthint * base unit +% The mode determines how \IEEEquantizedlength is quantized: +% d = always decrease (always round down \IEEEquantizeint) +% c = use the closest match +% i = always increase (always round up \IEEEquantizeint) +% In anycase, if the given length is already quantized, +% \IEEEquantizedlengthdiff will be set to zero. +\def\IEEEquantizelength#1#2#3{\begingroup +% work in isolation so as not to externally disturb the \@IEEEtrantmp +% variables +% load the argument values indirectly via \IEEEquantizedlengthdiff +% in case the user refers to our \@IEEEtrantmpdimenX, \IEEEquantizedlength, +% etc. in the arguments. we also will work with these as counters, +% i.e., in sp units +% A has the base unit +\IEEEquantizedlengthdiff #2\relax\relax\relax\relax +\@IEEEtrantmpcountA\IEEEquantizedlengthdiff +% B has the input length +\IEEEquantizedlengthdiff #3\relax\relax\relax\relax +\@IEEEtrantmpcountB\IEEEquantizedlengthdiff +\@IEEEtrantmpdimenA\the\@IEEEtrantmpcountA sp\relax +\@IEEEtrantmpdimenB\the\@IEEEtrantmpcountB sp\relax +% \@IEEEtrantmpcountC will have the quantized int +% \IEEEquantizedlength will have the quantized length +% \@IEEEtrantmpdimenC will have the quantized diff +% initialize them to zero as this is what will be +% exported if an error occurs +\@IEEEtrantmpcountC 0\relax +\IEEEquantizedlength 0sp\relax +\@IEEEtrantmpdimenC 0sp\relax +% extract mode +\@IEEEextracttoken{#1}\relax +% check for mode errors +\ifx\@IEEEextractedtokenmacro\@empty + \@IEEEclspkgerror{Empty mode type in \string\IEEEquantizelength\space (line \the\inputlineno).\MessageBreak + Defaulting to `d'}{Valid modes for \string\IEEEquantizelength\space are: d, c and i.}\relax + \let\@IEEEextractedtoken=d\relax + \def\@IEEEextractedtokenmacro{d}\relax +\else + \ifx\@IEEEextractedtokensdiscarded\@empty\else + \typeout{** WARNING: \string\IEEEquantizelength\space mode specifiers after the first in `\@IEEEextracttokenarg' ignored (line \the\inputlineno).}\relax + \fi +\fi +% check for base unit is zero error +\ifnum\@IEEEtrantmpcountA=0\relax +\@IEEEclspkgerror{Base unit is zero in \string\IEEEquantizelength\space (line \the\inputlineno).\MessageBreak + \string\IEEEquantizedlength\space and \string\IEEEquantizedlengthdiff\space are set to zero}{Division by zero is not allowed.}\relax +\else% base unit is nonzero + % \@IEEEtrantmpcountC carries the number of integer units + % in the quantized length (integer length \ base) + \@IEEEtrantmpcountC\@IEEEtrantmpcountB\relax + \divide\@IEEEtrantmpcountC by \@IEEEtrantmpcountA\relax + % \IEEEquantizedlength has the (rounded down) quantized length + % = base * int + \IEEEquantizedlength\@IEEEtrantmpdimenA\relax + \multiply\IEEEquantizedlength by \@IEEEtrantmpcountC\relax + % \@IEEEtrantmpdimenC has the difference + % = quantized length - length + \@IEEEtrantmpdimenC\IEEEquantizedlength\relax + \advance\@IEEEtrantmpdimenC by -\@IEEEtrantmpdimenB\relax + % trap special case of length being already quantized + % to avoid a roundup under i option + \ifdim\@IEEEtrantmpdimenC=0sp\relax + \else % length not is already quantized + % set dimenA to carry the upper quantized (absolute value) difference: + % quantizedlength + base - length + \advance\@IEEEtrantmpdimenA by \IEEEquantizedlength\relax + \advance\@IEEEtrantmpdimenA by -\@IEEEtrantmpdimenB\relax + % set dimenB to carry the lower quantized (absolute value) difference: + % length - quantizedlength + \advance\@IEEEtrantmpdimenB by -\IEEEquantizedlength\relax + % handle each mode + \if\@IEEEextractedtoken c\relax + % compare upper and lower amounts, select upper if lower > upper + \ifdim\@IEEEtrantmpdimenB>\@IEEEtrantmpdimenA\relax + % use upper + \advance\IEEEquantizedlength by \the\@IEEEtrantmpcountA sp\relax + \advance\@IEEEtrantmpcountC by 1\relax + \@IEEEtrantmpdimenC\@IEEEtrantmpdimenA + \else% <=. uselower + % no need to do anything for lower, use output values already setup + \fi + \else% not mode c + \if\@IEEEextractedtoken i\relax + % always round up under i mode + \advance\IEEEquantizedlength by \the\@IEEEtrantmpcountA sp\relax + \advance\@IEEEtrantmpcountC by 1\relax + \@IEEEtrantmpdimenC\@IEEEtrantmpdimenA + \else + \if\@IEEEextractedtoken d\relax + \else + \@IEEEclspkgerror{Unknown mode type `\@IEEEextractedtokenmacro' in \string\IEEEquantizelength\space (line \the\inputlineno).\MessageBreak + Defaulting to `d'}% + {Valid modes for \string\IEEEquantizelength\space are: d, c, and i.}\relax + \fi % if d + % no need to do anything for d, use output values already setup + \fi\fi % if i, c + \fi % if length is already quantized +\fi% if base unit is zero +% globally assign the results to macros we use here to escape the enclosing +% group without needing to call \global on any of the \@IEEEtrantmp variables. +% \@IEEEtrantmpcountC has the quantized int +% \IEEEquantizedlength has the quantized length +% \@IEEEtrantmpdimenC has the quantized diff +\xdef\@IEEEquantizedlengthintmacro{\the\@IEEEtrantmpcountC}\relax +\@IEEEtrantmpcountC\IEEEquantizedlength\relax +\xdef\@IEEEquantizedlengthmacro{\the\@IEEEtrantmpcountC}\relax +\@IEEEtrantmpcountC\@IEEEtrantmpdimenC\relax +\xdef\@IEEEquantizedlengthdiffmacro{\the\@IEEEtrantmpcountC}\relax +\endgroup +% locally assign the outputs here from the macros +\expandafter\IEEEquantizedlength\@IEEEquantizedlengthmacro sp\relax +\expandafter\IEEEquantizedlengthdiff\@IEEEquantizedlengthdiffmacro sp\relax +\edef\IEEEquantizedlengthint{\@IEEEquantizedlengthintmacro}\relax} + + + +\newdimen\IEEEquantizedtextheightdiff +\IEEEquantizedtextheightdiff 0sp\relax + +% usage: \IEEEquantizetextheight[base unit]{mode: d, c, i} +% Sets \textheight to be an integer multiple of the current \baselineskip +% (or the optionally specified base unit) plus the first (\topskip) line. +% \IEEEquantizedtextheightdiff is a length equal to the difference between +% the new quantized and original \textheight. +% \IEEEquantizedtextheightlpc is a macro containing the integer number of +% lines per column under the quantized \textheight. i.e., +% \textheight = \IEEEquantizedtextheightlpc * \baselineskip + \topskip +% The mode determines how \textheight is quantized: +% d = always decrease (always round down the number of lines per column) +% c = use the closest match +% i = always increase (always round up the number of lines per column) +% In anycase, if \textheight is already quantized, it will remain unchanged, +% and \IEEEquantizedtextheightdiff will be set to zero. +% Depends on: \IEEEquantizelength +\def\IEEEquantizetextheight{\@ifnextchar [{\@IEEEquantizetextheight}{\@IEEEquantizetextheight[\baselineskip]}} +\def\@IEEEquantizetextheight[#1]#2{\begingroup +% use our \IEEEquantizedtextheightdiff as a scratch pad +% we need to subtract off \topskip before quantization +\IEEEquantizedtextheightdiff\textheight +\advance\IEEEquantizedtextheightdiff by -\topskip\relax +\IEEEquantizelength{#2}{#1}{\IEEEquantizedtextheightdiff} +% add back \topskip line +\advance\IEEEquantizedlength by \topskip +\@IEEEtrantmpcountC\IEEEquantizedlengthint\relax +\advance\@IEEEtrantmpcountC by 1\relax +% globally assign the results to macros we use here to escape the enclosing +% group without needing to call \global on any of the \@IEEEtrantmp variables. +\xdef\@IEEEquantizedtextheightlpcmacro{\the\@IEEEtrantmpcountC}\relax +\@IEEEtrantmpcountC\IEEEquantizedlength\relax +\xdef\@IEEEquantizedtextheightmacro{\the\@IEEEtrantmpcountC}\relax +\@IEEEtrantmpcountC\IEEEquantizedlengthdiff\relax +\xdef\@IEEEquantizedtextheightdiffmacro{\the\@IEEEtrantmpcountC}\relax +\endgroup +% locally assign the outputs here from the macros +\textheight\@IEEEquantizedtextheightmacro sp\relax +\IEEEquantizedtextheightdiff\@IEEEquantizedtextheightdiffmacro sp\relax +\edef\IEEEquantizedtextheightlpc{\@IEEEquantizedtextheightlpcmacro}} + + + +% usage: \IEEEsettopmargin[sample text]{mode: t, b, c, a, q}{margin/offset} +% Sets \topmargin based on the specified vertical margin. +% Takes into consideration the base 1in offset, \headheight, \headsep, +% \topskip, and (by default) the the actual height (or, for the bottom, depth) +% of the \IEEEdefaultsampletext text. +% The available modes are: +% t = top margin +% b = bottom margin +% c = vertically centered, with the given offset +% a = adjust the vertical margins using the given offset +% q = adjust the margins using \IEEEquantizedtextheightdiff and the given offset +% For the offsets, positive values increase the top margin. +% \headheight, \headsep, \topskip and \textheight should be set properly for the +% given margins before calling this function. +\def\IEEEsettopmargin{\@ifnextchar [{\@IEEEsettopmargin}{\@IEEEsettopmargin[\IEEEdefaultsampletext]}} +\def\@IEEEsettopmargin[#1]#2#3{\@IEEEtrantmpdimenA #3\relax +\@IEEEextracttoken{#2}\relax +% check for mode errors +\ifx\@IEEEextractedtokenmacro\@empty + \@IEEEclspkgerror{Empty mode type in \string\IEEEsettopmargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `t'}{Valid modes for \string\IEEEsettopmargin\space are: t, b, c, a and q.}\relax + \let\@IEEEextractedtoken=t\relax + \def\@IEEEextractedtokenmacro{t}\relax +\else + \ifx\@IEEEextractedtokensdiscarded\@empty\else + \typeout{** WARNING: \string\IEEEsettopmargin\space mode specifiers after the first in `\@IEEEextracttokenarg' ignored (line \the\inputlineno).}\relax + \fi +\fi +% handle each mode +\if\@IEEEextractedtoken a\relax + \advance\topmargin by \@IEEEtrantmpdimenA\relax +\else +\if\@IEEEextractedtoken q\relax + % we need to adjust by half the \IEEEquantizedtextheightdiff value + \@IEEEtrantmpdimenB\IEEEquantizedtextheightdiff\relax + \divide\@IEEEtrantmpdimenB by 2\relax + % a positive \IEEEquantizedtextheightdiff means we need to reduce \topmargin + % because \textheight has been lenghtened + \advance\topmargin by -\@IEEEtrantmpdimenB\relax + \advance\topmargin by \@IEEEtrantmpdimenA\relax +\else +\if\@IEEEextractedtoken c\relax + \topmargin\paperheight + \advance\topmargin by -\textheight + % \textheight includes \topskip, but we should not count topskip whitespace here, backout + \advance \topmargin by \topskip + \settoheight{\@IEEEtrantmpdimenB}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\topmargin by -\@IEEEtrantmpdimenB\relax + \settodepth{\@IEEEtrantmpdimenB}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\topmargin by -\@IEEEtrantmpdimenB\relax + \divide\topmargin by 2\relax + \advance\topmargin by \@IEEEtrantmpdimenA\relax +\else +\if\@IEEEextractedtoken b\relax + \topmargin\paperheight + \advance\topmargin by -\textheight + % \textheight includes \topskip, but we should not count topskip whitespace here, backout + \advance \topmargin by \topskip + \settodepth{\@IEEEtrantmpdimenB}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\topmargin by -\@IEEEtrantmpdimenB\relax + \advance\topmargin by -\@IEEEtrantmpdimenA\relax +\else + \if\@IEEEextractedtoken t\relax + \else + \@IEEEclspkgerror{Unknown mode type `\@IEEEextractedtokenmacro' in \string\IEEEsettopmargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `t'}% + {Valid modes for \string\IEEEsettopmargin\space are: t, b, c, a and q.}\relax + \fi + \topmargin\@IEEEtrantmpdimenA\relax + \settoheight{\@IEEEtrantmpdimenB}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\topmargin by \@IEEEtrantmpdimenB\relax +\fi\fi % if t, b, c +% convert desired top margin into actual \topmargin +% this is not done for the q or a modes because they are only adjustments +\advance \topmargin by -\topskip +\advance \topmargin by -1in +\advance \topmargin by -\headheight +\advance \topmargin by -\headsep +\fi\fi % if q, a +} + + + +% usage: \IEEEsetheadermargin[header sample][text sample]{mode: t, b, c, a}{margin/offset} +% Differentially adjusts \topmargin and \headsep (such that their sum is unchanged) +% based on the specified header margin. +% Takes into consideration the base 1in offset, \headheight, \topskip, and (by default) +% the actual height (or depth) of the \IEEEdefaultheadersampletext and +% \IEEEdefaultsampletext text. +% The available modes are: +% t = top margin (top of the header text to the top of the page) +% b = bottom margin (bottom of the header text to the top of the main text) +% c = vertically centered between the main text and the top of the page, +% with the given offset +% a = adjust the vertical position using the given offset +% For the offsets, positive values move the header downward. +% \headheight, \headsep, \topskip and \topmargin should be set properly before +% calling this function. +\def\IEEEsetheadermargin{\@ifnextchar [{\@IEEEsetheadermargin}{\@IEEEsetheadermargin[\IEEEdefaultheadersampletext]}} +\def\@IEEEsetheadermargin[#1]{\@ifnextchar [{\@@IEEEsetheadermargin[#1]}{\@@IEEEsetheadermargin[#1][\IEEEdefaultsampletext]}} +\def\@@IEEEsetheadermargin[#1][#2]#3#4{\@IEEEtrantmpdimenA #4\relax +\@IEEEextracttoken{#3}\relax +% check for mode errors +\ifx\@IEEEextractedtokenmacro\@empty + \@IEEEclspkgerror{Empty mode type in \string\IEEEsetheadermargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `t'}{Valid modes for \string\IEEEsetheadermargin\space are: t, b, c, and a.}\relax + \let\@IEEEextractedtoken=t\relax + \def\@IEEEextractedtokenmacro{t}\relax +\else + \ifx\@IEEEextractedtokensdiscarded\@empty\else + \typeout{** WARNING: \string\IEEEsetheadermargin\space mode specifiers after the first in `\@IEEEextracttokenarg' ignored (line \the\inputlineno).}\relax + \fi +\fi +% handle each mode +\if\@IEEEextractedtoken a\relax + % No need to do anything here and can pass through the adjustment + % value as is. The end adjustment of \topmargin and \headsep will + % do all that is needed +\else +\if\@IEEEextractedtoken c\relax + % get the bottom margin + \@IEEEtrantmpdimenB\headsep\relax + \settodepth{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + \advance\@IEEEtrantmpdimenB by \topskip + \settoheight{\@IEEEtrantmpdimenC}{\begingroup #2\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the actual header bottom margin + % subtract from it the top header margin + \advance\@IEEEtrantmpdimenB -1in\relax % take into consideration the system 1in offset of the top margin + \advance\@IEEEtrantmpdimenB by -\topmargin + \advance\@IEEEtrantmpdimenB by -\headheight + \settoheight{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by \@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the difference between the bottom and top margins + % we need to adjust by half this amount to center the header + \divide\@IEEEtrantmpdimenB by 2\relax + % and add to offset + \advance\@IEEEtrantmpdimenA by \@IEEEtrantmpdimenB +\else +\if\@IEEEextractedtoken b\relax + \@IEEEtrantmpdimenB\headsep\relax + \settodepth{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + \advance\@IEEEtrantmpdimenB by \topskip + \settoheight{\@IEEEtrantmpdimenC}{\begingroup #2\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the actual header bottom margin + % get the difference between the actual and the desired + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenA + \@IEEEtrantmpdimenA\@IEEEtrantmpdimenB +\else + \if\@IEEEextractedtoken t\relax + \else + \@IEEEclspkgerror{Unknown mode type `\@IEEEextractedtokenmacro' in \string\IEEEsetheadermargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `t'}% + {Valid modes for \string\IEEEsetheadermargin\space are: t, b, c and a.}\relax + \fi + \@IEEEtrantmpdimenB 1in\relax % take into consideration the system 1in offset of the top margin + \advance\@IEEEtrantmpdimenB by \topmargin + \advance\@IEEEtrantmpdimenB by \headheight + \settoheight{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the actual header top margin + % get the difference between the desired and the actual + \advance\@IEEEtrantmpdimenA by -\@IEEEtrantmpdimenB +\fi\fi % if t, b, c +\fi % if a +% advance \topmargin by the needed amount and reduce \headsep by the same +% so as not to disturb the location of the main text +\advance\topmargin by \@IEEEtrantmpdimenA\relax +\advance\headsep by -\@IEEEtrantmpdimenA\relax +} + + + +% usage: \IEEEsetfootermargin[footer sample][text sample]{mode: t, b, c, a}{margin/offset} +% Adjusts \footskip based on the specified footer margin. +% Takes into consideration the base 1in offset, \paperheight, \headheight, +% \headsep, \textheight and (by default) the actual height (or depth) of the +% \IEEEdefaultfootersampletext and \IEEEdefaultsampletext text. +% The available modes are: +% t = top margin (top of the footer text to the bottom of the main text) +% b = bottom margin (bottom of the footer text to the bottom of page) +% c = vertically centered between the main text and the bottom of the page, +% with the given offset +% a = adjust the vertical position using the given offset +% For the offsets, positive values move the footer downward. +% \headheight, \headsep, \topskip, \topmargin, and \textheight should be set +% properly before calling this function. +\def\IEEEsetfootermargin{\@ifnextchar [{\@IEEEsetfootermargin}{\@IEEEsetfootermargin[\IEEEdefaultfootersampletext]}} +\def\@IEEEsetfootermargin[#1]{\@ifnextchar [{\@@IEEEsetfootermargin[#1]}{\@@IEEEsetfootermargin[#1][\IEEEdefaultsampletext]}} +\def\@@IEEEsetfootermargin[#1][#2]#3#4{\@IEEEtrantmpdimenA #4\relax +\@IEEEextracttoken{#3}\relax +% check for mode errors +\ifx\@IEEEextractedtokenmacro\@empty + \@IEEEclspkgerror{Empty mode type in \string\IEEEsetfootermargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `t'}{Valid modes for \string\IEEEsetfootermargin\space are: t, b, c, and a.}\relax + \let\@IEEEextractedtoken=t\relax + \def\@IEEEextractedtokenmacro{t}\relax +\else + \ifx\@IEEEextractedtokensdiscarded\@empty\else + \typeout{** WARNING: \string\IEEEsetfootermargin\space mode specifiers after the first in `\@IEEEextracttokenarg' ignored (line \the\inputlineno).}\relax + \fi +\fi +% handle each mode +\if\@IEEEextractedtoken a\relax + % No need to do anything here and can pass through the adjustment + % value as is. The end adjustment of \footskip will do all that + % is needed +\else +\if\@IEEEextractedtoken c\relax + % calculate the bottom margin + \@IEEEtrantmpdimenB 1in\relax % system 1in offset + \advance\@IEEEtrantmpdimenB\topmargin\relax + \advance\@IEEEtrantmpdimenB\headheight\relax + \advance\@IEEEtrantmpdimenB\headsep\relax + \advance\@IEEEtrantmpdimenB\textheight\relax + \advance\@IEEEtrantmpdimenB\footskip\relax + \settodepth{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenC by \@IEEEtrantmpdimenB + \@IEEEtrantmpdimenB\paperheight + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the actual footer bottom margin + % now subtract off the footer top margin + \advance\@IEEEtrantmpdimenB -\footskip\relax + \settodepth{\@IEEEtrantmpdimenC}{\begingroup #2\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by \@IEEEtrantmpdimenC + \settoheight{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by \@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the difference between the bottom + % and top footer margins + % our adjustment must be half this value to center the footer + \divide\@IEEEtrantmpdimenB by 2\relax + % add to the offset + \advance\@IEEEtrantmpdimenA by \@IEEEtrantmpdimenB +\else +\if\@IEEEextractedtoken b\relax + % calculate the bottom margin + \@IEEEtrantmpdimenB 1in\relax % system 1in offset + \advance\@IEEEtrantmpdimenB\topmargin\relax + \advance\@IEEEtrantmpdimenB\headheight\relax + \advance\@IEEEtrantmpdimenB\headsep\relax + \advance\@IEEEtrantmpdimenB\textheight\relax + \advance\@IEEEtrantmpdimenB\footskip\relax + \settodepth{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenC by \@IEEEtrantmpdimenB + \@IEEEtrantmpdimenB\paperheight + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the actual footer bottom margin + % get the difference between the actual and the desired + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenA + \@IEEEtrantmpdimenA\@IEEEtrantmpdimenB +\else + \if\@IEEEextractedtoken t\relax + \else + \@IEEEclspkgerror{Unknown mode type `\@IEEEextractedtokenmacro' in \string\IEEEsetfootermargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `t'}% + {Valid modes for \string\IEEEsetfootermargin\space are: t, b, c and a.}\relax + \fi + \@IEEEtrantmpdimenB\footskip\relax + \settodepth{\@IEEEtrantmpdimenC}{\begingroup #2\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + \settoheight{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the actual footer top margin + % get the difference between the desired and the actual + \advance\@IEEEtrantmpdimenA by -\@IEEEtrantmpdimenB +\fi\fi % if t, b, c +\fi % if a +% advance \footskip by the needed amount +\advance\footskip by \@IEEEtrantmpdimenA\relax +} + +% -- End V1.8a page setup commands -- + + + + + +% V1.6 +% LaTeX is a little to quick to use hyphenations +% So, we increase the penalty for their use and raise +% the badness level that triggers an underfull hbox +% warning. The author may still have to tweak things, +% but the appearance will be much better "right out +% of the box" than that under V1.5 and prior. +% TeX default is 50 +\hyphenpenalty=750 +\ifCLASSOPTIONcompsoc +\hyphenpenalty 500 +\fi +% If we didn't adjust the interword spacing, 2200 might be better. +% The TeX default is 1000 +\hbadness=1350 +% The IEEE does not use extra spacing after punctuation +\frenchspacing + +% V1.7 increase this a tad to discourage equation breaks +\binoppenalty=1000 % default 700 +\relpenalty=800 % default 500 + +% v1.8a increase these to discourage widows and orphans +\clubpenalty=1000 % default 150 +\widowpenalty=1000 % default 150 +\displaywidowpenalty=1000 % default 50 + + +% margin note stuff +\marginparsep 10pt +\marginparwidth 20pt +\marginparpush 25pt + + +% if things get too close, go ahead and let them touch +\lineskip 0pt +\normallineskip 0pt +\lineskiplimit 0pt +\normallineskiplimit 0pt + +% The distance from the lower edge of the text body to the +% footline +\footskip 0.4in + +% normally zero, should be relative to font height. +% put in a little rubber to help stop some bad breaks (underfull vboxes) +\parskip 0ex plus 0.2ex minus 0.1ex + +\parindent 1.0em +\ifCLASSOPTIONcompsoc + \parindent 1.5em +\fi + +\headheight 12pt +\headsep 18pt +% use the normal font baselineskip +% so that \topskip is unaffected by changes in \baselinestretch +\topskip=\@IEEEnormalsizeunitybaselineskip + + +% V1.8 \maxdepth defaults to 4pt, but should be font size dependent +\maxdepth=0.5\@IEEEnormalsizeunitybaselineskip +\textheight 58pc % 9.63in, 696pt + +% set the default top margin to 58pt +% which results in a \topmargin of -49.59pt for 10pt documents +\IEEEsettopmargin{t}{58pt} +% tweak textheight to a perfect integer number of lines/column. +% standard is: 9pt/63 lpc; 10pt/58 lpc; 11pt/52 lpc; 12pt/50 lpc +\IEEEquantizetextheight{c} +% tweak top margin so that the error is shared equally at the top and bottom +\IEEEsettopmargin{q}{0sp} + + +\columnsep 1pc +\textwidth 43pc % 2 x 21pc + 1pc = 43pc + +% set the default side margins to center the text +\IEEEsetsidemargin{c}{0pt} + + +% adjust margins for default conference mode +\ifCLASSOPTIONconference + \textheight 9.25in % The standard for conferences (668.4975pt) + \IEEEsettopmargin{t}{0.75in} + % tweak textheight to a perfect integer number of lines/page. + % standard is: 9pt/61 lpc; 10pt/56 lpc; 11pt/50 lpc; 12pt/48 lpc + \IEEEquantizetextheight{c} + % tweak top margin so that the error is shared equally at the top and bottom + \IEEEsettopmargin{q}{0sp} +\fi + + +% compsoc text sizes, margins and spacings +\ifCLASSOPTIONcompsoc + \columnsep 12bp + % CS specs for \textwdith are 6.875in + % \textwidth 6.875in + % however, measurements from proofs show they are using 3.5in columns + \textwidth 7in + \advance\textwidth by \columnsep + % set the side margins to center the text + \IEEEsetsidemargin{c}{0pt} + % top/bottom margins to center + % could just set \textheight to 9.75in for all the different paper sizes + % and then quantize, but we'll do it the long way here to allow for easy + % future per-paper size adjustments + \IEEEsettextheight{0.625in}{0.625in}% 11in - 2 * 0.625in = 9.75in is the standard text height for compsoc journals + \IEEEsettopmargin{t}{0.625in} + \if@IEEEusingcspaper + \IEEEsettextheight{0.5in}{0.5in}% 10.75in - 2 * 0.5in = 9.75in + \IEEEsettopmargin{t}{0.5in} + \fi + \if@IEEEusingAfourpaper + \IEEEsettextheight{24.675mm}{24.675mm}% 297mm - 2 * 24.675mm = 247.650mm (9.75in) + \IEEEsettopmargin{t}{24.675mm} + \fi + % tweak textheight to a perfect integer number of lines/page. + % standard is: 9pt/65 lpc; 10pt/61 lpc; 11pt/53 lpc; 12pt/49 lpc + \IEEEquantizetextheight{c} + % tweak top margin so that the error is shared equally at the top and bottom + \IEEEsettopmargin{q}{0sp} + +% compsoc conference + \ifCLASSOPTIONconference + % compsoc conference use a larger value for columnsep + \columnsep 0.25in + \IEEEsettextwidth{0.75in}{0.75in} + % set the side margins to center the text (0.75in for letterpaper) + \IEEEsetsidemargin{c}{0pt} + % compsoc conferences want 1in top and bottom margin + \IEEEsettextheight{1in}{1in} + \IEEEsettopmargin{t}{1in} + % tweak textheight to a perfect integer number of lines/page. + % standard is: 9pt/58 lpc; 10pt/53 lpc; 11pt/48 lpc; 12pt/46 lpc + \IEEEquantizetextheight{c} + % tweak top margin so that the error is shared equally at the top and bottom + \IEEEsettopmargin{q}{0sp} + \fi +\fi + + + +% draft mode settings override that of all other modes +% provides a nice 1in margin all around the paper and extra +% space between the lines for editor's comments +\ifCLASSOPTIONdraftcls + % we want 1in side margins regardless of paper type + \IEEEsettextwidth{1in}{1in} + \IEEEsetsidemargin{c}{0pt} + % want 1in top and bottom margins + \IEEEsettextheight{1in}{1in} + \IEEEsettopmargin{t}{1in} + % digitize textheight to be an integer number of lines. + % this may cause the top and bottom margins to be off a tad + \IEEEquantizetextheight{c} + % tweak top margin so that the error is shared equally at the top and bottom + \IEEEsettopmargin{q}{0sp} +\fi + + + +% process CLASSINPUT inner/outer margin +% if inner margin defined, but outer margin not, set outer to inner. +\ifx\CLASSINPUTinnersidemargin\@IEEEundefined +\else + \ifx\CLASSINPUToutersidemargin\@IEEEundefined + \edef\CLASSINPUToutersidemargin{\CLASSINPUTinnersidemargin} + \fi +\fi + +\ifx\CLASSINPUToutersidemargin\@IEEEundefined +\else + % if outer margin defined, but inner margin not, set inner to outer. + \ifx\CLASSINPUTinnersidemargin\@IEEEundefined + \edef\CLASSINPUTinnersidemargin{\CLASSINPUToutersidemargin} + \fi + \IEEEsettextwidth{\CLASSINPUTinnersidemargin}{\CLASSINPUToutersidemargin} + \IEEEsetsidemargin{i}{\CLASSINPUTinnersidemargin} + \typeout{** ATTENTION: Overriding inner side margin to \CLASSINPUTinnersidemargin\space and + outer side margin to \CLASSINPUToutersidemargin\space via \string\CLASSINPUT.} +\fi + + + +% process CLASSINPUT top/bottom text margin +% if toptext margin defined, but bottomtext margin not, set bottomtext to toptext margin +\ifx\CLASSINPUTtoptextmargin\@IEEEundefined +\else + \ifx\CLASSINPUTbottomtextmargin\@IEEEundefined + \edef\CLASSINPUTbottomtextmargin{\CLASSINPUTtoptextmargin} + \fi +\fi + +\ifx\CLASSINPUTbottomtextmargin\@IEEEundefined +\else + % if bottomtext margin defined, but toptext margin not, set toptext to bottomtext margin + \ifx\CLASSINPUTtoptextmargin\@IEEEundefined + \edef\CLASSINPUTtoptextmargin{\CLASSINPUTbottomtextmargin} + \fi + \IEEEsettextheight{\CLASSINPUTtoptextmargin}{\CLASSINPUTbottomtextmargin} + \IEEEsettopmargin{t}{\CLASSINPUTtoptextmargin} + \typeout{** ATTENTION: Overriding top text margin to \CLASSINPUTtoptextmargin\space and + bottom text margin to \CLASSINPUTbottomtextmargin\space via \string\CLASSINPUT.} +\fi + + + +% default to center header and footer text in the margins +\IEEEsetheadermargin{c}{0pt} +\IEEEsetfootermargin{c}{0pt} + +% adjust header and footer positions for compsoc journals +\ifCLASSOPTIONcompsoc + \ifCLASSOPTIONjournal + \IEEEsetheadermargin{b}{\@IEEEnormalsizeunitybaselineskip} + \IEEEsetfootermargin{t}{\@IEEEnormalsizeunitybaselineskip} + \fi +\fi + + +% V1.8a display lines per column info message on user's console +\def\IEEEdisplayinfolinespercolumn{\@IEEEtrantmpdimenA=\textheight +% topskip represents only one line even if > baselineskip +\advance\@IEEEtrantmpdimenA by -1\topskip +\@IEEEtrantmpcountA=\@IEEEtrantmpdimenA +\@IEEEtrantmpcountB=\@IEEEtrantmpdimenA +\divide\@IEEEtrantmpcountB by \baselineskip +% need to add one line to include topskip (first) line +\advance\@IEEEtrantmpcountB by 1 +% save lines per column value as text +\edef\@IEEEnumlinespercolumninfotxt{\the\@IEEEtrantmpcountB} +% backout topskip advance to allow direct \@IEEEtrantmpcountA comparison +\advance\@IEEEtrantmpcountB by -1 +% restore value as text height (without topskip) rather than just as number of lines +\multiply\@IEEEtrantmpcountB by \baselineskip +% is the column height an integer number of lines per column? +\ifnum\@IEEEtrantmpcountA=\@IEEEtrantmpcountB +\edef\@IEEEnumlinespercolumnexactinfotxt{exact} +\else +\@IEEEtrantmpdimenA\@IEEEtrantmpcountA sp\relax +\advance\@IEEEtrantmpdimenA by -\@IEEEtrantmpcountB sp\relax +\edef\@IEEEnumlinespercolumnexactinfotxt{approximate, difference = \the\@IEEEtrantmpdimenA} +\fi +\typeout{-- Lines per column: \@IEEEnumlinespercolumninfotxt\space (\@IEEEnumlinespercolumnexactinfotxt).}} +% delay execution till start of document to allow for user changes +\AtBeginDocument{\IEEEdisplayinfolinespercolumn} + + + +% LIST SPACING CONTROLS + +% Controls the amount of EXTRA spacing +% above and below \trivlist +% Both \list and IED lists override this. +% However, \trivlist will use this as will most +% things built from \trivlist like the \center +% environment. +\topsep 0.5\baselineskip + +% Controls the additional spacing around lists preceded +% or followed by blank lines. the IEEE does not increase +% spacing before or after paragraphs so it is set to zero. +% \z@ is the same as zero, but faster. +\partopsep \z@ + +% Controls the spacing between paragraphs in lists. +% The IEEE does not increase spacing before or after paragraphs +% so this is also zero. +% With IEEEtran.cls, global changes to +% this value DO affect lists (but not IED lists). +\parsep \z@ + +% Controls the extra spacing between list items. +% The IEEE does not put extra spacing between items. +% With IEEEtran.cls, global changes to this value DO affect +% lists (but not IED lists). +\itemsep \z@ + +% \itemindent is the amount to indent the FIRST line of a list +% item. It is auto set to zero within the \list environment. To alter +% it, you have to do so when you call the \list. +% However, the IEEE uses this for the theorem environment +% There is an alternative value for this near \leftmargini below +\itemindent -1em + +% \leftmargin, the spacing from the left margin of the main text to +% the left of the main body of a list item is set by \list. +% Hence this statement does nothing for lists. +% But, quote and verse do use it for indention. +\leftmargin 2em + +% we retain this stuff from the older IEEEtran.cls so that \list +% will work the same way as before. However, itemize, enumerate and +% description (IED) could care less about what these are as they +% all are overridden. +\leftmargini 2em +%\itemindent 2em % Alternative values: sometimes used. +%\leftmargini 0em +\leftmarginii 1em +\leftmarginiii 1.5em +\leftmarginiv 1.5em +\leftmarginv 1.0em +\leftmarginvi 1.0em +\labelsep 0.5em +\labelwidth \z@ + + +% The old IEEEtran.cls behavior of \list is retained. +% However, the new V1.3 IED list environments override all the +% @list stuff (\@listX is called within \list for the +% appropriate level just before the user's list_decl is called). +% \topsep is now 2pt as the IEEE puts a little extra space around +% lists - used by those non-IED macros that depend on \list. +% Note that \parsep and \itemsep are not redefined as in +% the sizexx.clo \@listX (which article.cls uses) so global changes +% of these values DO affect \list +% +\def\@listi{\leftmargin\leftmargini \topsep 2pt plus 1pt minus 1pt} +\let\@listI\@listi +\def\@listii{\leftmargin\leftmarginii\labelwidth\leftmarginii% + \advance\labelwidth-\labelsep \topsep 2pt} +\def\@listiii{\leftmargin\leftmarginiii\labelwidth\leftmarginiii% + \advance\labelwidth-\labelsep \topsep 2pt} +\def\@listiv{\leftmargin\leftmarginiv\labelwidth\leftmarginiv% + \advance\labelwidth-\labelsep \topsep 2pt} +\def\@listv{\leftmargin\leftmarginv\labelwidth\leftmarginv% + \advance\labelwidth-\labelsep \topsep 2pt} +\def\@listvi{\leftmargin\leftmarginvi\labelwidth\leftmarginvi% + \advance\labelwidth-\labelsep \topsep 2pt} + + +% The IEEE uses 5) not 5. +\def\labelenumi{\theenumi)} \def\theenumi{\arabic{enumi}} + +% The IEEE uses a) not (a) +\def\labelenumii{\theenumii)} \def\theenumii{\alph{enumii}} + +% The IEEE uses iii) not iii. +\def\labelenumiii{\theenumiii)} \def\theenumiii{\roman{enumiii}} + +% The IEEE uses A) not A. +\def\labelenumiv{\theenumiv)} \def\theenumiv{\Alph{enumiv}} + +% exactly the same as in article.cls +\def\p@enumii{\theenumi} +\def\p@enumiii{\theenumi(\theenumii)} +\def\p@enumiv{\p@enumiii\theenumiii} + +% itemized list label styles +\def\labelitemi{$\scriptstyle\bullet$} +\def\labelitemii{\textbf{--}} +\def\labelitemiii{$\ast$} +\def\labelitemiv{$\cdot$} + + + +% **** V1.3 ENHANCEMENTS **** +% Itemize, Enumerate and Description (IED) List Controls +% *************************** +% +% +% The IEEE seems to use at least two different values by +% which ITEMIZED list labels are indented to the right +% For The Journal of Lightwave Technology (JLT) and The Journal +% on Selected Areas in Communications (JSAC), they tend to use +% an indention equal to \parindent. For Transactions on Communications +% they tend to indent ITEMIZED lists a little more--- 1.3\parindent. +% We'll provide both values here for you so that you can choose +% which one you like in your document using a command such as: +% setlength{\IEEEilabelindent}{\IEEEilabelindentB} +\newdimen\IEEEilabelindentA +\IEEEilabelindentA \parindent + +\newdimen\IEEEilabelindentB +\IEEEilabelindentB 1.3\parindent +% However, we'll default to using \parindent +% which makes more sense to me +\newdimen\IEEEilabelindent +\IEEEilabelindent \IEEEilabelindentA + + +% This controls the default amount the enumerated list labels +% are indented to the right. +% Normally, this is the same as the paragraph indention +\newdimen\IEEEelabelindent +\IEEEelabelindent \parindent + +% This controls the default amount the description list labels +% are indented to the right. +% Normally, this is the same as the paragraph indention +\newdimen\IEEEdlabelindent +\IEEEdlabelindent \parindent + +% This is the value actually used within the IED lists. +% The IED environments automatically set its value to +% one of the three values above, so global changes do +% not have any effect +\newdimen\IEEElabelindent +\IEEElabelindent \parindent + +% The actual amount labels will be indented is +% \IEEElabelindent multiplied by the factor below +% corresponding to the level of nesting depth +% This provides a means by which the user can +% alter the effective \IEEElabelindent for deeper +% levels +% There may not be such a thing as correct "standard IEEE" +% values. What the IEEE actually does may depend on the specific +% circumstances. +% The first list level almost always has full indention. +% The second levels I've seen have only 75% of the normal indentation +% Three level or greater nestings are very rare. I am guessing +% that they don't use any indentation. +\def\IEEElabelindentfactori{1.0} % almost always one +\def\IEEElabelindentfactorii{0.75} % 0.0 or 1.0 may be used in some cases +\def\IEEElabelindentfactoriii{0.0} % 0.75? 0.5? 0.0? +\def\IEEElabelindentfactoriv{0.0} +\def\IEEElabelindentfactorv{0.0} +\def\IEEElabelindentfactorvi{0.0} + +% value actually used within IED lists, it is auto +% set to one of the 6 values above +% global changes here have no effect +\def\IEEElabelindentfactor{1.0} + +% This controls the default spacing between the end of the IED +% list labels and the list text, when normal text is used for +% the labels. +% compsoc uses a larger value here, but we'll set that later +% in the class so that this code block area can be extracted +% as-is for IEEEtrantools.sty +\newdimen\IEEEiednormlabelsep +\IEEEiednormlabelsep 0.6em + +% This controls the default spacing between the end of the IED +% list labels and the list text, when math symbols are used for +% the labels (nomenclature lists). The IEEE usually increases the +% spacing in these cases +\newdimen\IEEEiedmathlabelsep +\IEEEiedmathlabelsep 1.2em + +% This controls the extra vertical separation put above and +% below each IED list. the IEEE usually puts a little extra spacing +% around each list. However, this spacing is barely noticeable. +% compsoc uses a larger value here, but we'll set that later +% in the class so that this code block area can be extracted +% as-is for IEEEtrantools.sty +\newskip\IEEEiedtopsep +\IEEEiedtopsep 2pt plus 1pt minus 1pt + + +% This command is executed within each IED list environment +% at the beginning of the list. You can use this to set the +% parameters for some/all your IED list(s) without disturbing +% global parameters that affect things other than lists. +% i.e., renewcommand{\IEEEiedlistdecl}{\setlength{\labelsep}{5em}} +% will alter the \labelsep for the next list(s) until +% \IEEEiedlistdecl is redefined. +\def\IEEEiedlistdecl{\relax} + +% This command provides an easy way to set \leftmargin based +% on the \labelwidth, \labelsep and the argument \IEEElabelindent +% Usage: \IEEEcalcleftmargin{width-to-indent-the-label} +% output is in the \leftmargin variable, i.e., effectively: +% \leftmargin = argument + \labelwidth + \labelsep +% Note controlled spacing here, shield end of lines with % +\def\IEEEcalcleftmargin#1{\setlength{\leftmargin}{#1}% +\addtolength{\leftmargin}{\labelwidth}% +\addtolength{\leftmargin}{\labelsep}} + +% This command provides an easy way to set \labelwidth to the +% width of the given text. It is the same as +% \settowidth{\labelwidth}{label-text} +% and useful as a shorter alternative. +% Typically used to set \labelwidth to be the width +% of the longest label in the list +\def\IEEEsetlabelwidth#1{\settowidth{\labelwidth}{#1}} + +% When this command is executed, IED lists will use the +% IEEEiedmathlabelsep label separation rather than the normal +% spacing. To have an effect, this command must be executed via +% the \IEEEiedlistdecl or within the option of the IED list +% environments. +\def\IEEEusemathlabelsep{\setlength{\labelsep}{\IEEEiedmathlabelsep}} + +% A flag which controls whether the IED lists automatically +% calculate \leftmargin from \IEEElabelindent, \labelwidth and \labelsep +% Useful if you want to specify your own \leftmargin +% This flag must be set (\IEEEnocalcleftmargintrue or \IEEEnocalcleftmarginfalse) +% via the \IEEEiedlistdecl or within the option of the IED list +% environments to have an effect. +\newif\ifIEEEnocalcleftmargin +\IEEEnocalcleftmarginfalse + +% A flag which controls whether \IEEElabelindent is multiplied by +% the \IEEElabelindentfactor for each list level. +% This flag must be set via the \IEEEiedlistdecl or within the option +% of the IED list environments to have an effect. +\newif\ifIEEEnolabelindentfactor +\IEEEnolabelindentfactorfalse + + +% internal variable to indicate type of IED label +% justification +% 0 - left; 1 - center; 2 - right +\def\@IEEEiedjustify{0} + + +% commands to allow the user to control IED +% label justifications. Use these commands within +% the IED environment option or in the \IEEEiedlistdecl +% Note that changing the normal list justifications +% is nonstandard and the IEEE may not like it if you do so! +% I include these commands as they may be helpful to +% those who are using these enhanced list controls for +% other non-IEEE related LaTeX work. +% itemize and enumerate automatically default to right +% justification, description defaults to left. +\def\IEEEiedlabeljustifyl{\def\@IEEEiedjustify{0}}%left +\def\IEEEiedlabeljustifyc{\def\@IEEEiedjustify{1}}%center +\def\IEEEiedlabeljustifyr{\def\@IEEEiedjustify{2}}%right + + + + +% commands to save to and restore from the list parameter copies +% this allows us to set all the list parameters within +% the list_decl and prevent \list (and its \@list) +% from overriding any of our parameters +% V1.6 use \edefs instead of dimen's to conserve dimen registers +% Note controlled spacing here, shield end of lines with % +\def\@IEEEsavelistparams{\edef\@IEEEiedtopsep{\the\topsep}% +\edef\@IEEEiedlabelwidth{\the\labelwidth}% +\edef\@IEEEiedlabelsep{\the\labelsep}% +\edef\@IEEEiedleftmargin{\the\leftmargin}% +\edef\@IEEEiedpartopsep{\the\partopsep}% +\edef\@IEEEiedparsep{\the\parsep}% +\edef\@IEEEieditemsep{\the\itemsep}% +\edef\@IEEEiedrightmargin{\the\rightmargin}% +\edef\@IEEEiedlistparindent{\the\listparindent}% +\edef\@IEEEieditemindent{\the\itemindent}} + +% Note controlled spacing here +\def\@IEEErestorelistparams{\topsep\@IEEEiedtopsep\relax% +\labelwidth\@IEEEiedlabelwidth\relax% +\labelsep\@IEEEiedlabelsep\relax% +\leftmargin\@IEEEiedleftmargin\relax% +\partopsep\@IEEEiedpartopsep\relax% +\parsep\@IEEEiedparsep\relax% +\itemsep\@IEEEieditemsep\relax% +\rightmargin\@IEEEiedrightmargin\relax% +\listparindent\@IEEEiedlistparindent\relax% +\itemindent\@IEEEieditemindent\relax} + + +% v1.6b provide original LaTeX IED list environments +% note that latex.ltx defines \itemize and \enumerate, but not \description +% which must be created by the base classes +% save original LaTeX itemize and enumerate +\let\LaTeXitemize\itemize +\let\endLaTeXitemize\enditemize +\let\LaTeXenumerate\enumerate +\let\endLaTeXenumerate\endenumerate + +% provide original LaTeX description environment from article.cls +\newenvironment{LaTeXdescription} + {\list{}{\labelwidth\z@ \itemindent-\leftmargin + \let\makelabel\descriptionlabel}} + {\endlist} +\newcommand*\descriptionlabel[1]{\hspace\labelsep + \normalfont\bfseries #1} + + +% override LaTeX's default IED lists +\def\itemize{\@IEEEitemize} +\def\enditemize{\@endIEEEitemize} +\def\enumerate{\@IEEEenumerate} +\def\endenumerate{\@endIEEEenumerate} +\def\description{\@IEEEdescription} +\def\enddescription{\@endIEEEdescription} + +% provide the user with aliases - may help those using packages that +% override itemize, enumerate, or description +\def\IEEEitemize{\@IEEEitemize} +\def\endIEEEitemize{\@endIEEEitemize} +\def\IEEEenumerate{\@IEEEenumerate} +\def\endIEEEenumerate{\@endIEEEenumerate} +\def\IEEEdescription{\@IEEEdescription} +\def\endIEEEdescription{\@endIEEEdescription} + + +% V1.6 we want to keep the IEEEtran IED list definitions as our own internal +% commands so they are protected against redefinition +\def\@IEEEitemize{\@ifnextchar[{\@@IEEEitemize}{\@@IEEEitemize[\relax]}} +\def\@IEEEenumerate{\@ifnextchar[{\@@IEEEenumerate}{\@@IEEEenumerate[\relax]}} +\def\@IEEEdescription{\@ifnextchar[{\@@IEEEdescription}{\@@IEEEdescription[\relax]}} +\def\@endIEEEitemize{\endlist} +\def\@endIEEEenumerate{\endlist} +\def\@endIEEEdescription{\endlist} + + +% DO NOT ALLOW BLANK LINES TO BE IN THESE IED ENVIRONMENTS +% AS THIS WILL FORCE NEW PARAGRAPHS AFTER THE IED LISTS +% IEEEtran itemized list MDS 1/2001 +% Note controlled spacing here, shield end of lines with % +\def\@@IEEEitemize[#1]{% + \ifnum\@itemdepth>3\relax\@toodeep\else% + \ifnum\@listdepth>5\relax\@toodeep\else% + \advance\@itemdepth\@ne% + \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}% + % get the IEEElabelindentfactor for this level + \advance\@listdepth\@ne% we need to know what the level WILL be + \edef\IEEElabelindentfactor{\csname IEEElabelindentfactor\romannumeral\the\@listdepth\endcsname}% + \advance\@listdepth-\@ne% undo our increment + \def\@IEEEiedjustify{2}% right justified labels are default + % set other defaults + \IEEEnocalcleftmarginfalse% + \IEEEnolabelindentfactorfalse% + \topsep\IEEEiedtopsep% + \IEEElabelindent\IEEEilabelindent% + \labelsep\IEEEiednormlabelsep% + \partopsep 0ex% + \parsep 0ex% + \itemsep 0ex% + \rightmargin 0em% + \listparindent 0em% + \itemindent 0em% + % calculate the label width + % the user can override this later if + % they specified a \labelwidth + \settowidth{\labelwidth}{\csname labelitem\romannumeral\the\@itemdepth\endcsname}% + \@IEEEsavelistparams% save our list parameters + \list{\csname\@itemitem\endcsname}{% + \@IEEErestorelistparams% override any list{} changes + % to our globals + \let\makelabel\@IEEEiedmakelabel% v1.6b setup \makelabel + \IEEEiedlistdecl% let user alter parameters + #1\relax% + % If the user has requested not to use the + % IEEElabelindent factor, don't revise \IEEElabelindent + \ifIEEEnolabelindentfactor\relax% + \else\IEEElabelindent=\IEEElabelindentfactor\IEEElabelindent% + \fi% + % Unless the user has requested otherwise, + % calculate our left margin based + % on \IEEElabelindent, \labelwidth and + % \labelsep + \ifIEEEnocalcleftmargin\relax% + \else\IEEEcalcleftmargin{\IEEElabelindent}% + \fi}\fi\fi}% + + +% DO NOT ALLOW BLANK LINES TO BE IN THESE IED ENVIRONMENTS +% AS THIS WILL FORCE NEW PARAGRAPHS AFTER THE IED LISTS +% IEEEtran enumerate list MDS 1/2001 +% Note controlled spacing here, shield end of lines with % +\def\@@IEEEenumerate[#1]{% + \ifnum\@enumdepth>3\relax\@toodeep\else% + \ifnum\@listdepth>5\relax\@toodeep\else% + \advance\@enumdepth\@ne% + \edef\@enumctr{enum\romannumeral\the\@enumdepth}% + % get the IEEElabelindentfactor for this level + \advance\@listdepth\@ne% we need to know what the level WILL be + \edef\IEEElabelindentfactor{\csname IEEElabelindentfactor\romannumeral\the\@listdepth\endcsname}% + \advance\@listdepth-\@ne% undo our increment + \def\@IEEEiedjustify{2}% right justified labels are default + % set other defaults + \IEEEnocalcleftmarginfalse% + \IEEEnolabelindentfactorfalse% + \topsep\IEEEiedtopsep% + \IEEElabelindent\IEEEelabelindent% + \labelsep\IEEEiednormlabelsep% + \partopsep 0ex% + \parsep 0ex% + \itemsep 0ex% + \rightmargin 0em% + \listparindent 0em% + \itemindent 0em% + % calculate the label width + % We'll set it to the width suitable for all labels using + % normalfont 1) to 9) + % The user can override this later + \settowidth{\labelwidth}{9)}% + \@IEEEsavelistparams% save our list parameters + \list{\csname label\@enumctr\endcsname}{\usecounter{\@enumctr}% + \@IEEErestorelistparams% override any list{} changes + % to our globals + \let\makelabel\@IEEEiedmakelabel% v1.6b setup \makelabel + \IEEEiedlistdecl% let user alter parameters + #1\relax% + % If the user has requested not to use the + % IEEElabelindent factor, don't revise \IEEElabelindent + \ifIEEEnolabelindentfactor\relax% + \else\IEEElabelindent=\IEEElabelindentfactor\IEEElabelindent% + \fi% + % Unless the user has requested otherwise, + % calculate our left margin based + % on \IEEElabelindent, \labelwidth and + % \labelsep + \ifIEEEnocalcleftmargin\relax% + \else\IEEEcalcleftmargin{\IEEElabelindent}% + \fi}\fi\fi}% + + +% DO NOT ALLOW BLANK LINES TO BE IN THESE IED ENVIRONMENTS +% AS THIS WILL FORCE NEW PARAGRAPHS AFTER THE IED LISTS +% IEEEtran description list MDS 1/2001 +% Note controlled spacing here, shield end of lines with % +\def\@@IEEEdescription[#1]{% + \ifnum\@listdepth>5\relax\@toodeep\else% + % get the IEEElabelindentfactor for this level + \advance\@listdepth\@ne% we need to know what the level WILL be + \edef\IEEElabelindentfactor{\csname IEEElabelindentfactor\romannumeral\the\@listdepth\endcsname}% + \advance\@listdepth-\@ne% undo our increment + \def\@IEEEiedjustify{0}% left justified labels are default + % set other defaults + \IEEEnocalcleftmarginfalse% + \IEEEnolabelindentfactorfalse% + \topsep\IEEEiedtopsep% + \IEEElabelindent\IEEEdlabelindent% + % assume normal labelsep + \labelsep\IEEEiednormlabelsep% + \partopsep 0ex% + \parsep 0ex% + \itemsep 0ex% + \rightmargin 0em% + \listparindent 0em% + \itemindent 0em% + % Bogus label width in case the user forgets + % to set it. + % TIP: If you want to see what a variable's width is you + % can use the TeX command \showthe\width-variable to + % display it on the screen during compilation + % (This might be helpful to know when you need to find out + % which label is the widest) + \settowidth{\labelwidth}{Hello}% + \@IEEEsavelistparams% save our list parameters + \list{}{\@IEEErestorelistparams% override any list{} changes + % to our globals + \let\makelabel\@IEEEiedmakelabel% v1.6b setup \makelabel + \IEEEiedlistdecl% let user alter parameters + #1\relax% + % If the user has requested not to use the + % labelindent factor, don't revise \IEEElabelindent + \ifIEEEnolabelindentfactor\relax% + \else\IEEElabelindent=\IEEElabelindentfactor\IEEElabelindent% + \fi% + % Unless the user has requested otherwise, + % calculate our left margin based + % on \IEEElabelindent, \labelwidth and + % \labelsep + \ifIEEEnocalcleftmargin\relax% + \else\IEEEcalcleftmargin{\IEEElabelindent}\relax% + \fi}\fi} + +% v1.6b we use one makelabel that does justification as needed. +\def\@IEEEiedmakelabel#1{\relax\if\@IEEEiedjustify 0\relax +\makebox[\labelwidth][l]{\normalfont #1}\else +\if\@IEEEiedjustify 1\relax +\makebox[\labelwidth][c]{\normalfont #1}\else +\makebox[\labelwidth][r]{\normalfont #1}\fi\fi} + + +% compsoc uses a larger value for the normal labelsep +% and also extra spacing above and below each list +\ifCLASSOPTIONcompsoc + \IEEEiednormlabelsep 1.2em + \IEEEiedtopsep 6pt plus 3pt minus 3pt +\fi + + +% VERSE and QUOTE +% V1.7 define environments with newenvironment +\newenvironment{verse}{\let\\=\@centercr + \list{}{\itemsep\z@ \itemindent -1.5em \listparindent \itemindent + \rightmargin\leftmargin\advance\leftmargin 1.5em}\item\relax} + {\endlist} +\newenvironment{quotation}{\list{}{\listparindent 1.5em \itemindent\listparindent + \rightmargin\leftmargin \parsep 0pt plus 1pt}\item\relax} + {\endlist} +\newenvironment{quote}{\list{}{\rightmargin\leftmargin}\item\relax} + {\endlist} + + +% \titlepage +% provided only for backward compatibility. \maketitle is the correct +% way to create the title page. +\def\titlepage{\@restonecolfalse\if@twocolumn\@restonecoltrue\onecolumn + \else \newpage \fi \thispagestyle{empty}\c@page\z@} +\def\endtitlepage{\if@restonecol\twocolumn \else \newpage \fi} + +% standard values from article.cls +\arraycolsep 5pt +\arrayrulewidth .4pt +\doublerulesep 2pt + +\tabcolsep 6pt +\tabbingsep 0.5em + + +%% FOOTNOTES +% +%\skip\footins 10pt plus 4pt minus 2pt +% V1.6 respond to changes in font size +% space added above the footnotes (if present) +\skip\footins 0.9\baselineskip plus 0.4\baselineskip minus 0.2\baselineskip + +% V1.6, we need to make \footnotesep responsive to changes +% in \baselineskip or strange spacings will result when in +% draft mode. Here is a little LaTeX secret - \footnotesep +% determines the height of an invisible strut that is placed +% *above* the baseline of footnotes after the first. Since +% LaTeX considers the space for characters to be 0.7\baselineskip +% above the baseline and 0.3\baselineskip below it, we need to +% use 0.7\baselineskip as a \footnotesep to maintain equal spacing +% between all the lines of the footnotes. The IEEE often uses a tad +% more, so use 0.8\baselineskip. This slightly larger value also helps +% the text to clear the footnote marks. Note that \thanks in IEEEtran +% uses its own value of \footnotesep which is set in \maketitle. +{\footnotesize +\global\footnotesep 0.8\baselineskip} + + +\skip\@mpfootins = \skip\footins +\fboxsep = 3pt +\fboxrule = .4pt +% V1.6 use 1em, then use LaTeX2e's \@makefnmark +% Note that the IEEE normally *left* aligns the footnote marks, so we don't need +% box resizing tricks here. +\long\def\@makefntext#1{\parindent 1em\indent\hbox{\@makefnmark}#1}% V1.6 use 1em +% V1.7 compsoc does not use superscipts for footnote marks +\ifCLASSOPTIONcompsoc +\def\@IEEEcompsocmakefnmark{\hbox{\normalfont\@thefnmark.\ }} +\long\def\@makefntext#1{\parindent 1em\indent\hbox{\@IEEEcompsocmakefnmark}#1} +\fi + +% The IEEE does not use footnote rules +\def\footnoterule{} + +% V1.7 for compsoc, the IEEE uses a footnote rule only for \thanks. We devise a "one-shot" +% system to implement this. +\newif\if@IEEEenableoneshotfootnoterule +\@IEEEenableoneshotfootnoterulefalse +\ifCLASSOPTIONcompsoc +\def\footnoterule{\relax\if@IEEEenableoneshotfootnoterule +\kern-5pt +\hbox to \columnwidth{\hfill\vrule width 0.5\columnwidth height 0.4pt\hfill} +\kern4.6pt +\global\@IEEEenableoneshotfootnoterulefalse +\else +\relax +\fi} +\fi + +% V1.6 do not allow LaTeX to break a footnote across multiple pages +\interfootnotelinepenalty=10000 + +% V1.6 discourage breaks within equations +% Note that amsmath normally sets this to 10000, +% but LaTeX2e normally uses 100. +\interdisplaylinepenalty=2500 + +% default allows section depth up to /paragraph +\setcounter{secnumdepth}{4} + +% technotes do not allow /paragraph +\ifCLASSOPTIONtechnote + \setcounter{secnumdepth}{3} +\fi +% neither do compsoc conferences +\@IEEEcompsocconfonly{\setcounter{secnumdepth}{3}} + + +\newcounter{section} +\newcounter{subsection}[section] +\newcounter{subsubsection}[subsection] +\newcounter{paragraph}[subsubsection] + +% used only by IEEEtran's IEEEeqnarray as other packages may +% have their own, different, implementations +\newcounter{IEEEsubequation}[equation] + +% as shown when called by user from \ref, \label and in table of contents +\def\theequation{\arabic{equation}} % 1 +\def\theIEEEsubequation{\theequation\alph{IEEEsubequation}} % 1a (used only by IEEEtran's IEEEeqnarray) +\ifCLASSOPTIONcompsoc +% compsoc is all arabic +\def\thesection{\arabic{section}} +\def\thesubsection{\thesection.\arabic{subsection}} +\def\thesubsubsection{\thesubsection.\arabic{subsubsection}} +\def\theparagraph{\thesubsubsection.\arabic{paragraph}} +\else +\def\thesection{\Roman{section}} % I +% V1.7, \mbox prevents breaks around - +\def\thesubsection{\mbox{\thesection-\Alph{subsection}}} % I-A +% V1.7 use I-A1 format used by the IEEE rather than I-A.1 +\def\thesubsubsection{\thesubsection\arabic{subsubsection}} % I-A1 +\def\theparagraph{\thesubsubsection\alph{paragraph}} % I-A1a +\fi + +% From Heiko Oberdiek. Because of the \mbox in \thesubsection, we need to +% tell hyperref to disable the \mbox command when making PDF bookmarks. +% This done already with hyperref.sty version 6.74o and later, but +% it will not hurt to do it here again for users of older versions. +\@ifundefined{pdfstringdefPreHook}{\let\pdfstringdefPreHook\@empty}{}% +\g@addto@macro\pdfstringdefPreHook{\let\mbox\relax} + + +% Main text forms (how shown in main text headings) +% V1.6, using \thesection in \thesectiondis allows changes +% in the former to automatically appear in the latter +\ifCLASSOPTIONcompsoc + \ifCLASSOPTIONconference% compsoc conference + \def\thesectiondis{\thesection.} + \def\thesubsectiondis{\thesectiondis\arabic{subsection}.} + \def\thesubsubsectiondis{\thesubsectiondis\arabic{subsubsection}.} + \def\theparagraphdis{\thesubsubsectiondis\arabic{paragraph}.} + \else% compsoc not conferencs + \def\thesectiondis{\thesection} + \def\thesubsectiondis{\thesectiondis.\arabic{subsection}} + \def\thesubsubsectiondis{\thesubsectiondis.\arabic{subsubsection}} + \def\theparagraphdis{\thesubsubsectiondis.\arabic{paragraph}} + \fi +\else% not compsoc + \def\thesectiondis{\thesection.} % I. + \def\thesubsectiondis{\Alph{subsection}.} % B. + \def\thesubsubsectiondis{\arabic{subsubsection})} % 3) + \def\theparagraphdis{\alph{paragraph})} % d) +\fi + +% just like LaTeX2e's \@eqnnum +\def\theequationdis{{\normalfont \normalcolor (\theequation)}}% (1) +% IEEEsubequation used only by IEEEtran's IEEEeqnarray +\def\theIEEEsubequationdis{{\normalfont \normalcolor (\theIEEEsubequation)}}% (1a) +% redirect LaTeX2e's equation number display and all that depend on +% it, through IEEEtran's \theequationdis +\def\@eqnnum{\theequationdis} + + + +% V1.7 provide string macros as article.cls does +\def\contentsname{Contents} +\def\listfigurename{List of Figures} +\def\listtablename{List of Tables} +\def\refname{References} +\def\indexname{Index} +\def\figurename{Fig.} +\def\tablename{TABLE} +\@IEEEcompsocconfonly{\def\figurename{Figure}} +\def\partname{Part} +\def\appendixname{Appendix} +\def\abstractname{Abstract} +% IEEE specific names +\def\IEEEkeywordsname{Index Terms} +\def\IEEEproofname{Proof} + + +% LIST OF FIGURES AND TABLES AND TABLE OF CONTENTS +% +\def\@pnumwidth{1.55em} +\def\@tocrmarg{2.55em} +\def\@dotsep{4.5} +\setcounter{tocdepth}{3} + +% adjusted some spacings here so that section numbers will not easily +% collide with the section titles. +% VIII; VIII-A; and VIII-A.1 are usually the worst offenders. +% MDS 1/2001 +\def\tableofcontents{\section*{\contentsname}\@starttoc{toc}} +\def\l@section#1#2{\addpenalty{\@secpenalty}\addvspace{1.0em plus 1pt}% + \@tempdima 2.75em \begingroup \parindent \z@ \rightskip \@pnumwidth% + \parfillskip-\@pnumwidth {\bfseries\leavevmode #1}\hfil\hbox to\@pnumwidth{\hss #2}\par% + \endgroup} +% argument format #1:level, #2:labelindent,#3:labelsep +\def\l@subsection{\@dottedtocline{2}{2.75em}{3.75em}} +\def\l@subsubsection{\@dottedtocline{3}{6.5em}{4.5em}} +% must provide \l@ defs for ALL sublevels EVEN if tocdepth +% is such as they will not appear in the table of contents +% these defs are how TOC knows what level these things are! +\def\l@paragraph{\@dottedtocline{4}{6.5em}{5.5em}} +\def\l@subparagraph{\@dottedtocline{5}{6.5em}{6.5em}} +\def\listoffigures{\section*{\listfigurename}\@starttoc{lof}} +\def\l@figure{\@dottedtocline{1}{0em}{2.75em}} +\def\listoftables{\section*{\listtablename}\@starttoc{lot}} +\let\l@table\l@figure + + +% Definitions for floats +% +% Normal Floats +% V1.8 floatsep et al. revised down by 0.15\baselineskip +% to account for the sideeffects of \topskip compensation +\floatsep 0.85\baselineskip plus 0.2\baselineskip minus 0.2\baselineskip +\textfloatsep 1.55\baselineskip plus 0.2\baselineskip minus 0.4\baselineskip +\@fptop 0pt plus 1fil +\@fpsep 0.75\baselineskip plus 2fil +\@fpbot 0pt plus 1fil +\def\topfraction{0.9} +\def\bottomfraction{0.4} +\def\floatpagefraction{0.8} +% V1.7, let top floats approach 90% of page +\def\textfraction{0.1} + +% Double Column Floats +\dblfloatsep 0.85\baselineskip plus 0.2\baselineskip minus 0.2\baselineskip + +\dbltextfloatsep 1.55\baselineskip plus 0.2\baselineskip minus 0.4\baselineskip +% Note that it would be nice if the rubber here actually worked in LaTeX2e. +% There is a long standing limitation in LaTeX, first discovered (to the best +% of my knowledge) by Alan Jeffrey in 1992. LaTeX ignores the stretchable +% portion of \dbltextfloatsep, and as a result, double column figures can and +% do result in an non-integer number of lines in the main text columns with +% underfull vbox errors as a consequence. A post to comp.text.tex +% by Donald Arseneau confirms that this had not yet been fixed in 1998. +% IEEEtran V1.6 will fix this problem for you in the titles, but it doesn't +% protect you from other double floats. Happy vspace'ing. + +\@dblfptop 0pt plus 1fil +\@dblfpsep 0.75\baselineskip plus 2fil +\@dblfpbot 0pt plus 1fil +\def\dbltopfraction{0.8} +\def\dblfloatpagefraction{0.8} +\setcounter{dbltopnumber}{4} + +\intextsep 0.85\baselineskip plus 0.2\baselineskip minus 0.2\baselineskip +\setcounter{topnumber}{2} +\setcounter{bottomnumber}{2} +\setcounter{totalnumber}{4} + + + +% article class provides these, we should too. +\newlength\abovecaptionskip +\newlength\belowcaptionskip +% but only \abovecaptionskip is used above figure captions and *below* table +% captions +\setlength\abovecaptionskip{0.5\baselineskip} +% compsoc journals are a little more generous +\ifCLASSOPTIONcompsoc\ifCLASSOPTIONjournal + \setlength\abovecaptionskip{0.75\baselineskip} +\fi\fi +\setlength\belowcaptionskip{0pt} +% V1.6 create hooks in case the caption spacing ever needs to be +% overridden by a user +\def\@IEEEfigurecaptionsepspace{\vskip\abovecaptionskip\relax}% +\def\@IEEEtablecaptionsepspace{\vskip\abovecaptionskip\relax}% + + +% 1.6b revise caption system so that \@makecaption uses two arguments +% as with LaTeX2e. Otherwise, there will be problems when using hyperref. +\def\@IEEEtablestring{table} + + +% V1.8 compensate for \topskip so top of top figures align with tops of the first lines of main text +% here we calculate a space equal to the amount \topskip exceeds the main text height +% we hook in at \@floatboxreset +\def\@IEEEfiguretopskipspace{\ifdim\prevdepth=-1000pt\relax +\setlength{\@IEEEtrantmpdimenA}{1\topskip}\relax +\addtolength{\@IEEEtrantmpdimenA}{-0.7\@IEEEnormalsizeunitybaselineskip}\relax +\vspace*{\@IEEEtrantmpdimenA}\fi} +% V1.8 compensate for \topskip at the top of top tables so caption text is on main text baseline +% use a strut set on the caption baseline within \@makecaption +\def\@IEEEtabletopskipstrut{\ifdim\prevdepth=-1000pt\rule{0pt}{\topskip}\fi} +% the \ifdim\prevdepth checks are always expected to be true for IEEE style float caption ordering +% because top of figure content and top of captions in tables is the first thing on the vertical +% list of these floats +% thanks to Donald Arseneau for his 2000/11/11 post "Re: caption hacking" with info on this topic. + + +\ifCLASSOPTIONcompsoc +% V1.7 compsoc \@makecaption +\ifCLASSOPTIONconference% compsoc conference +\long\def\@makecaption#1#2{% +% test if is a for a figure or table +\ifx\@captype\@IEEEtablestring% +% if a table, do table caption +\footnotesize\bgroup\par\centering\@IEEEtabletopskipstrut{\normalfont\footnotesize {#1.}\nobreakspace\scshape #2}\par\addvspace{0.5\baselineskip}\egroup% +\@IEEEtablecaptionsepspace +% if not a table, format it as a figure +\else +\@IEEEfigurecaptionsepspace +\setbox\@tempboxa\hbox{\normalfont\footnotesize {#1.}\nobreakspace #2}% +\ifdim \wd\@tempboxa >\hsize% +% if caption is longer than a line, let it wrap around +\setbox\@tempboxa\hbox{\normalfont\footnotesize {#1.}\nobreakspace}% +\parbox[t]{\hsize}{\normalfont\footnotesize \noindent\unhbox\@tempboxa#2}% +% if caption is shorter than a line, center +\else% +\hbox to\hsize{\normalfont\footnotesize\hfil\box\@tempboxa\hfil}% +\fi\fi} +% +\else% nonconference compsoc +\long\def\@makecaption#1#2{% +% test if is a for a figure or table +\ifx\@captype\@IEEEtablestring% +% if a table, do table caption +\footnotesize\bgroup\par\centering\@IEEEtabletopskipstrut{\normalfont\sffamily\footnotesize #1}\\{\normalfont\sffamily\footnotesize #2}\par\addvspace{0.5\baselineskip}\egroup% +\@IEEEtablecaptionsepspace +% if not a table, format it as a figure +\else +\@IEEEfigurecaptionsepspace +\setbox\@tempboxa\hbox{\normalfont\sffamily\footnotesize {#1.}\nobreakspace #2}% +\ifdim \wd\@tempboxa >\hsize% +% if caption is longer than a line, let it wrap around +\setbox\@tempboxa\hbox{\normalfont\sffamily\footnotesize {#1.}\nobreakspace}% +\parbox[t]{\hsize}{\normalfont\sffamily\footnotesize \noindent\unhbox\@tempboxa#2}% +% if caption is shorter than a line, left justify +\else% +\hbox to\hsize{\normalfont\sffamily\footnotesize\box\@tempboxa\hfil}% +\fi\fi} +\fi +% +\else% traditional noncompsoc \@makecaption +\long\def\@makecaption#1#2{% +% test if is a for a figure or table +\ifx\@captype\@IEEEtablestring% +% if a table, do table caption +\footnotesize\bgroup\par\centering\@IEEEtabletopskipstrut{\normalfont\footnotesize #1}\\{\normalfont\footnotesize\scshape #2}\par\addvspace{0.5\baselineskip}\egroup% +\@IEEEtablecaptionsepspace +% if not a table, format it as a figure +\else +\@IEEEfigurecaptionsepspace +% 3/2001 use footnotesize, not small; use two nonbreaking spaces, not one +\setbox\@tempboxa\hbox{\normalfont\footnotesize {#1.}\nobreakspace\nobreakspace #2}% +\ifdim \wd\@tempboxa >\hsize% +% if caption is longer than a line, let it wrap around +\setbox\@tempboxa\hbox{\normalfont\footnotesize {#1.}\nobreakspace\nobreakspace}% +\parbox[t]{\hsize}{\normalfont\footnotesize\noindent\unhbox\@tempboxa#2}% +% if caption is shorter than a line, center if conference, left justify otherwise +\else% +\ifCLASSOPTIONconference \hbox to\hsize{\normalfont\footnotesize\hfil\box\@tempboxa\hfil}% +\else \hbox to\hsize{\normalfont\footnotesize\box\@tempboxa\hfil}% +\fi\fi\fi} +\fi + + + +% V1.7 disable captions class option, do so in a way that retains operation of \label +% within \caption +\ifCLASSOPTIONcaptionsoff +\long\def\@makecaption#1#2{\vspace*{2em}\footnotesize\bgroup\par\addvspace{0.5\baselineskip}\centering{\footnotesize #1}\par\addvspace{0.5\baselineskip}\egroup% +\let\@IEEEtemporiglabeldefsave\label +\let\@IEEEtemplabelargsave\relax +\def\label##1{\gdef\@IEEEtemplabelargsave{##1}}% +\setbox\@tempboxa\hbox{#2}% +\let\label\@IEEEtemporiglabeldefsave +\ifx\@IEEEtemplabelargsave\relax\else\label{\@IEEEtemplabelargsave}\fi} +\fi + + +% V1.7 define end environments with \def not \let so as to work OK with +% preview-latex +\newcounter{figure} +\def\thefigure{\@arabic\c@figure} +\def\fps@figure{tbp} +\def\ftype@figure{1} +\def\ext@figure{lof} +\def\fnum@figure{\figurename\nobreakspace\thefigure} +% V1.8 within figures add \@IEEEfiguretopskipspace compensation to LaTeX2e's \@floatboxreset +\def\figure{\def\@floatboxreset{\reset@font\normalsize\@setminipage\@IEEEfiguretopskipspace}\@float{figure}} +\def\endfigure{\end@float} +% V1.8 also add \@IEEEfiguretopskipspace compensation to \figure* +\@namedef{figure*}{\def\@floatboxreset{\reset@font\normalsize\@setminipage\@IEEEfiguretopskipspace}\@dblfloat{figure}} +\@namedef{endfigure*}{\end@dblfloat} + +\newcounter{table} +\ifCLASSOPTIONcompsoc +\def\thetable{\arabic{table}} +\else +\def\thetable{\@Roman\c@table} +\fi +\def\fps@table{tbp} +\def\ftype@table{2} +\def\ext@table{lot} +\def\fnum@table{\tablename\nobreakspace\thetable} +% V1.6 The IEEE uses 8pt text for tables +% within tables alter LaTeX2e's \@floatboxreset to use \footnotesize +\def\table{\def\@floatboxreset{\reset@font\footnotesize\@setminipage}\@float{table}} +\def\endtable{\end@float} +% v1.6b double column tables need to default to footnotesize as well. +\@namedef{table*}{\def\@floatboxreset{\reset@font\footnotesize\@setminipage}\@dblfloat{table}} +\@namedef{endtable*}{\end@dblfloat} + + + + +%% -- Command Argument Scanning Support Functions -- +%% V1.8a + +% usage: \@IEEEstripouterbraces*{} +% \@IEEEstripouterbraces fully expands its argument (which it then stores +% in \@IEEEstripouterbracesarg) via \edef, then removes any outer enclosing +% braces, and finally stores the result in the macro +% \@IEEEstrippedouterbraces. +% +% For example: +% \@IEEEstripouterbraces{{{{ab}c}}} +% results in: +% +% \@IEEEstripouterbracesarg ==> a macro containing {{{ab}c}} +% \@IEEEstrippedouterbraces ==> a macro containing {ab}c +% +% the *-star form,\@IEEEstripouterbraces*, does not expand the argument +% contents during processing +\def\@IEEEstripouterbraces{\@ifstar{\let\@IEEEstripouterbracesdef=\def\@@IEEEstripouterbraces}{\let\@IEEEstripouterbracesdef=\edef\@@IEEEstripouterbraces}} + +\def\@@IEEEstripouterbraces#1{\@IEEEstripouterbracesdef\@IEEEstripouterbracesarg{#1}\relax +% If the macro is unchanged after being acquired as a single delimited +% argument, we know we have one sequence of tokens without any enclosing +% braces. Loop until this is true. +\loop + \expandafter\@@@IEEEstripouterbraces\@IEEEstripouterbracesarg\@IEEEgeneralsequenceDELIMITER +\ifx\@IEEEstrippedouterbraces\@IEEEstripouterbracesarg +\else + \let\@IEEEstripouterbracesarg\@IEEEstrippedouterbraces +\repeat} + +\def\@@@IEEEstripouterbraces#1\@IEEEgeneralsequenceDELIMITER{\def\@IEEEstrippedouterbraces{#1}} + + + +% usage: \@IEEEextractgroup*{} +% \@IEEEextractgroup fully expands its argument (which it then stores in +% \@IEEEextractgrouparg) via \edef and then assigns the first "brace group" +% of tokens to the macro \@IEEEextractedgroup. +% The remaining groups, if any, are stored in the macro +% \@IEEEextractedgroupremain. If the argument does not contain the requisite +% groups, the respective macros will be defined to be empty. +% There is an asymmetry in that \@IEEEextractedgroup is stripped of its first +% outer grouping while \@IEEEextractedgroupremain retains even the outer +% grouping (if present) that originally identified it as a group. +% +% For example: +% \@IEEEextractgroup{{{ab}}{c{de}}} +% results in: +% +% \@IEEEextractgrouparg ==> a macro containing {{ab}}{c{de}} +% \@IEEEextractedgroup ==> a macro containing {ab} +% \@IEEEextractedgroupremain ==> a macro containing {c{de}} +% +% The *-star form, \@IEEEextractgroup*, does not expand its argument +% contents during processing. +\def\@IEEEextractgroup{\@ifstar{\let\@IEEEextractgroupdef=\def\@@IEEEextractgroup}{\let\@IEEEextractgroupdef=\edef\@@IEEEextractgroup}} + +\def\@@IEEEextractgroup#1{\@IEEEextractgroupdef\@IEEEextractgrouparg{#1}\relax +% trap the case of an empty extracted group as this would cause problems with +% \@IEEEextractgroupremain's argument acquisition +\ifx\@IEEEextractgrouparg\@empty + \def\@IEEEextractedgroup{}\relax + \def\@IEEEextractedgroupremain{}\relax +\else + % We have to use some dirty tricks here. We want to insert {} around + % whatever remains after the first group so that TeX's argument scanner + % will preserve any originally enclosing braces as well as provide an + % empty argument to acquire even if there isn't a second group. + % In this first of two dirty tricks, we put a } at the end of the structure + % we are going to extract from. The \ifnum0=`{\fi keeps TeX happy to allow + % what would otherwise be an unbalanced macro definition for + % \@@IEEEextractgroup to be acceptable to it. + \ifnum0=`{\fi\expandafter\@IEEEextractgroupremain\@IEEEextractgrouparg}\relax +\fi} + +% In the second part of the dirty tricks, we insert a leading { right after +% the first group is acquired, but before the remainder is. Again, the +% \ifnum0=`}\fi keeps TeX happy during definition time, but will disappear +% during run time. +\def\@IEEEextractgroupremain#1{\def\@IEEEextractedgroup{#1}\expandafter\@@IEEEextractgroupremain\expandafter{\ifnum0=`}\fi} + +\def\@@IEEEextractgroupremain#1{\def\@IEEEextractedgroupremain{#1}} + + + +% \@IEEEextracttoken relocated at top because margin setting commands rely on it + + + +% usage: \@IEEEextracttokengroups*{} +% \@IEEEextracttokengroups fully expands its argument (which it then stores +% in \@IEEEextracttokengroupsarg) and then assigns the first "brace group" of +% tokens (with the outermost braces removed) to the macro +% \@IEEEextractedfirstgroup. +% The meaning of the first nonbrace (but including the empty group) token +% within this first group is assigned via \let to \@IEEEextractedfirsttoken +% as well as stored in the macro \@IEEEextractedfirsttokenmacro. If a first +% nonbrace token does not exist (or is an empty group), these will be \relax +% and empty, respectively. Tokens that would otherwise be discarded during +% the acquisition of the first token in the first group are stored in +% \@IEEEextractedfirsttokensdiscarded, however their original relative brace +% nesting depths are not guaranteed to be preserved. +% The first group within this first group is stored in the macro +% \@IEEEextractedfirstfirstgroup. +% Likewise for the next group after the first: \@IEEEextractednextgroup, +% \@IEEEextractednextfirstgroup, \@IEEEextractednextgroupfirsttoken, +% \@IEEEextractednextgroupfirsttokenmacro, and +% \@IEEEextractednextfirsttokensdiscarded. +% All tokens/groups after the first group, including any enclosing braces, +% are stored in the macro \@IEEEextractedafterfirstgroupremain which will +% be empty if none exist. +% +% For example: +% \@IEEEextracttokengroups{{{ab}{cd}}{{ef}g}} +% will result in: +% +% \@IEEEextracttokengroupsarg ==> a macro containing {{ab}{cd}}{{ef}g} +% \@IEEEextractedfirstgroup ==> a macro containing {ab}{cd} +% \@IEEEextractedafterfirstgroupremain ==> a macro containing {{ef}g} +% \@IEEEextractedfirsttoken ==> the letter a +% \@IEEEextractedfirsttokenmacro ==> a macro containing a +% \@IEEEextractedfirsttokensdiscarded ==> a macro containing bcd +% \@IEEEextractedfirstfirstgroup ==> a macro containing ab +% \@IEEEextractednextgroup ==> a macro containing {ef}g +% \@IEEEextractednextfirsttoken ==> the letter e +% \@IEEEextractednextfirsttokenmacro ==> a macro containing e +% \@IEEEextractednextfirsttokensdiscarded ==> a macro containing fg +% \@IEEEextractednextfirstgroup ==> a macro containing ef +% +% If given an empty argument, \@IEEEextractedfirsttoken and +% \@IEEEextractednextfirsttoken will be set to \relax +% and all the macros will be empty. +% the *-star form, \@IEEEextracttokengroups*, does not expand its argument +% contents during processing. +% +% Depends on: \@IEEEextractgroup, \@IEEEextracttoken +\def\@IEEEextracttokengroups{\@ifstar{\let\@IEEEextracttokengroupsdef=\def\@@IEEEextracttokengroups}{\let\@IEEEextracttokengroupsdef=\edef\@@IEEEextracttokengroups}} +\def\@@IEEEextracttokengroups#1{\@IEEEextracttokengroupsdef\@IEEEextracttokengroupsarg{#1}\relax +% begin extraction, these functions are safe with empty arguments +% first group +\expandafter\@IEEEextractgroup\expandafter*\expandafter{\@IEEEextracttokengroupsarg}\relax +\let\@IEEEextractedfirstgroup\@IEEEextractedgroup +\let\@IEEEextractedafterfirstgroupremain\@IEEEextractedgroupremain +\expandafter\@IEEEextracttoken\expandafter*\expandafter{\@IEEEextractedfirstgroup}\relax +\let\@IEEEextractedfirsttoken\@IEEEextractedtoken +\let\@IEEEextractedfirsttokenmacro\@IEEEextractedtokenmacro +\let\@IEEEextractedfirsttokensdiscarded\@IEEEextractedtokensdiscarded +% first first group +\expandafter\@IEEEextractgroup\expandafter*\expandafter{\@IEEEextractedfirstgroup}\relax +\let\@IEEEextractedfirstfirstgroup\@IEEEextractedgroup +% next group +\expandafter\@IEEEextractgroup\expandafter*\expandafter{\@IEEEextractedafterfirstgroupremain}\relax +\let\@IEEEextractednextgroup\@IEEEextractedgroup +\expandafter\@IEEEextracttoken\expandafter*\expandafter{\@IEEEextractednextgroup}\relax +\let\@IEEEextractednextfirsttoken\@IEEEextractedtoken +\let\@IEEEextractednextfirsttokenmacro\@IEEEextractedtokenmacro +\let\@IEEEextractednextfirsttokensdiscarded\@IEEEextractedtokensdiscarded +% next first group +\expandafter\@IEEEextractgroup\expandafter*\expandafter{\@IEEEextractednextgroup}\relax +\let\@IEEEextractednextfirstgroup\@IEEEextractedgroup} + + +%% -- End of Command Argument Scanning Support Functions -- + + + + +%% +%% START OF IEEEeqnarray DEFINITIONS +%% +%% Inspired by the concepts, examples, and previous works of LaTeX +%% coders and developers such as Donald Arseneau, Fred Bartlett, +%% David Carlisle, Tony Liu, Frank Mittelbach, Piet van Oostrum, +%% Roland Winkler and Mark Wooding. +%% I don't make the claim that my work here is even near their calibre. ;) + + +\newif\if@IEEEeqnarrayboxnojot% flag to indicate if the environment was called as the star form +\@IEEEeqnarrayboxnojotfalse + +\newif\if@advanceIEEEeqncolcnt% tracks if the environment should advance the col counter +% allows a way to make an \IEEEeqnarraybox that can be used within an \IEEEeqnarray +% used by IEEEeqnarraymulticol so that it can work properly in both +\@advanceIEEEeqncolcnttrue + +\newcount\@IEEEeqnnumcols % tracks how many IEEEeqnarray cols are defined +\newcount\@IEEEeqncolcnt % tracks how many IEEEeqnarray cols the user actually used + + +% The default math style used by the columns +\def\IEEEeqnarraymathstyle{\displaystyle} +% The default text style used by the columns +% default to using the current font +\def\IEEEeqnarraytextstyle{\relax} + +% like the iedlistdecl but for \IEEEeqnarray +\def\IEEEeqnarraydecl{\relax} +\def\IEEEeqnarrayboxdecl{\relax} + + + +% V1.8 flags to indicate that equation numbering is to persist +\newif\if@IEEEeqnumpersist% +\@IEEEeqnumpersistfalse +\newif\if@IEEEsubeqnumpersist% +\@IEEEsubeqnumpersistfalse +% +% V1.8 flags to indicate if (sub)equation number of last line was preadvanced +\newif\if@IEEEeqnumpreadv% +\@IEEEeqnumpreadvfalse +\newif\if@IEEEsubeqnumpreadv% +\@IEEEsubeqnumpreadvfalse + +\newcount\@IEEEsubeqnnumrollback% saves previous value of IEEEsubequation number in case we need to restore it + +% \yesnumber is the opposite of \nonumber +% a novel concept with the same def as the equationarray package +% However, we give IEEE versions too since some LaTeX packages such as +% the MDWtools mathenv.sty redefine \nonumber to something else. +% This command is intended for use in non-IEEEeqnarray math environments +\providecommand{\yesnumber}{\global\@eqnswtrue} + + +% IEEEyes/nonumber +% V1.8 add persistant * forms +% These commands can alter the type of equation an IEEEeqnarray line is. +\def\IEEEyesnumber{\@ifstar{\global\@IEEEeqnumpersisttrue\global\@IEEEsubeqnumpersistfalse\@IEEEyesnumber}{\@IEEEyesnumber}} + +\def\@IEEEyesnumber{\global\@eqnswtrue +\if@IEEEeqnarrayISinner% alter counters and label only inside an IEEEeqnarray +\ifnum\c@IEEEsubequation>0\relax + \stepcounter{equation}\setcounter{IEEEsubequation}{0}\gdef\@currentlabel{\p@equation\theequation}\relax + \gdef\@currentHref{\@IEEEtheHrefequation}% setup hyperref label +\fi +% even if we reached this eqn num via a preadv, it is legit now +\global\@IEEEeqnumpreadvfalse\global\@IEEEsubeqnumpreadvfalse +\fi} + +\def\IEEEnonumber{\@ifstar{\global\@IEEEeqnumpersistfalse\global\@IEEEsubeqnumpersistfalse\global\@eqnswfalse}{\global\@eqnswfalse}} + + +\def\IEEEyessubnumber{\@ifstar{\global\@IEEEsubeqnumpersisttrue\@IEEEyessubnumber}{\@IEEEyessubnumber}} +% +\def\@IEEEyessubnumber{\if@IEEEeqnarrayISinner% alter counters and label only inside an IEEEeqnarray + \ifnum\c@IEEEsubequation>0\relax% if it already is a subequation, we are good to go as-is + \else% if we are a regular equation we have to watch out for two cases + \if@IEEEeqnumpreadv% if this equation is the result of a preadvance, backout and bump the sub eqnnum + \global\advance\c@equation\m@ne\global\c@IEEEsubequation=\@IEEEsubeqnnumrollback\addtocounter{IEEEsubequation}{1}\relax + \else% non-preadvanced equations just need initialization of their sub eqnnum + \setcounter{IEEEsubequation}{1}\relax + \fi + \fi% fi already is subequation + \gdef\@currentlabel{\p@IEEEsubequation\theIEEEsubequation}\relax + \gdef\@currentHref{\@IEEEtheHrefsubequation}% setup hyperref label + \global\@IEEEeqnumpreadvfalse\global\@IEEEsubeqnumpreadvfalse% no longer a preadv anymore + \global\@eqnswtrue +\fi} + + +\def\IEEEnosubnumber{\@ifstar{\global\@IEEEsubeqnumpersistfalse\@IEEEnosubnumber}{\@IEEEnosubnumber}} +% +\def\@IEEEnosubnumber{\if@IEEEeqnarrayISinner% alter counters and label only inside an IEEEeqnarray + \if@eqnsw % we do nothing unless we know we will display because we play with the counters here + % if it currently is a subequation, bump up to the next equation number and turn off the subequation + \ifnum\c@IEEEsubequation>0\relax\addtocounter{equation}{1}\setcounter{IEEEsubequation}{0}\relax + \fi + \global\@IEEEeqnumpreadvfalse\global\@IEEEsubeqnumpreadvfalse% no longer a preadv anymore + \gdef\@currentlabel{\p@equation\theequation}\relax + \gdef\@currentHref{\@IEEEtheHrefequation}% setup hyperref label + \fi +\fi} + + + +% allows users to "push away" equations that get too close to the equation numbers +\def\IEEEeqnarraynumspace{\hphantom{\ifnum\c@IEEEsubequation>0\relax\theIEEEsubequationdis\else\theequationdis\fi}} + +% provides a way to span multiple columns within IEEEeqnarray environments +% will consider \if@advanceIEEEeqncolcnt before globally advancing the +% column counter - so as to work within \IEEEeqnarraybox +% usage: \IEEEeqnarraymulticol{number cols. to span}{col type}{cell text} +\long\def\IEEEeqnarraymulticol#1#2#3{\multispan{#1}\relax +% check if column is defined for the precolumn definition +% We have to be careful here because TeX scans for & even within an \iffalse +% where it does not expand macros. So, if we used only one \ifx and a #3 +% appeared in the false branch and the user inserted another alignment +% structure that uses & in the \IEEEeqnarraymulticol{}, TeX will not see that +% there is an inner alignment in the false branch yet still will see any & +% there and will think that they apply to the outer alignment resulting in an +% incomplete \ifx error. +% So, here we use separate checks for the pre and post parts in order to keep +% the #3 outside of all conditionals. +\relax\expandafter\ifx\csname @IEEEeqnarraycolDEF#2\endcsname\@IEEEeqnarraycolisdefined\relax +\csname @IEEEeqnarraycolPRE#2\endcsname +\else% if not, error and use default type +\@IEEEclspkgerror{Invalid column type "#2" in \string\IEEEeqnarraymulticol.\MessageBreak +Using a default centering column instead}% +{You must define IEEEeqnarray column types before use.}% +\csname @IEEEeqnarraycolPRE@IEEEdefault\endcsname +\fi +% The ten \relax are to help prevent misleading error messages in case a user +% accidently inserted a macro that tries to acquire additional arguments. +#3\relax\relax\relax\relax\relax\relax\relax\relax\relax\relax +% check if column is defined for the postcolumn definition +\expandafter\ifx\csname @IEEEeqnarraycolDEF#2\endcsname\@IEEEeqnarraycolisdefined\relax +\csname @IEEEeqnarraycolPOST#2\endcsname +\else% if not, use the default type +\csname @IEEEeqnarraycolPOST@IEEEdefault\endcsname +\fi +% advance column counter only if the IEEEeqnarray environment wants it +\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by #1\relax\fi} + +% like \omit, but maintains track of the column counter for \IEEEeqnarray +\def\IEEEeqnarrayomit{\omit\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by 1\relax\fi} + + +% provides a way to define a letter referenced column type +% usage: \IEEEeqnarraydefcol{col. type letter/name}{pre insertion text}{post insertion text} +\def\IEEEeqnarraydefcol#1#2#3{\expandafter\def\csname @IEEEeqnarraycolPRE#1\endcsname{#2}% +\expandafter\def\csname @IEEEeqnarraycolPOST#1\endcsname{#3}% +\expandafter\def\csname @IEEEeqnarraycolDEF#1\endcsname{1}} + + +% provides a way to define a numerically referenced inter-column glue types +% usage: \IEEEeqnarraydefcolsep{col. glue number}{glue definition} +\def\IEEEeqnarraydefcolsep#1#2{\expandafter\def\csname @IEEEeqnarraycolSEP\romannumeral #1\endcsname{#2}% +\expandafter\def\csname @IEEEeqnarraycolSEPDEF\romannumeral #1\endcsname{1}} + + +\def\@IEEEeqnarraycolisdefined{1}% just a macro for 1, used for checking undefined column types + + +% expands and appends the given argument to the \@IEEEtrantmptoksA token list +% used to build up the \halign preamble +\def\@IEEEappendtoksA#1{\edef\@@IEEEappendtoksA{\@IEEEtrantmptoksA={\the\@IEEEtrantmptoksA #1}}% +\@@IEEEappendtoksA} + +% also appends to \@IEEEtrantmptoksA, but does not expand the argument +% uses \toks8 as a scratchpad register +\def\@IEEEappendNOEXPANDtoksA#1{\toks8={#1}% +\edef\@@IEEEappendNOEXPANDtoksA{\@IEEEtrantmptoksA={\the\@IEEEtrantmptoksA\the\toks8}}% +\@@IEEEappendNOEXPANDtoksA} + +% define some common column types for the user +% math +\IEEEeqnarraydefcol{l}{$\IEEEeqnarraymathstyle}{$\hfil} +\IEEEeqnarraydefcol{c}{\hfil$\IEEEeqnarraymathstyle}{$\hfil} +\IEEEeqnarraydefcol{r}{\hfil$\IEEEeqnarraymathstyle}{$} +\IEEEeqnarraydefcol{L}{$\IEEEeqnarraymathstyle{}}{{}$\hfil} +\IEEEeqnarraydefcol{C}{\hfil$\IEEEeqnarraymathstyle{}}{{}$\hfil} +\IEEEeqnarraydefcol{R}{\hfil$\IEEEeqnarraymathstyle{}}{{}$} +% text +\IEEEeqnarraydefcol{s}{\IEEEeqnarraytextstyle}{\hfil} +\IEEEeqnarraydefcol{t}{\hfil\IEEEeqnarraytextstyle}{\hfil} +\IEEEeqnarraydefcol{u}{\hfil\IEEEeqnarraytextstyle}{} + +% vertical rules +\IEEEeqnarraydefcol{v}{}{\vrule width\arrayrulewidth} +\IEEEeqnarraydefcol{vv}{\vrule width\arrayrulewidth\hfil}{\hfil\vrule width\arrayrulewidth} +\IEEEeqnarraydefcol{V}{}{\vrule width\arrayrulewidth\hskip\doublerulesep\vrule width\arrayrulewidth} +\IEEEeqnarraydefcol{VV}{\vrule width\arrayrulewidth\hskip\doublerulesep\vrule width\arrayrulewidth\hfil}% +{\hfil\vrule width\arrayrulewidth\hskip\doublerulesep\vrule width\arrayrulewidth} + +% horizontal rules +\IEEEeqnarraydefcol{h}{}{\leaders\hrule height\arrayrulewidth\hfil} +\IEEEeqnarraydefcol{H}{}{\leaders\vbox{\hrule width\arrayrulewidth\vskip\doublerulesep\hrule width\arrayrulewidth}\hfil} + +% plain +\IEEEeqnarraydefcol{x}{}{} +\IEEEeqnarraydefcol{X}{$}{$} + +% the default column type to use in the event a column type is not defined +\IEEEeqnarraydefcol{@IEEEdefault}{\hfil$\IEEEeqnarraymathstyle}{$\hfil} + + +% a zero tabskip (used for "-" col types) +\def\@IEEEeqnarraycolSEPzero{0pt plus 0pt minus 0pt} +% a centering tabskip (used for "+" col types) +\def\@IEEEeqnarraycolSEPcenter{1000pt plus 0pt minus 1000pt} + +% top level default tabskip glues for the start, end, and inter-column +% may be reset within environments not always at the top level, e.g., \IEEEeqnarraybox +\edef\@IEEEeqnarraycolSEPdefaultstart{\@IEEEeqnarraycolSEPcenter}% default start glue +\edef\@IEEEeqnarraycolSEPdefaultend{\@IEEEeqnarraycolSEPcenter}% default end glue +\edef\@IEEEeqnarraycolSEPdefaultmid{\@IEEEeqnarraycolSEPzero}% default inter-column glue + + + +% creates a vertical rule that extends from the bottom to the top a a cell +% Provided in case other packages redefine \vline some other way. +% usage: \IEEEeqnarrayvrule[rule thickness] +% If no argument is provided, \arrayrulewidth will be used for the rule thickness. +\newcommand\IEEEeqnarrayvrule[1][\arrayrulewidth]{\vrule\@width#1\relax} + +% creates a blank separator row +% usage: \IEEEeqnarrayseprow[separation length][font size commands] +% default is \IEEEeqnarrayseprow[0.25\normalbaselineskip][\relax] +% blank arguments inherit the default values +% uses \skip5 as a scratch register - calls \@IEEEeqnarraystrutsize which uses more scratch registers +\def\IEEEeqnarrayseprow{\relax\@ifnextchar[{\@IEEEeqnarrayseprow}{\@IEEEeqnarrayseprow[0.25\normalbaselineskip]}} +\def\@IEEEeqnarrayseprow[#1]{\relax\@ifnextchar[{\@@IEEEeqnarrayseprow[#1]}{\@@IEEEeqnarrayseprow[#1][\relax]}} +\def\@@IEEEeqnarrayseprow[#1][#2]{\def\@IEEEeqnarrayseprowARGONE{#1}% +\ifx\@IEEEeqnarrayseprowARGONE\@empty% +% get the skip value, based on the font commands +% use skip5 because \IEEEeqnarraystrutsize uses \skip0, \skip2, \skip3 +% assign within a bogus box to confine the font changes +{\setbox0=\hbox{#2\relax\global\skip5=0.25\normalbaselineskip}}% +\else% +{\setbox0=\hbox{#2\relax\global\skip5=#1}}% +\fi% +\@IEEEeqnarrayhoptolastcolumn\IEEEeqnarraystrutsize{\skip5}{0pt}[\relax]\relax} + +% creates a blank separator row, but omits all the column templates +% usage: \IEEEeqnarrayseprowcut[separation length][font size commands] +% default is \IEEEeqnarrayseprowcut[0.25\normalbaselineskip][\relax] +% blank arguments inherit the default values +% uses \skip5 as a scratch register - calls \@IEEEeqnarraystrutsize which uses more scratch registers +\def\IEEEeqnarrayseprowcut{\multispan{\@IEEEeqnnumcols}\relax% span all the cols +% advance column counter only if the IEEEeqnarray environment wants it +\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by \@IEEEeqnnumcols\relax\fi% +\@ifnextchar[{\@IEEEeqnarrayseprowcut}{\@IEEEeqnarrayseprowcut[0.25\normalbaselineskip]}} +\def\@IEEEeqnarrayseprowcut[#1]{\relax\@ifnextchar[{\@@IEEEeqnarrayseprowcut[#1]}{\@@IEEEeqnarrayseprowcut[#1][\relax]}} +\def\@@IEEEeqnarrayseprowcut[#1][#2]{\def\@IEEEeqnarrayseprowARGONE{#1}% +\ifx\@IEEEeqnarrayseprowARGONE\@empty% +% get the skip value, based on the font commands +% use skip5 because \IEEEeqnarraystrutsize uses \skip0, \skip2, \skip3 +% assign within a bogus box to confine the font changes +{\setbox0=\hbox{#2\relax\global\skip5=0.25\normalbaselineskip}}% +\else% +{\setbox0=\hbox{#2\relax\global\skip5=#1}}% +\fi% +\IEEEeqnarraystrutsize{\skip5}{0pt}[\relax]\relax} + + + +% draws a single rule across all the columns optional +% argument determines the rule width, \arrayrulewidth is the default +% updates column counter as needed and turns off struts +% usage: \IEEEeqnarrayrulerow[rule line thickness] +\def\IEEEeqnarrayrulerow{\multispan{\@IEEEeqnnumcols}\relax% span all the cols +% advance column counter only if the IEEEeqnarray environment wants it +\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by \@IEEEeqnnumcols\relax\fi% +\@ifnextchar[{\@IEEEeqnarrayrulerow}{\@IEEEeqnarrayrulerow[\arrayrulewidth]}} +\def\@IEEEeqnarrayrulerow[#1]{\leaders\hrule height#1\hfil\relax% put in our rule +% turn off any struts +\IEEEeqnarraystrutsize{0pt}{0pt}[\relax]\relax} + + +% draws a double rule by using a single rule row, a separator row, and then +% another single rule row +% first optional argument determines the rule thicknesses, \arrayrulewidth is the default +% second optional argument determines the rule spacing, \doublerulesep is the default +% usage: \IEEEeqnarraydblrulerow[rule line thickness][rule spacing] +\def\IEEEeqnarraydblrulerow{\multispan{\@IEEEeqnnumcols}\relax% span all the cols +% advance column counter only if the IEEEeqnarray environment wants it +\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by \@IEEEeqnnumcols\relax\fi% +\@ifnextchar[{\@IEEEeqnarraydblrulerow}{\@IEEEeqnarraydblrulerow[\arrayrulewidth]}} +\def\@IEEEeqnarraydblrulerow[#1]{\relax\@ifnextchar[{\@@IEEEeqnarraydblrulerow[#1]}% +{\@@IEEEeqnarraydblrulerow[#1][\doublerulesep]}} +\def\@@IEEEeqnarraydblrulerow[#1][#2]{\def\@IEEEeqnarraydblrulerowARG{#1}% +% we allow the user to say \IEEEeqnarraydblrulerow[][] +\ifx\@IEEEeqnarraydblrulerowARG\@empty% +\@IEEEeqnarrayrulerow[\arrayrulewidth]% +\else% +\@IEEEeqnarrayrulerow[#1]\relax% +\fi% +\def\@IEEEeqnarraydblrulerowARG{#2}% +\ifx\@IEEEeqnarraydblrulerowARG\@empty% +\\\IEEEeqnarrayseprow[\doublerulesep][\relax]% +\else% +\\\IEEEeqnarrayseprow[#2][\relax]% +\fi% +\\\multispan{\@IEEEeqnnumcols}% +% advance column counter only if the IEEEeqnarray environment wants it +\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by \@IEEEeqnnumcols\relax\fi% +\def\@IEEEeqnarraydblrulerowARG{#1}% +\ifx\@IEEEeqnarraydblrulerowARG\@empty% +\@IEEEeqnarrayrulerow[\arrayrulewidth]% +\else% +\@IEEEeqnarrayrulerow[#1]% +\fi% +} + +% draws a double rule by using a single rule row, a separator (cutting) row, and then +% another single rule row +% first optional argument determines the rule thicknesses, \arrayrulewidth is the default +% second optional argument determines the rule spacing, \doublerulesep is the default +% usage: \IEEEeqnarraydblrulerow[rule line thickness][rule spacing] +\def\IEEEeqnarraydblrulerowcut{\multispan{\@IEEEeqnnumcols}\relax% span all the cols +% advance column counter only if the IEEEeqnarray environment wants it +\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by \@IEEEeqnnumcols\relax\fi% +\@ifnextchar[{\@IEEEeqnarraydblrulerowcut}{\@IEEEeqnarraydblrulerowcut[\arrayrulewidth]}} +\def\@IEEEeqnarraydblrulerowcut[#1]{\relax\@ifnextchar[{\@@IEEEeqnarraydblrulerowcut[#1]}% +{\@@IEEEeqnarraydblrulerowcut[#1][\doublerulesep]}} +\def\@@IEEEeqnarraydblrulerowcut[#1][#2]{\def\@IEEEeqnarraydblrulerowARG{#1}% +% we allow the user to say \IEEEeqnarraydblrulerow[][] +\ifx\@IEEEeqnarraydblrulerowARG\@empty% +\@IEEEeqnarrayrulerow[\arrayrulewidth]% +\else% +\@IEEEeqnarrayrulerow[#1]% +\fi% +\def\@IEEEeqnarraydblrulerowARG{#2}% +\ifx\@IEEEeqnarraydblrulerowARG\@empty% +\\\IEEEeqnarrayseprowcut[\doublerulesep][\relax]% +\else% +\\\IEEEeqnarrayseprowcut[#2][\relax]% +\fi% +\\\multispan{\@IEEEeqnnumcols}% +% advance column counter only if the IEEEeqnarray environment wants it +\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by \@IEEEeqnnumcols\relax\fi% +\def\@IEEEeqnarraydblrulerowARG{#1}% +\ifx\@IEEEeqnarraydblrulerowARG\@empty% +\@IEEEeqnarrayrulerow[\arrayrulewidth]% +\else% +\@IEEEeqnarrayrulerow[#1]% +\fi% +} + + + +% inserts a full row's worth of &'s +% relies on \@IEEEeqnnumcols to provide the correct number of columns +% uses \@IEEEtrantmptoksA, \count0 as scratch registers +\def\@IEEEeqnarrayhoptolastcolumn{\@IEEEtrantmptoksA={}\count0=1\relax% +\loop% add cols if the user did not use them all +\ifnum\count0<\@IEEEeqnnumcols\relax% +\@IEEEappendtoksA{&}% +\advance\count0 by 1\relax% update the col count +\repeat% +\the\@IEEEtrantmptoksA%execute the &'s +} + + + +\newif\if@IEEEeqnarrayISinner % flag to indicate if we are within the lines +\@IEEEeqnarrayISinnerfalse % of an IEEEeqnarray - after the IEEEeqnarraydecl + +\edef\@IEEEeqnarrayTHEstrutheight{0pt} % height and depth of IEEEeqnarray struts +\edef\@IEEEeqnarrayTHEstrutdepth{0pt} + +\edef\@IEEEeqnarrayTHEmasterstrutheight{0pt} % default height and depth of +\edef\@IEEEeqnarrayTHEmasterstrutdepth{0pt} % struts within an IEEEeqnarray + +\edef\@IEEEeqnarrayTHEmasterstrutHSAVE{0pt} % saved master strut height +\edef\@IEEEeqnarrayTHEmasterstrutDSAVE{0pt} % and depth + +\newif\if@IEEEeqnarrayusemasterstrut % flag to indicate that the master strut value +\@IEEEeqnarrayusemasterstruttrue % is to be used + + + +% saves the strut height and depth of the master strut +\def\@IEEEeqnarraymasterstrutsave{\relax% +\expandafter\skip0=\@IEEEeqnarrayTHEmasterstrutheight\relax% +\expandafter\skip2=\@IEEEeqnarrayTHEmasterstrutdepth\relax% +% remove stretchability +\dimen0\skip0\relax% +\dimen2\skip2\relax% +% save values +\edef\@IEEEeqnarrayTHEmasterstrutHSAVE{\the\dimen0}% +\edef\@IEEEeqnarrayTHEmasterstrutDSAVE{\the\dimen2}} + +% restores the strut height and depth of the master strut +\def\@IEEEeqnarraymasterstrutrestore{\relax% +\expandafter\skip0=\@IEEEeqnarrayTHEmasterstrutHSAVE\relax% +\expandafter\skip2=\@IEEEeqnarrayTHEmasterstrutDSAVE\relax% +% remove stretchability +\dimen0\skip0\relax% +\dimen2\skip2\relax% +% restore values +\edef\@IEEEeqnarrayTHEmasterstrutheight{\the\dimen0}% +\edef\@IEEEeqnarrayTHEmasterstrutdepth{\the\dimen2}} + + +% globally restores the strut height and depth to the +% master values and sets the master strut flag to true +\def\@IEEEeqnarraystrutreset{\relax% +\expandafter\skip0=\@IEEEeqnarrayTHEmasterstrutheight\relax% +\expandafter\skip2=\@IEEEeqnarrayTHEmasterstrutdepth\relax% +% remove stretchability +\dimen0\skip0\relax% +\dimen2\skip2\relax% +% restore values +\xdef\@IEEEeqnarrayTHEstrutheight{\the\dimen0}% +\xdef\@IEEEeqnarrayTHEstrutdepth{\the\dimen2}% +\global\@IEEEeqnarrayusemasterstruttrue} + + +% if the master strut is not to be used, make the current +% values of \@IEEEeqnarrayTHEstrutheight, \@IEEEeqnarrayTHEstrutdepth +% and the use master strut flag, global +% this allows user strut commands issued in the last column to be carried +% into the isolation/strut column +\def\@IEEEeqnarrayglobalizestrutstatus{\relax% +\if@IEEEeqnarrayusemasterstrut\else% +\xdef\@IEEEeqnarrayTHEstrutheight{\@IEEEeqnarrayTHEstrutheight}% +\xdef\@IEEEeqnarrayTHEstrutdepth{\@IEEEeqnarrayTHEstrutdepth}% +\global\@IEEEeqnarrayusemasterstrutfalse% +\fi} + + + +% usage: \IEEEeqnarraystrutsize{height}{depth}[font size commands] +% If called outside the lines of an IEEEeqnarray, sets the height +% and depth of both the master and local struts. If called inside +% an IEEEeqnarray line, sets the height and depth of the local strut +% only and sets the flag to indicate the use of the local strut +% values. If the height or depth is left blank, 0.7\normalbaselineskip +% and 0.3\normalbaselineskip will be used, respectively. +% The optional argument can be used to evaluate the lengths under +% a different font size and styles. If none is specified, the current +% font is used. +% uses scratch registers \skip0, \skip2, \skip3, \dimen0, \dimen2 +\def\IEEEeqnarraystrutsize#1#2{\relax\@ifnextchar[{\@IEEEeqnarraystrutsize{#1}{#2}}{\@IEEEeqnarraystrutsize{#1}{#2}[\relax]}} +\def\@IEEEeqnarraystrutsize#1#2[#3]{\def\@IEEEeqnarraystrutsizeARG{#1}% +\ifx\@IEEEeqnarraystrutsizeARG\@empty% +{\setbox0=\hbox{#3\relax\global\skip3=0.7\normalbaselineskip}}% +\skip0=\skip3\relax% +\else% arg one present +{\setbox0=\hbox{#3\relax\global\skip3=#1\relax}}% +\skip0=\skip3\relax% +\fi% if null arg +\def\@IEEEeqnarraystrutsizeARG{#2}% +\ifx\@IEEEeqnarraystrutsizeARG\@empty% +{\setbox0=\hbox{#3\relax\global\skip3=0.3\normalbaselineskip}}% +\skip2=\skip3\relax% +\else% arg two present +{\setbox0=\hbox{#3\relax\global\skip3=#2\relax}}% +\skip2=\skip3\relax% +\fi% if null arg +% remove stretchability, just to be safe +\dimen0\skip0\relax% +\dimen2\skip2\relax% +% dimen0 = height, dimen2 = depth +\if@IEEEeqnarrayISinner% inner does not touch master strut size +\edef\@IEEEeqnarrayTHEstrutheight{\the\dimen0}% +\edef\@IEEEeqnarrayTHEstrutdepth{\the\dimen2}% +\@IEEEeqnarrayusemasterstrutfalse% do not use master +\else% outer, have to set master strut too +\edef\@IEEEeqnarrayTHEmasterstrutheight{\the\dimen0}% +\edef\@IEEEeqnarrayTHEmasterstrutdepth{\the\dimen2}% +\edef\@IEEEeqnarrayTHEstrutheight{\the\dimen0}% +\edef\@IEEEeqnarrayTHEstrutdepth{\the\dimen2}% +\@IEEEeqnarrayusemasterstruttrue% use master strut +\fi} + + +% usage: \IEEEeqnarraystrutsizeadd{added height}{added depth}[font size commands] +% If called outside the lines of an IEEEeqnarray, adds the given height +% and depth to both the master and local struts. +% If called inside an IEEEeqnarray line, adds the given height and depth +% to the local strut only and sets the flag to indicate the use +% of the local strut values. +% In both cases, if a height or depth is left blank, 0pt is used instead. +% The optional argument can be used to evaluate the lengths under +% a different font size and styles. If none is specified, the current +% font is used. +% uses scratch registers \skip0, \skip2, \skip3, \dimen0, \dimen2 +\def\IEEEeqnarraystrutsizeadd#1#2{\relax\@ifnextchar[{\@IEEEeqnarraystrutsizeadd{#1}{#2}}{\@IEEEeqnarraystrutsizeadd{#1}{#2}[\relax]}} +\def\@IEEEeqnarraystrutsizeadd#1#2[#3]{\def\@IEEEeqnarraystrutsizearg{#1}% +\ifx\@IEEEeqnarraystrutsizearg\@empty% +\skip0=0pt\relax% +\else% arg one present +{\setbox0=\hbox{#3\relax\global\skip3=#1}}% +\skip0=\skip3\relax% +\fi% if null arg +\def\@IEEEeqnarraystrutsizearg{#2}% +\ifx\@IEEEeqnarraystrutsizearg\@empty% +\skip2=0pt\relax% +\else% arg two present +{\setbox0=\hbox{#3\relax\global\skip3=#2}}% +\skip2=\skip3\relax% +\fi% if null arg +% remove stretchability, just to be safe +\dimen0\skip0\relax% +\dimen2\skip2\relax% +% dimen0 = height, dimen2 = depth +\if@IEEEeqnarrayISinner% inner does not touch master strut size +% get local strut size +\expandafter\skip0=\@IEEEeqnarrayTHEstrutheight\relax% +\expandafter\skip2=\@IEEEeqnarrayTHEstrutdepth\relax% +% add it to the user supplied values +\advance\dimen0 by \skip0\relax% +\advance\dimen2 by \skip2\relax% +% update the local strut size +\edef\@IEEEeqnarrayTHEstrutheight{\the\dimen0}% +\edef\@IEEEeqnarrayTHEstrutdepth{\the\dimen2}% +\@IEEEeqnarrayusemasterstrutfalse% do not use master +\else% outer, have to set master strut too +% get master strut size +\expandafter\skip0=\@IEEEeqnarrayTHEmasterstrutheight\relax% +\expandafter\skip2=\@IEEEeqnarrayTHEmasterstrutdepth\relax% +% add it to the user supplied values +\advance\dimen0 by \skip0\relax% +\advance\dimen2 by \skip2\relax% +% update the local and master strut sizes +\edef\@IEEEeqnarrayTHEmasterstrutheight{\the\dimen0}% +\edef\@IEEEeqnarrayTHEmasterstrutdepth{\the\dimen2}% +\edef\@IEEEeqnarrayTHEstrutheight{\the\dimen0}% +\edef\@IEEEeqnarrayTHEstrutdepth{\the\dimen2}% +\@IEEEeqnarrayusemasterstruttrue% use master strut +\fi} + + +% allow user a way to see the struts +\newif\ifIEEEvisiblestruts +\IEEEvisiblestrutsfalse + +% inserts an invisible strut using the master or local strut values +% uses scratch registers \skip0, \skip2, \dimen0, \dimen2 +\def\@IEEEeqnarrayinsertstrut{\relax% +\if@IEEEeqnarrayusemasterstrut +% get master strut size +\expandafter\skip0=\@IEEEeqnarrayTHEmasterstrutheight\relax% +\expandafter\skip2=\@IEEEeqnarrayTHEmasterstrutdepth\relax% +\else% +% get local strut size +\expandafter\skip0=\@IEEEeqnarrayTHEstrutheight\relax% +\expandafter\skip2=\@IEEEeqnarrayTHEstrutdepth\relax% +\fi% +% remove stretchability, probably not needed +\dimen0\skip0\relax% +\dimen2\skip2\relax% +% dimen0 = height, dimen2 = depth +% allow user to see struts if desired +\ifIEEEvisiblestruts% +\vrule width0.2pt height\dimen0 depth\dimen2\relax% +\else% +\vrule width0pt height\dimen0 depth\dimen2\relax\fi} + + +% creates an invisible strut, useable even outside \IEEEeqnarray +% if \IEEEvisiblestrutstrue, the strut will be visible and 0.2pt wide. +% usage: \IEEEstrut[height][depth][font size commands] +% default is \IEEEstrut[0.7\normalbaselineskip][0.3\normalbaselineskip][\relax] +% blank arguments inherit the default values +% uses \dimen0, \dimen2, \skip0, \skip2 +\def\IEEEstrut{\relax\@ifnextchar[{\@IEEEstrut}{\@IEEEstrut[0.7\normalbaselineskip]}} +\def\@IEEEstrut[#1]{\relax\@ifnextchar[{\@@IEEEstrut[#1]}{\@@IEEEstrut[#1][0.3\normalbaselineskip]}} +\def\@@IEEEstrut[#1][#2]{\relax\@ifnextchar[{\@@@IEEEstrut[#1][#2]}{\@@@IEEEstrut[#1][#2][\relax]}} +\def\@@@IEEEstrut[#1][#2][#3]{\mbox{#3\relax% +\def\@IEEEstrutARG{#1}% +\ifx\@IEEEstrutARG\@empty% +\skip0=0.7\normalbaselineskip\relax% +\else% +\skip0=#1\relax% +\fi% +\def\@IEEEstrutARG{#2}% +\ifx\@IEEEstrutARG\@empty% +\skip2=0.3\normalbaselineskip\relax% +\else% +\skip2=#2\relax% +\fi% +% remove stretchability, probably not needed +\dimen0\skip0\relax% +\dimen2\skip2\relax% +\ifIEEEvisiblestruts% +\vrule width0.2pt height\dimen0 depth\dimen2\relax% +\else% +\vrule width0.0pt height\dimen0 depth\dimen2\relax\fi}} + + +% enables strut mode by setting a default strut size and then zeroing the +% \baselineskip, \lineskip, \lineskiplimit and \jot +\def\IEEEeqnarraystrutmode{\IEEEeqnarraystrutsize{0.7\normalbaselineskip}{0.3\normalbaselineskip}[\relax]% +\baselineskip=0pt\lineskip=0pt\lineskiplimit=0pt\jot=0pt} + + +% equation and subequation forms to use to setup hyperref's \@currentHref +\def\@IEEEtheHrefequation{equation.\theHequation} +\def\@IEEEtheHrefsubequation{equation.\theHequation\alph{IEEEsubequation}} + + +\def\IEEEeqnarray{\@IEEEeqnumpersisttrue\@IEEEsubeqnumpersistfalse\@IEEEeqnarray} +\def\endIEEEeqnarray{\end@IEEEeqnarray} + +\@namedef{IEEEeqnarray*}{\@IEEEeqnumpersistfalse\@IEEEsubeqnumpersistfalse\@IEEEeqnarray} +\@namedef{endIEEEeqnarray*}{\end@IEEEeqnarray} + + +% \IEEEeqnarray is an enhanced \eqnarray. +% The star form defaults to not putting equation numbers at the end of each row. +% usage: \IEEEeqnarray[decl]{cols} +\def\@IEEEeqnarray{\relax\@ifnextchar[{\@@IEEEeqnarray}{\@@IEEEeqnarray[\relax]}} +% We have to be careful here to normalize catcodes just before acquiring the +% cols as that specification may contain punctuation which could be subject +% to document catcode changes. +\def\@@IEEEeqnarray[#1]{\begingroup\IEEEnormalcatcodes\@@@IEEEeqnarray[#1]} +\def\@@@IEEEeqnarray[#1]#2{\endgroup + % default to showing the equation number or not based on whether or not + % the star form was involked + \if@IEEEeqnumpersist\global\@eqnswtrue + \else% not the star form + \global\@eqnswfalse + \fi% if star form + % provide a basic hyperref \theHequation if this has not already been setup (hyperref not loaded, or no section counter) + \@ifundefined{theHequation}{\def\theHequation{\arabic{equation}}}{}\relax + % provide dummy hyperref commands in case hyperref is not loaded + \providecommand{\Hy@raisedlink}[1]{}\relax + \providecommand{\hyper@anchorstart}[1]{}\relax + \providecommand{\hyper@anchorend}{}\relax + \providecommand{\@currentHref}{}\relax + \@IEEEeqnumpreadvfalse% reset eqnpreadv flag + \@IEEEsubeqnumpreadvfalse% reset subeqnpreadv flag + \@IEEEeqnarrayISinnerfalse% not yet within the lines of the halign + \@IEEEeqnarraystrutsize{0pt}{0pt}[\relax]% turn off struts by default + \@IEEEeqnarrayusemasterstruttrue% use master strut till user asks otherwise + \IEEEvisiblestrutsfalse% diagnostic mode defaults to off + % no extra space unless the user specifically requests it + \lineskip=0pt\relax + \lineskiplimit=0pt\relax + \baselineskip=\normalbaselineskip\relax% + \jot=\IEEEnormaljot\relax% + \mathsurround\z@\relax% no extra spacing around math + \@advanceIEEEeqncolcnttrue% advance the col counter for each col the user uses, + % used in \IEEEeqnarraymulticol and in the preamble build + %V1.8 Here we preadvance to the next equation number. + % If the user later wants a continued subequation, we can roll back. + \global\@IEEEsubeqnnumrollback=\c@IEEEsubequation% + \stepcounter{equation}\@IEEEeqnumpreadvtrue% advance equation counter before first line + \setcounter{IEEEsubequation}{0}% no subequation yet + \let\@IEEEcurrentlabelsave\@currentlabel% save current label as we later change it globally + \let\@IEEEcurrentHrefsave\@currentHref% save current href label as we later change it globally + \def\@currentlabel{\p@equation\theequation}% redefine the ref label + \def\@currentHref{\@IEEEtheHrefequation}% setup hyperref label + \IEEEeqnarraydecl\relax% allow a way for the user to make global overrides + #1\relax% allow user to override defaults + \let\\\@IEEEeqnarraycr% replace newline with one that can put in eqn. numbers + \global\@IEEEeqncolcnt\z@% col. count = 0 for first line + \@IEEEbuildpreamble{#2}\relax% build the preamble and put it into \@IEEEtrantmptoksA + % put in the column for the equation number + \ifnum\@IEEEeqnnumcols>0\relax\@IEEEappendtoksA{&}\fi% col separator for those after the first + \toks0={##}% + % advance the \@IEEEeqncolcnt for the isolation col, this helps with error checking + \@IEEEappendtoksA{\global\advance\@IEEEeqncolcnt by 1\relax}% + % add the isolation column + \@IEEEappendtoksA{\tabskip\z@skip\bgroup\the\toks0\egroup}% + % advance the \@IEEEeqncolcnt for the equation number col, this helps with error checking + \@IEEEappendtoksA{&\global\advance\@IEEEeqncolcnt by 1\relax}% + % add the equation number col to the preamble + \@IEEEappendtoksA{\tabskip\z@skip\hb@xt@\z@\bgroup\hss\the\toks0\egroup}% + % note \@IEEEeqnnumcols does not count the equation col or isolation col + % set the starting tabskip glue as determined by the preamble build + \tabskip=\@IEEEBPstartglue\relax + % begin the display alignment + \@IEEEeqnarrayISinnertrue% commands are now within the lines + $$\everycr{}\halign to\displaywidth\bgroup + % "exspand" the preamble + \span\the\@IEEEtrantmptoksA\cr} + +% enter isolation/strut column (or the next column if the user did not use +% every column), record the strut status, complete the columns, do the strut if needed, +% restore counters (to backout any equation setup for a next line that was never used) +% to their correct values and exit +\def\end@IEEEeqnarray{\@IEEEeqnarrayglobalizestrutstatus&\@@IEEEeqnarraycr\egroup +\if@IEEEsubeqnumpreadv\global\advance\c@IEEEsubequation\m@ne\fi +\if@IEEEeqnumpreadv\global\advance\c@equation\m@ne\global\c@IEEEsubequation=\@IEEEsubeqnnumrollback\fi +\global\let\@currentlabel\@IEEEcurrentlabelsave% restore current label +\global\let\@currentHref\@IEEEcurrentHrefsave% restore current href label +$$\@ignoretrue} + + +% IEEEeqnarray uses a modifed \\ instead of the plain \cr to +% end rows. This allows for things like \\*[vskip amount] +% These "cr" macros are modified versions of those for LaTeX2e's eqnarray +% the {\ifnum0=`} braces must be kept away from the last column to avoid +% altering spacing of its math, so we use & to advance to the next column +% as there is an isolation/strut column after the user's columns +\def\@IEEEeqnarraycr{\@IEEEeqnarrayglobalizestrutstatus&% save strut status and advance to next column + {\ifnum0=`}\fi + \@ifstar{% + \global\@eqpen\@M\@IEEEeqnarrayYCR + }{% + \global\@eqpen\interdisplaylinepenalty \@IEEEeqnarrayYCR + }% +} + +\def\@IEEEeqnarrayYCR{\@testopt\@IEEEeqnarrayXCR\z@skip} + +\def\@IEEEeqnarrayXCR[#1]{% + \ifnum0=`{\fi}% + \@@IEEEeqnarraycr + \noalign{\penalty\@eqpen\vskip\jot\vskip #1\relax}}% + +\def\@@IEEEeqnarraycr{\@IEEEtrantmptoksA={}% clear token register + \advance\@IEEEeqncolcnt by -1\relax% adjust col count because of the isolation column + \ifnum\@IEEEeqncolcnt>\@IEEEeqnnumcols\relax + \@IEEEclspkgerror{Too many columns within the IEEEeqnarray\MessageBreak + environment}% + {Use fewer \string &'s or put more columns in the IEEEeqnarray column\MessageBreak + specifications.}\relax% + \else + \loop% add cols if the user did not use them all + \ifnum\@IEEEeqncolcnt<\@IEEEeqnnumcols\relax + \@IEEEappendtoksA{&}% + \advance\@IEEEeqncolcnt by 1\relax% update the col count + \repeat + % this number of &'s will take us the the isolation column + \fi + % execute the &'s + \the\@IEEEtrantmptoksA% + % handle the strut/isolation column + \@IEEEeqnarrayinsertstrut% do the strut if needed + \@IEEEeqnarraystrutreset% reset the strut system for next line or IEEEeqnarray + &% and enter the equation number column + \if@eqnsw% only if we display something + \Hy@raisedlink{\hyper@anchorstart{\@currentHref}}% start a hyperref anchor + \global\@IEEEeqnumpreadvfalse\relax% displaying an equation number means + \global\@IEEEsubeqnumpreadvfalse\relax% the equation counters point to valid equations + % V1.8 Here we setup the counters, currentlabel and status for what would be the *next* + % equation line as would be the case under the current settings. However, there are two problems. + % One problem is that there might not ever be a next line. The second problem is that the user + % may later alter the meaning of a line with commands such as \IEEEyessubnumber. So, to handle + % these cases we have to record the current values of the (sub)equation counters and revert back + % to them if the next line is changed or never comes. The \if@IEEEeqnumpreadv, \if@IEEEsubeqnumpreadv + % and \@IEEEsubeqnnumrollback stuff tracks this. + % The logic to handle all this is surprisingly complex, but a nice feature of the approach here is + % that the equation counters and labels remain valid for what the line would be unless a + % \IEEEyessubnumber et al. later changes it. So, any hyperref links are always correct. + \ifnum\c@IEEEsubequation>0\relax% handle subequation + \theIEEEsubequationdis\relax + \if@IEEEsubeqnumpersist% setup for default type of next line + \stepcounter{IEEEsubequation}\global\@IEEEsubeqnumpreadvtrue\relax + \gdef\@currentlabel{\p@IEEEsubequation\theIEEEsubequation}\relax + \gdef\@currentHref{\@IEEEtheHrefsubequation}% setup hyperref label + \else + % if no subeqnum persist, go ahead and setup for a new equation number + \global\@IEEEsubeqnnumrollback=\c@IEEEsubequation + \stepcounter{equation}\global\@IEEEeqnumpreadvtrue\relax + \setcounter{IEEEsubequation}{0}\gdef\@currentlabel{\p@equation\theequation}\relax + \gdef\@currentHref{\@IEEEtheHrefequation}% setup hyperref label + \fi + \else% display a standard equation number + \theequationdis\relax + \setcounter{IEEEsubequation}{0}\relax% not really needed + \if@IEEEsubeqnumpersist% setup for default type of next line + % subequations that follow plain equations carry the same equation number e.g, 5, 5a rather than 5, 6a + \stepcounter{IEEEsubequation}\global\@IEEEsubeqnumpreadvtrue\relax + \gdef\@currentlabel{\p@IEEEsubequation\theIEEEsubequation}\relax + \gdef\@currentHref{\@IEEEtheHrefsubequation}% setup hyperref label + \else + % if no subeqnum persist, go ahead and setup for a new equation number + \global\@IEEEsubeqnnumrollback=\c@IEEEsubequation + \stepcounter{equation}\global\@IEEEeqnumpreadvtrue\relax + \setcounter{IEEEsubequation}{0}\gdef\@currentlabel{\p@equation\theequation}\relax + \gdef\@currentHref{\@IEEEtheHrefequation}% setup hyperref label + \fi + \fi% + \Hy@raisedlink{\hyper@anchorend}% end hyperref anchor + \fi% fi only if we display something + % reset the flags to indicate the default preferences of the display of equation numbers + \if@IEEEeqnumpersist\global\@eqnswtrue\else\global\@eqnswfalse\fi + \if@IEEEsubeqnumpersist\global\@eqnswtrue\fi% ditto for the subequation flag + % reset the number of columns the user actually used + \global\@IEEEeqncolcnt\z@\relax + % the real end of the line + \cr} + + + + + +% \IEEEeqnarraybox is like \IEEEeqnarray except the box form puts everything +% inside a vtop, vbox, or vcenter box depending on the letter in the second +% optional argument (t,b,c). Vbox is the default. Unlike \IEEEeqnarray, +% equation numbers are not displayed and \IEEEeqnarraybox can be nested. +% \IEEEeqnarrayboxm is for math mode (like \array) and does not put the vbox +% within an hbox. +% \IEEEeqnarrayboxt is for text mode (like \tabular) and puts the vbox within +% a \hbox{$ $} construct. +% \IEEEeqnarraybox will auto detect whether to use \IEEEeqnarrayboxm or +% \IEEEeqnarrayboxt depending on the math mode. +% The third optional argument specifies the width this box is to be set to - +% natural width is the default. +% The * forms do not add \jot line spacing +% usage: \IEEEeqnarraybox[decl][pos][width]{cols} +\def\IEEEeqnarrayboxm{\@IEEEeqnarrayboxnojotfalse\@IEEEeqnarrayboxHBOXSWfalse\@IEEEeqnarraybox} +\def\endIEEEeqnarrayboxm{\end@IEEEeqnarraybox} +\@namedef{IEEEeqnarrayboxm*}{\@IEEEeqnarrayboxnojottrue\@IEEEeqnarrayboxHBOXSWfalse\@IEEEeqnarraybox} +\@namedef{endIEEEeqnarrayboxm*}{\end@IEEEeqnarraybox} + +\def\IEEEeqnarrayboxt{\@IEEEeqnarrayboxnojotfalse\@IEEEeqnarrayboxHBOXSWtrue\@IEEEeqnarraybox} +\def\endIEEEeqnarrayboxt{\end@IEEEeqnarraybox} +\@namedef{IEEEeqnarrayboxt*}{\@IEEEeqnarrayboxnojottrue\@IEEEeqnarrayboxHBOXSWtrue\@IEEEeqnarraybox} +\@namedef{endIEEEeqnarrayboxt*}{\end@IEEEeqnarraybox} + +\def\IEEEeqnarraybox{\@IEEEeqnarrayboxnojotfalse\ifmmode\@IEEEeqnarrayboxHBOXSWfalse\else\@IEEEeqnarrayboxHBOXSWtrue\fi% +\@IEEEeqnarraybox} +\def\endIEEEeqnarraybox{\end@IEEEeqnarraybox} + +\@namedef{IEEEeqnarraybox*}{\@IEEEeqnarrayboxnojottrue\ifmmode\@IEEEeqnarrayboxHBOXSWfalse\else\@IEEEeqnarrayboxHBOXSWtrue\fi% +\@IEEEeqnarraybox} +\@namedef{endIEEEeqnarraybox*}{\end@IEEEeqnarraybox} + +% flag to indicate if the \IEEEeqnarraybox needs to put things into an hbox{$ $} +% for \vcenter in non-math mode +\newif\if@IEEEeqnarrayboxHBOXSW% +\@IEEEeqnarrayboxHBOXSWfalse + +\def\@IEEEeqnarraybox{\relax\@ifnextchar[{\@@IEEEeqnarraybox}{\@@IEEEeqnarraybox[\relax]}} +% We have to be careful here to normalize catcodes just before acquiring the +% cols as that specification may contain punctuation which could be subject +% to document catcode changes. +\def\@@IEEEeqnarraybox[#1]{\relax\begingroup\IEEEnormalcatcodes\@ifnextchar[{\@@@IEEEeqnarraybox[#1]}{\@@@IEEEeqnarraybox[#1][b]}} +\def\@@@IEEEeqnarraybox[#1][#2]{\relax\@ifnextchar[{\@@@@IEEEeqnarraybox[#1][#2]}{\@@@@IEEEeqnarraybox[#1][#2][\relax]}} + +% #1 = decl; #2 = t,b,c; #3 = width, #4 = col specs +\def\@@@@IEEEeqnarraybox[#1][#2][#3]#4{\endgroup\@IEEEeqnarrayISinnerfalse % not yet within the lines of the halign + \@IEEEeqnarraymasterstrutsave% save current master strut values + \@IEEEeqnarraystrutsize{0pt}{0pt}[\relax]% turn off struts by default + \@IEEEeqnarrayusemasterstruttrue% use master strut till user asks otherwise + \IEEEvisiblestrutsfalse% diagnostic mode defaults to off + % no extra space unless the user specifically requests it + \lineskip=0pt\relax% + \lineskiplimit=0pt\relax% + \baselineskip=\normalbaselineskip\relax% + \jot=\IEEEnormaljot\relax% + \mathsurround\z@\relax% no extra spacing around math + % the default end glues are zero for an \IEEEeqnarraybox + \edef\@IEEEeqnarraycolSEPdefaultstart{\@IEEEeqnarraycolSEPzero}% default start glue + \edef\@IEEEeqnarraycolSEPdefaultend{\@IEEEeqnarraycolSEPzero}% default end glue + \edef\@IEEEeqnarraycolSEPdefaultmid{\@IEEEeqnarraycolSEPzero}% default inter-column glue + \@advanceIEEEeqncolcntfalse% do not advance the col counter for each col the user uses, + % used in \IEEEeqnarraymulticol and in the preamble build + \IEEEeqnarrayboxdecl\relax% allow a way for the user to make global overrides + #1\relax% allow user to override defaults + \let\\\@IEEEeqnarrayboxcr% replace newline with one that allows optional spacing + \@IEEEbuildpreamble{#4}\relax% build the preamble and put it into \@IEEEtrantmptoksA + % add an isolation column to the preamble to stop \\'s {} from getting into the last col + \ifnum\@IEEEeqnnumcols>0\relax\@IEEEappendtoksA{&}\fi% col separator for those after the first + \toks0={##}% + % add the isolation column to the preamble + \@IEEEappendtoksA{\tabskip\z@skip\bgroup\the\toks0\egroup}% + % set the starting tabskip glue as determined by the preamble build + \tabskip=\@IEEEBPstartglue\relax + % begin the alignment + \everycr{}% + % use only the very first token to determine the positioning + \@IEEEextracttoken{#2}\relax + \ifx\@IEEEextractedtokensdiscarded\@empty\else + \typeout{** WARNING: IEEEeqnarraybox position specifiers after the first in `\@IEEEextracttokenarg' ignored (line \the\inputlineno).}\relax + \fi + % \@IEEEextractedtoken has the first token, the rest are ignored + % if we need to put things into and hbox and go into math mode, do so now + \if@IEEEeqnarrayboxHBOXSW \leavevmode \hbox \bgroup $\fi% + % use the appropriate vbox type + \if\@IEEEextractedtoken t\relax\vtop\else\if\@IEEEextractedtoken c\relax% + \vcenter\else\vbox\fi\fi\bgroup% + \@IEEEeqnarrayISinnertrue% commands are now within the lines + \ifx#3\relax\halign\else\halign to #3\relax\fi% + \bgroup + % "exspand" the preamble + \span\the\@IEEEtrantmptoksA\cr} + +% carry strut status and enter the isolation/strut column, +% exit from math mode if needed, and exit +\def\end@IEEEeqnarraybox{\@IEEEeqnarrayglobalizestrutstatus% carry strut status +&% enter isolation/strut column +\@IEEEeqnarrayinsertstrut% do strut if needed +\@IEEEeqnarraymasterstrutrestore% restore the previous master strut values +% reset the strut system for next IEEEeqnarray +% (sets local strut values back to previous master strut values) +\@IEEEeqnarraystrutreset% +% ensure last line, exit from halign, close vbox +\crcr\egroup\egroup% +% exit from math mode and close hbox if needed +\if@IEEEeqnarrayboxHBOXSW $\egroup\fi} + + + +% IEEEeqnarraybox uses a modifed \\ instead of the plain \cr to +% end rows. This allows for things like \\[vskip amount] +% This "cr" macros are modified versions those for LaTeX2e's eqnarray +% For IEEEeqnarraybox, \\* is the same as \\ +% the {\ifnum0=`} braces must be kept away from the last column to avoid +% altering spacing of its math, so we use & to advance to the isolation/strut column +% carry strut status into isolation/strut column +\def\@IEEEeqnarrayboxcr{\@IEEEeqnarrayglobalizestrutstatus% carry strut status +&% enter isolation/strut column +\@IEEEeqnarrayinsertstrut% do strut if needed +% reset the strut system for next line or IEEEeqnarray +\@IEEEeqnarraystrutreset% +{\ifnum0=`}\fi% +\@ifstar{\@IEEEeqnarrayboxYCR}{\@IEEEeqnarrayboxYCR}} + +% test and setup the optional argument to \\[] +\def\@IEEEeqnarrayboxYCR{\@testopt\@IEEEeqnarrayboxXCR\z@skip} + +% IEEEeqnarraybox does not automatically increase line spacing by \jot +\def\@IEEEeqnarrayboxXCR[#1]{\ifnum0=`{\fi}% +\cr\noalign{\if@IEEEeqnarrayboxnojot\else\vskip\jot\fi\vskip#1\relax}} + + + +% usage: \@IEEEbuildpreamble{column specifiers} +% starts the halign preamble build +% the assembled preamble is put in \@IEEEtrantmptoksA +\def\@IEEEbuildpreamble#1{\@IEEEtrantmptoksA={}% clear token register +\let\@IEEEBPcurtype=u%current column type is not yet known +\let\@IEEEBPprevtype=s%the previous column type was the start +\let\@IEEEBPnexttype=u%next column type is not yet known +% ensure these are valid +\def\@IEEEBPcurglue={0pt plus 0pt minus 0pt}% +\def\@IEEEBPcurcolname{@IEEEdefault}% name of current column definition +% currently acquired numerically referenced glue +% use a name that is easier to remember +\let\@IEEEBPcurnum=\@IEEEtrantmpcountA% +\@IEEEBPcurnum=0% +% tracks number of columns in the preamble +\@IEEEeqnnumcols=0% +% record the default end glues +\edef\@IEEEBPstartglue{\@IEEEeqnarraycolSEPdefaultstart}% +\edef\@IEEEBPendglue{\@IEEEeqnarraycolSEPdefaultend}% +\edef\@IEEEedefMACRO{#1}\relax% fully expand the preamble to support macro containers +% now parse the user's column specifications +% \ignorespaces is used as a delimiter, need at least one trailing \relax because +% \@@IEEEbuildpreamble looks into the future +\expandafter\@@IEEEbuildpreamble\@IEEEedefMACRO\ignorespaces\relax\relax} + + +% usage: \@@IEEEbuildpreamble{current column}{next column} +% parses and builds the halign preamble +\def\@@IEEEbuildpreamble#1#2{\let\@@nextIEEEbuildpreamble=\@@IEEEbuildpreamble% +% use only the very first token to check the end +\@IEEEextracttokengroups{#1}\relax +\ifx\@IEEEextractedfirsttoken\ignorespaces\let\@@nextIEEEbuildpreamble=\@@IEEEfinishpreamble\else% +% identify current and next token type +\@IEEEgetcoltype{#1}{\@IEEEBPcurtype}{1}% current, error on invalid +\@IEEEgetcoltype{#2}{\@IEEEBPnexttype}{0}% next, no error on invalid next +% if curtype is a glue, get the glue def +\if\@IEEEBPcurtype g\@IEEEgetcurglue{#1}{\@IEEEBPcurglue}\fi% +% if curtype is a column, get the column def and set the current column name +\if\@IEEEBPcurtype c\@IEEEgetcurcol{#1}\fi% +% if curtype is a numeral, acquire the user defined glue +\if\@IEEEBPcurtype n\@IEEEprocessNcol{#1}\fi% +% process the acquired glue +\if\@IEEEBPcurtype g\@IEEEprocessGcol\fi% +% process the acquired col +\if\@IEEEBPcurtype c\@IEEEprocessCcol\fi% +% ready prevtype for next col spec. +\let\@IEEEBPprevtype=\@IEEEBPcurtype% +% be sure and put back the future token(s) as a group +\fi\@@nextIEEEbuildpreamble{#2}} + + +% usage: \@@IEEEfinishpreamble{discarded} +% executed just after preamble build is completed +% warn about zero cols, and if prevtype type = u, put in end tabskip glue +% argument is not used +\def\@@IEEEfinishpreamble#1{\ifnum\@IEEEeqnnumcols<1\relax +\@IEEEclspkgerror{No column specifiers declared for IEEEeqnarray}% +{At least one column type must be declared for each IEEEeqnarray.}% +\fi%num cols less than 1 +%if last type undefined, set default end tabskip glue +\if\@IEEEBPprevtype u\@IEEEappendtoksA{\tabskip=\@IEEEBPendglue}\fi} + + +% usage: \@IEEEgetcoltype{col specifier}{\output}{error more} +% Identify and return the column specifier's type code in the given +% \output macro: +% n = number +% g = glue (any other char in catagory 12) +% c = letter +% e = \ignorespaces (end of sequence) +% u = undefined +% error mode: 0 = no error message, 1 = error on invalid char +\def\@IEEEgetcoltype#1#2#3{% +% use only the very first token to determine the type +\@IEEEextracttoken{#1}\relax +% \@IEEEextractedtoken has the first token, the rest are discarded +\let#2=u\relax% assume invalid until know otherwise +\ifx\@IEEEextractedtoken\ignorespaces\let#2=e\else +\ifcat\@IEEEextractedtoken\relax\else% screen out control sequences +\if0\@IEEEextractedtoken\let#2=n\else +\if1\@IEEEextractedtoken\let#2=n\else +\if2\@IEEEextractedtoken\let#2=n\else +\if3\@IEEEextractedtoken\let#2=n\else +\if4\@IEEEextractedtoken\let#2=n\else +\if5\@IEEEextractedtoken\let#2=n\else +\if6\@IEEEextractedtoken\let#2=n\else +\if7\@IEEEextractedtoken\let#2=n\else +\if8\@IEEEextractedtoken\let#2=n\else +\if9\@IEEEextractedtoken\let#2=n\else +\ifcat,\@IEEEextractedtoken\let#2=g\relax +\else\ifcat a\@IEEEextractedtoken\let#2=c\relax\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi +\if#2u\relax +\if0\noexpand#3\relax\else\@IEEEclspkgerror{Invalid character in column specifications}% +{Only letters, numerals and certain other symbols are allowed \MessageBreak +as IEEEeqnarray column specifiers.}\fi\fi} + + +% usage: \@IEEEgetcurcol{col specifier} +% verify the letter referenced column exists +% and return its name in \@IEEEBPcurcolname +% if column specifier is invalid, use the default column @IEEEdefault +\def\@IEEEgetcurcol#1{\expandafter\ifx\csname @IEEEeqnarraycolDEF#1\endcsname\@IEEEeqnarraycolisdefined% +\def\@IEEEBPcurcolname{#1}\else% invalid column name +\@IEEEclspkgerror{Invalid column type "#1" in column specifications.\MessageBreak +Using a default centering column instead}% +{You must define IEEEeqnarray column types before use.}% +\def\@IEEEBPcurcolname{@IEEEdefault}\fi} + + +% usage: \@IEEEgetcurglue{glue specifier}{\output} +% identify the predefined (punctuation) glue value +% and return it in the given output macro +\def\@IEEEgetcurglue#1#2{% +% ! = \! (neg small) -0.16667em (-3/18 em) +% , = \, (small) 0.16667em ( 3/18 em) +% : = \: (med) 0.22222em ( 4/18 em) +% ; = \; (large) 0.27778em ( 5/18 em) +% ' = \quad 1em +% " = \qquad 2em +% . = 0.5\arraycolsep +% / = \arraycolsep +% ? = 2\arraycolsep +% * = 1fil +% + = \@IEEEeqnarraycolSEPcenter +% - = \@IEEEeqnarraycolSEPzero +% Note that all em values are referenced to the math font (textfont2) fontdimen6 +% value for 1em. +% +% use only the very first token to determine the type +\@IEEEextracttoken{#1}\relax +\ifx\@IEEEextractedtokensdiscarded\@empty\else + \typeout{** WARNING: IEEEeqnarray predefined inter-column glue type specifiers after the first in `\@IEEEextracttokenarg' ignored (line \the\inputlineno).}\relax +\fi +% get the math font 1em value +% LaTeX2e's NFSS2 does not preload the fonts, but \IEEEeqnarray needs +% to gain access to the math (\textfont2) font's spacing parameters. +% So we create a bogus box here that uses the math font to ensure +% that \textfont2 is loaded and ready. If this is not done, +% the \textfont2 stuff here may not work. +% Thanks to Bernd Raichle for his 1997 post on this topic. +{\setbox0=\hbox{$\displaystyle\relax$}}% +% fontdimen6 has the width of 1em (a quad). +\@IEEEtrantmpdimenA=\fontdimen6\textfont2\relax% +% identify the glue value based on the first token +% we discard anything after the first +\if!\@IEEEextractedtoken\@IEEEtrantmpdimenA=-0.16667\@IEEEtrantmpdimenA\edef#2{\the\@IEEEtrantmpdimenA}\else +\if,\@IEEEextractedtoken\@IEEEtrantmpdimenA=0.16667\@IEEEtrantmpdimenA\edef#2{\the\@IEEEtrantmpdimenA}\else +\if:\@IEEEextractedtoken\@IEEEtrantmpdimenA=0.22222\@IEEEtrantmpdimenA\edef#2{\the\@IEEEtrantmpdimenA}\else +\if;\@IEEEextractedtoken\@IEEEtrantmpdimenA=0.27778\@IEEEtrantmpdimenA\edef#2{\the\@IEEEtrantmpdimenA}\else +\if'\@IEEEextractedtoken\@IEEEtrantmpdimenA=1\@IEEEtrantmpdimenA\edef#2{\the\@IEEEtrantmpdimenA}\else +\if"\@IEEEextractedtoken\@IEEEtrantmpdimenA=2\@IEEEtrantmpdimenA\edef#2{\the\@IEEEtrantmpdimenA}\else +\if.\@IEEEextractedtoken\@IEEEtrantmpdimenA=0.5\arraycolsep\edef#2{\the\@IEEEtrantmpdimenA}\else +\if/\@IEEEextractedtoken\edef#2{\the\arraycolsep}\else +\if?\@IEEEextractedtoken\@IEEEtrantmpdimenA=2\arraycolsep\edef#2{\the\@IEEEtrantmpdimenA}\else +\if *\@IEEEextractedtoken\edef#2{0pt plus 1fil minus 0pt}\else +\if+\@IEEEextractedtoken\edef#2{\@IEEEeqnarraycolSEPcenter}\else +\if-\@IEEEextractedtoken\edef#2{\@IEEEeqnarraycolSEPzero}\else +\edef#2{\@IEEEeqnarraycolSEPzero}% +\@IEEEclspkgerror{Invalid predefined inter-column glue type "#1" in\MessageBreak +column specifications. Using a default value of\MessageBreak +0pt instead}% +{Only !,:;'"./?*+ and - are valid predefined glue types in the\MessageBreak +IEEEeqnarray column specifications.}\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + + +% usage: \@IEEEprocessNcol{digit} +% process a numerical digit from the column specification +% and look up the corresponding user defined glue value +% can transform current type from n to g or a as the user defined glue is acquired +\def\@IEEEprocessNcol#1{\if\@IEEEBPprevtype g% +\@IEEEclspkgerror{Back-to-back inter-column glue specifiers in column\MessageBreak +specifications. Ignoring consecutive glue specifiers\MessageBreak +after the first}% +{You cannot have two or more glue types next to each other\MessageBreak +in the IEEEeqnarray column specifications.}% +\let\@IEEEBPcurtype=a% abort this glue, future digits will be discarded +\@IEEEBPcurnum=0\relax% +\else% if we previously aborted a glue +\if\@IEEEBPprevtype a\@IEEEBPcurnum=0\let\@IEEEBPcurtype=a%maintain digit abortion +\else%acquire this number +% save the previous type before the numerical digits started +\if\@IEEEBPprevtype n\else\let\@IEEEBPprevsavedtype=\@IEEEBPprevtype\fi% +\multiply\@IEEEBPcurnum by 10\relax% +\advance\@IEEEBPcurnum by #1\relax% add in number, \relax is needed to stop TeX's number scan +\if\@IEEEBPnexttype n\else%close acquisition +\expandafter\ifx\csname @IEEEeqnarraycolSEPDEF\expandafter\romannumeral\number\@IEEEBPcurnum\endcsname\@IEEEeqnarraycolisdefined% +\edef\@IEEEBPcurglue{\csname @IEEEeqnarraycolSEP\expandafter\romannumeral\number\@IEEEBPcurnum\endcsname}% +\else%user glue not defined +\@IEEEclspkgerror{Invalid user defined inter-column glue type "\number\@IEEEBPcurnum" in\MessageBreak +column specifications. Using a default value of\MessageBreak +0pt instead}% +{You must define all IEEEeqnarray numerical inter-column glue types via\MessageBreak +\string\IEEEeqnarraydefcolsep \space before they are used in column specifications.}% +\edef\@IEEEBPcurglue{\@IEEEeqnarraycolSEPzero}% +\fi% glue defined or not +\let\@IEEEBPcurtype=g% change the type to reflect the acquired glue +\let\@IEEEBPprevtype=\@IEEEBPprevsavedtype% restore the prev type before this number glue +\@IEEEBPcurnum=0\relax%ready for next acquisition +\fi%close acquisition, get glue +\fi%discard or acquire number +\fi%prevtype glue or not +} + + +% process an acquired glue +% add any acquired column/glue pair to the preamble +\def\@IEEEprocessGcol{\if\@IEEEBPprevtype a\let\@IEEEBPcurtype=a%maintain previous glue abortions +\else +% if this is the start glue, save it, but do nothing else +% as this is not used in the preamble, but before +\if\@IEEEBPprevtype s\edef\@IEEEBPstartglue{\@IEEEBPcurglue}% +\else%not the start glue +\if\@IEEEBPprevtype g%ignore if back to back glues +\@IEEEclspkgerror{Back-to-back inter-column glue specifiers in column\MessageBreak +specifications. Ignoring consecutive glue specifiers\MessageBreak +after the first}% +{You cannot have two or more glue types next to each other\MessageBreak +in the IEEEeqnarray column specifications.}% +\let\@IEEEBPcurtype=a% abort this glue +\else% not a back to back glue +\if\@IEEEBPprevtype c\relax% if the previoustype was a col, add column/glue pair to preamble +\ifnum\@IEEEeqnnumcols>0\relax\@IEEEappendtoksA{&}\fi +\toks0={##}% +% make preamble advance col counter if this environment needs this +\if@advanceIEEEeqncolcnt\@IEEEappendtoksA{\global\advance\@IEEEeqncolcnt by 1\relax}\fi +% insert the column defintion into the preamble, being careful not to expand +% the column definition +\@IEEEappendtoksA{\tabskip=\@IEEEBPcurglue}% +\@IEEEappendNOEXPANDtoksA{\begingroup\csname @IEEEeqnarraycolPRE}% +\@IEEEappendtoksA{\@IEEEBPcurcolname}% +\@IEEEappendNOEXPANDtoksA{\endcsname}% +\@IEEEappendtoksA{\the\toks0}% +\@IEEEappendNOEXPANDtoksA{\relax\relax\relax\relax\relax% +\relax\relax\relax\relax\relax\csname @IEEEeqnarraycolPOST}% +\@IEEEappendtoksA{\@IEEEBPcurcolname}% +\@IEEEappendNOEXPANDtoksA{\endcsname\relax\relax\relax\relax\relax% +\relax\relax\relax\relax\relax\endgroup}% +\advance\@IEEEeqnnumcols by 1\relax%one more column in the preamble +\else% error: non-start glue with no pending column +\@IEEEclspkgerror{Inter-column glue specifier without a prior column\MessageBreak +type in the column specifications. Ignoring this glue\MessageBreak +specifier}% +{Except for the first and last positions, glue can be placed only\MessageBreak +between column types.}% +\let\@IEEEBPcurtype=a% abort this glue +\fi% previous was a column +\fi% back-to-back glues +\fi% is start column glue +\fi% prev type not a +} + + +% process an acquired letter referenced column and, if necessary, add it to the preamble +\def\@IEEEprocessCcol{\if\@IEEEBPnexttype g\else +\if\@IEEEBPnexttype n\else +% we have a column followed by something other than a glue (or numeral glue) +% so we must add this column to the preamble now +\ifnum\@IEEEeqnnumcols>0\relax\@IEEEappendtoksA{&}\fi%col separator for those after the first +\if\@IEEEBPnexttype e\@IEEEappendtoksA{\tabskip=\@IEEEBPendglue\relax}\else%put in end glue +\@IEEEappendtoksA{\tabskip=\@IEEEeqnarraycolSEPdefaultmid\relax}\fi% or default mid glue +\toks0={##}% +% make preamble advance col counter if this environment needs this +\if@advanceIEEEeqncolcnt\@IEEEappendtoksA{\global\advance\@IEEEeqncolcnt by 1\relax}\fi +% insert the column definition into the preamble, being careful not to expand +% the column definition +\@IEEEappendNOEXPANDtoksA{\begingroup\csname @IEEEeqnarraycolPRE}% +\@IEEEappendtoksA{\@IEEEBPcurcolname}% +\@IEEEappendNOEXPANDtoksA{\endcsname}% +\@IEEEappendtoksA{\the\toks0}% +\@IEEEappendNOEXPANDtoksA{\relax\relax\relax\relax\relax% +\relax\relax\relax\relax\relax\csname @IEEEeqnarraycolPOST}% +\@IEEEappendtoksA{\@IEEEBPcurcolname}% +\@IEEEappendNOEXPANDtoksA{\endcsname\relax\relax\relax\relax\relax% +\relax\relax\relax\relax\relax\endgroup}% +\advance\@IEEEeqnnumcols by 1\relax%one more column in the preamble +\fi%next type not numeral +\fi%next type not glue +} + + +%% +%% END OF IEEEeqnarray DEFINITIONS +%% + + + + + +% set up the running headers and footers +% +% header and footer font and size specifications +\def\@IEEEheaderstyle{\normalfont\scriptsize} +\def\@IEEEfooterstyle{\normalfont\scriptsize} +% +% compsoc uses sans-serif headers and footers +\ifCLASSOPTIONcompsoc + \def\@IEEEheaderstyle{\normalfont\sffamily\scriptsize} + \def\@IEEEfooterstyle{\normalfont\sffamily\scriptsize} +\fi + + +% standard page style, ps@headings +\def\ps@headings{% default to standard twoside headers, no footers +% will change later if the mode requires otherwise +\def\@oddhead{\hbox{}\@IEEEheaderstyle\rightmark\hfil\thepage}\relax +\def\@evenhead{\@IEEEheaderstyle\thepage\hfil\leftmark\hbox{}}\relax +\let\@oddfoot\@empty +\let\@evenfoot\@empty +\ifCLASSOPTIONtechnote + % technote twoside + \def\@oddhead{\hbox{}\@IEEEheaderstyle\leftmark\hfil\thepage}\relax + \def\@evenhead{\@IEEEheaderstyle\thepage\hfil\leftmark\hbox{}}\relax +\fi +\ifCLASSOPTIONdraftcls + % draft footers + \def\@oddfoot{\@IEEEfooterstyle\@date\hfil DRAFT}\relax + \def\@evenfoot{\@IEEEfooterstyle DRAFT\hfil\@date}\relax +\fi +% oneside +\if@twoside\else + % standard one side headers + \def\@oddhead{\hbox{}\@IEEEheaderstyle\leftmark\hfil\thepage}\relax + \let\@evenhead\@empty + \ifCLASSOPTIONdraftcls + % oneside draft footers + \def\@oddfoot{\@IEEEfooterstyle\@date\hfil DRAFT}\relax + \let\@evenfoot\@empty + \fi +\fi +% turn off headers for conferences +\ifCLASSOPTIONconference + \let\@oddhead\@empty + \let\@evenhead\@empty +\fi +% turn off footers for draftclsnofoot +\ifCLASSOPTIONdraftclsnofoot + \let\@oddfoot\@empty + \let\@evenfoot\@empty +\fi} + + +% title page style, ps@IEEEtitlepagestyle +\def\ps@IEEEtitlepagestyle{% default title page headers, no footers +\def\@oddhead{\hbox{}\@IEEEheaderstyle\leftmark\hfil\thepage}\relax +\def\@evenhead{\@IEEEheaderstyle\thepage\hfil\leftmark\hbox{}}\relax +\let\@oddfoot\@empty +\let\@evenfoot\@empty +% will change later if the mode requires otherwise +\ifCLASSOPTIONdraftcls + % draft footers + \ifCLASSOPTIONdraftclsnofoot\else + % but only if not draftclsnofoot + \def\@oddfoot{\@IEEEfooterstyle\@date\hfil DRAFT}\relax + \def\@evenfoot{\@IEEEfooterstyle DRAFT\hfil\@date}\relax + \fi +\else + % all nondraft mode footers + \if@IEEEusingpubid + % for title pages that are using a pubid + % do not repeat pubid on the title page if using a peer review cover page + \ifCLASSOPTIONpeerreview\else + % for noncompsoc papers, the pubid uses footnotesize and + % is at the same vertical position as where the last baseline would normally be + \def\@oddfoot{\hbox{}\hss\@IEEEfooterstyle\footnotesize\raisebox{\footskip}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \def\@evenfoot{\hbox{}\hss\@IEEEfooterstyle\footnotesize\raisebox{\footskip}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \ifCLASSOPTIONcompsoc + % for compsoc papers, the pubid is at the same vertical position as the normal footer + \def\@oddfoot{\hbox{}\hss\@IEEEfooterstyle\raisebox{0pt}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \def\@evenfoot{\hbox{}\hss\@IEEEfooterstyle\raisebox{0pt}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \fi + \fi + \fi +\fi +% turn off headers for conferences +\ifCLASSOPTIONconference + \let\@oddhead\@empty + \let\@evenhead\@empty +\fi} + + +% peer review cover page style, ps@IEEEpeerreviewcoverpagestyle +\def\ps@IEEEpeerreviewcoverpagestyle{% default peer review cover no headers, no footers +\let\@oddhead\@empty +\let\@evenhead\@empty +\let\@oddfoot\@empty +\let\@evenfoot\@empty +% will change later if the mode requires otherwise +\ifCLASSOPTIONdraftcls + % draft footers + \ifCLASSOPTIONdraftclsnofoot\else + % but only if not draftclsnofoot + \def\@oddfoot{\@IEEEfooterstyle\@date\hfil DRAFT}\relax + \def\@evenfoot{\@IEEEfooterstyle DRAFT\hfil\@date}\relax + \fi +\else + % all nondraft mode footers + \if@IEEEusingpubid + % for peer review cover pages that are using a pubid + % for noncompsoc papers, the pubid uses footnotesize and + % is at the same vertical position as where the last baseline would normally be + \def\@oddfoot{\hbox{}\hss\@IEEEfooterstyle\footnotesize\raisebox{\footskip}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \def\@evenfoot{\hbox{}\hss\@IEEEfooterstyle\footnotesize\raisebox{\footskip}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \ifCLASSOPTIONcompsoc + % for compsoc papers, the pubid is at the same vertical position as the normal footer + \def\@oddfoot{\hbox{}\hss\@IEEEfooterstyle\raisebox{0pt}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \def\@evenfoot{\hbox{}\hss\@IEEEfooterstyle\raisebox{0pt}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \fi + \fi +\fi} + + + +%% Defines the command for putting the header. +%% Note that all the text is forced into uppercase, if you have some text +%% that needs to be in lower case, for instance et. al., then either manually +%% set \leftmark and \rightmark or use \MakeLowercase{et. al.} within the +%% arguments to \markboth. +%% V1.7b add \protect to work with Babel +\def\markboth#1#2{\def\leftmark{\MakeUppercase{\protect#1}}% +\def\rightmark{\MakeUppercase{\protect#2}}} + +\def\today{\ifcase\month\or + January\or February\or March\or April\or May\or June\or + July\or August\or September\or October\or November\or December\fi + \space\number\day, \number\year} + + + + +%% CITATION AND BIBLIOGRAPHY COMMANDS +%% +%% V1.6 no longer supports the older, nonstandard \shortcite and \citename setup stuff +% +% +% Modify Latex2e \@citex to separate citations with "], [" +\def\@citex[#1]#2{% + \let\@citea\@empty + \@cite{\@for\@citeb:=#2\do + {\@citea\def\@citea{], [}% + \edef\@citeb{\expandafter\@firstofone\@citeb\@empty}% + \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi + \@ifundefined{b@\@citeb}{\mbox{\reset@font\bfseries ?}% + \G@refundefinedtrue + \@latex@warning + {Citation `\@citeb' on page \thepage \space undefined}}% + {\hbox{\csname b@\@citeb\endcsname}}}}{#1}} + +% V1.6 we create hooks for the optional use of Donald Arseneau's +% cite.sty package. cite.sty is "smart" and will notice that the +% following format controls are already defined and will not +% redefine them. The result will be the proper sorting of the +% citation numbers and auto detection of 3 or more entry "ranges" - +% all in IEEE style: [1], [2], [5]--[7], [12] +% This also allows for an optional note, i.e., \cite[mynote]{..}. +% If the \cite with note has more than one reference, the note will +% be applied to the last of the listed references. It is generally +% desired that if a note is given, only one reference is listed in +% that \cite. +% Thanks to Mr. Arseneau for providing the required format arguments +% to produce the IEEE style. +\def\citepunct{], [} +\def\citedash{]--[} + +% V1.7 default to using same font for urls made by url.sty +\AtBeginDocument{\csname url@samestyle\endcsname} + +% V1.6 class files should always provide these +\def\newblock{\hskip .11em\@plus.33em\@minus.07em} +\let\@openbib@code\@empty +% V1.8b article.cls is now providing these too +% we do not use \@mkboth, nor alter the page style +\newenvironment{theindex} + {\if@twocolumn + \@restonecolfalse + \else + \@restonecoltrue + \fi + \twocolumn[\section*{\indexname}]% + \parindent\z@ + \parskip\z@ \@plus .3\p@\relax + \columnseprule \z@ + \columnsep 35\p@ + \let\item\@idxitem} + {\if@restonecol\onecolumn\else\clearpage\fi} +\newcommand\@idxitem{\par\hangindent 40\p@} +\newcommand\subitem{\@idxitem \hspace*{20\p@}} +\newcommand\subsubitem{\@idxitem \hspace*{30\p@}} +\newcommand\indexspace{\par \vskip 10\p@ \@plus5\p@ \@minus3\p@\relax} + + + +% Provide support for the control entries of IEEEtran.bst V1.00 and later. +% V1.7 optional argument allows for a different aux file to be specified in +% order to handle multiple bibliographies. For example, with multibib.sty: +% \newcites{sec}{Secondary Literature} +% \bstctlcite[@auxoutsec]{BSTcontrolhak} +\def\bstctlcite{\@ifnextchar[{\@bstctlcite}{\@bstctlcite[@auxout]}} +\def\@bstctlcite[#1]#2{\@bsphack + \@for\@citeb:=#2\do{% + \edef\@citeb{\expandafter\@firstofone\@citeb}% + \if@filesw\immediate\write\csname #1\endcsname{\string\citation{\@citeb}}\fi}% + \@esphack} + +% \IEEEnoauxwrite{} allows for citations that do not add to or affect +% the order of the existing citation list. Can be useful for \cite +% within \thanks{}. +\DeclareRobustCommand{\IEEEnoauxwrite}[1]{\relax +\if@filesw +\@fileswfalse +#1\relax\relax\relax\relax\relax +\@fileswtrue +\else +#1\relax\relax\relax\relax\relax +\fi} + +% V1.6 provide a way for a user to execute a command just before +% a given reference number - used to insert a \newpage to balance +% the columns on the last page +\edef\@IEEEtriggerrefnum{0} % the default of zero means that + % the command is not executed +\def\@IEEEtriggercmd{\newpage} + +% allow the user to alter the triggered command +\long\def\IEEEtriggercmd#1{\long\def\@IEEEtriggercmd{#1}} + +% allow user a way to specify the reference number just before the +% command is executed +\def\IEEEtriggeratref#1{\@IEEEtrantmpcountA=#1% +\edef\@IEEEtriggerrefnum{\the\@IEEEtrantmpcountA}}% + +% trigger command at the given reference +\def\@IEEEbibitemprefix{\@IEEEtrantmpcountA=\@IEEEtriggerrefnum\relax% +\advance\@IEEEtrantmpcountA by -1\relax% +\ifnum\c@enumiv=\@IEEEtrantmpcountA\relax\@IEEEtriggercmd\relax\fi} + + +\def\@biblabel#1{[#1]} + +% compsoc journals and conferences left align the reference numbers +\@IEEEcompsoconly{\def\@biblabel#1{[#1]\hfill}} + +% controls bib item spacing +\def\IEEEbibitemsep{0pt plus .5pt} + +\@IEEEcompsocconfonly{\def\IEEEbibitemsep{0.5\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip}} + + +\def\thebibliography#1{\section*{\refname}% + \addcontentsline{toc}{section}{\refname}% + % V1.6 add some rubber space here and provide a command trigger + \footnotesize\vskip 0.3\baselineskip plus 0.1\baselineskip minus 0.1\baselineskip% + \list{\@biblabel{\@arabic\c@enumiv}}% + {\settowidth\labelwidth{\@biblabel{#1}}% + \leftmargin\labelwidth + \advance\leftmargin\labelsep\relax + \itemsep \IEEEbibitemsep\relax + \usecounter{enumiv}% + \let\p@enumiv\@empty + \renewcommand\theenumiv{\@arabic\c@enumiv}}% + \let\@IEEElatexbibitem\bibitem% + \def\bibitem{\@IEEEbibitemprefix\@IEEElatexbibitem}% +\def\newblock{\hskip .11em plus .33em minus .07em}% +% originally: +% \sloppy\clubpenalty4000\widowpenalty4000% +% by adding the \interlinepenalty here, we make it more +% difficult, but not impossible, for LaTeX to break within a reference. +% The IEEE almost never breaks a reference (but they do it more often with +% technotes). You may get an underfull vbox warning around the bibliography, +% but the final result will be much more like what the IEEE will publish. +% MDS 11/2000 +\ifCLASSOPTIONtechnote\sloppy\clubpenalty4000\widowpenalty4000\interlinepenalty100% +\else\sloppy\clubpenalty4000\widowpenalty4000\interlinepenalty500\fi% + \sfcode`\.=1000\relax} +\let\endthebibliography=\endlist + + + + +% TITLE PAGE COMMANDS +% +% +% \IEEEmembership is used to produce the sublargesize italic font used to indicate author +% IEEE membership. compsoc uses a large size sans slant font +\def\IEEEmembership#1{{\@IEEEnotcompsoconly{\sublargesize}\normalfont\@IEEEcompsoconly{\sffamily}\textit{#1}}} + + +% \IEEEauthorrefmark{} produces a footnote type symbol to indicate author affiliation. +% When given an argument of 1 to 9, \IEEEauthorrefmark{} follows the standard LaTeX footnote +% symbol sequence convention. However, for arguments 10 and above, \IEEEauthorrefmark{} +% reverts to using lower case roman numerals, so it cannot overflow. Do note that you +% cannot use \footnotemark[] in place of \IEEEauthorrefmark{} within \author as the footnote +% symbols will have been turned off to prevent \thanks from creating footnote marks. +% \IEEEauthorrefmark{} produces a symbol that appears to LaTeX as having zero vertical +% height - this allows for a more compact line packing, but the user must ensure that +% the interline spacing is large enough to prevent \IEEEauthorrefmark{} from colliding +% with the text above. +% V1.7 make this a robust command +% V1.8 transmag uses an arabic author affiliation symbol +\ifCLASSOPTIONtransmag +\DeclareRobustCommand*{\IEEEauthorrefmark}[1]{\raisebox{0pt}[0pt][0pt]{\textsuperscript{\footnotesize #1}}} +\else +\DeclareRobustCommand*{\IEEEauthorrefmark}[1]{\raisebox{0pt}[0pt][0pt]{\textsuperscript{\footnotesize\ensuremath{\ifcase#1\or *\or \dagger\or \ddagger\or% + \mathsection\or \mathparagraph\or \|\or **\or \dagger\dagger% + \or \ddagger\ddagger \else\textsuperscript{\expandafter\romannumeral#1}\fi}}}} +\fi + + +% FONT CONTROLS AND SPACINGS FOR CONFERENCE MODE AUTHOR NAME AND AFFILIATION BLOCKS +% +% The default font styles for the author name and affiliation blocks (confmode) +\def\@IEEEauthorblockNstyle{\normalfont\@IEEEcompsocnotconfonly{\sffamily}\sublargesize} +\def\@IEEEauthorblockAstyle{\normalfont\@IEEEcompsocnotconfonly{\sffamily}\@IEEEcompsocconfonly{\itshape}\normalsize} +% The default if the user does not use an author block +\def\@IEEEauthordefaulttextstyle{\normalfont\@IEEEcompsocnotconfonly{\sffamily}\sublargesize} + +% adjustment spacing from title (or special paper notice) to author name blocks (confmode) +% can be negative +\def\@IEEEauthorblockconfadjspace{-0.25em} +% compsoc conferences need more space here +\@IEEEcompsocconfonly{\def\@IEEEauthorblockconfadjspace{0.75\@IEEEnormalsizeunitybaselineskip}} + +% spacing between name and affiliation blocks (confmode) +% This can be negative. +% The IEEE doesn't want any added spacing here, but I will leave these +% controls in place in case they ever change their mind. +% Personally, I like 0.75ex. +%\def\@IEEEauthorblockNtopspace{0.75ex} +%\def\@IEEEauthorblockAtopspace{0.75ex} +\def\@IEEEauthorblockNtopspace{0.0ex} +\def\@IEEEauthorblockAtopspace{0.0ex} +\ifCLASSOPTIONtransmag +% transmag uses one line of space above first affiliation block +\def\@IEEEauthorblockAtopspace{1\@IEEEnormalsizeunitybaselineskip} +\fi + +% baseline spacing within name and affiliation blocks (confmode) +% must be positive, spacings below certain values will make +% the position of line of text sensitive to the contents of the +% line above it i.e., whether or not the prior line has descenders, +% subscripts, etc. For this reason it is a good idea to keep +% these above 2.6ex +\def\@IEEEauthorblockNinterlinespace{2.6ex} +\def\@IEEEauthorblockAinterlinespace{2.75ex} + +% This tracks the required strut size. +% See the \@IEEEauthorhalign command for the actual default value used. +\def\@IEEEauthorblockXinterlinespace{2.7ex} + +% variables to retain font size and style across groups +% values given here have no effect as they will be overwritten later +\gdef\@IEEESAVESTATEfontsize{10} +\gdef\@IEEESAVESTATEfontbaselineskip{12} +\gdef\@IEEESAVESTATEfontencoding{OT1} +\gdef\@IEEESAVESTATEfontfamily{ptm} +\gdef\@IEEESAVESTATEfontseries{m} +\gdef\@IEEESAVESTATEfontshape{n} + +% saves the current font attributes +\def\@IEEEcurfontSAVE{\global\let\@IEEESAVESTATEfontsize\f@size% +\global\let\@IEEESAVESTATEfontbaselineskip\f@baselineskip% +\global\let\@IEEESAVESTATEfontencoding\f@encoding% +\global\let\@IEEESAVESTATEfontfamily\f@family% +\global\let\@IEEESAVESTATEfontseries\f@series% +\global\let\@IEEESAVESTATEfontshape\f@shape} + +% restores the saved font attributes +\def\@IEEEcurfontRESTORE{\fontsize{\@IEEESAVESTATEfontsize}{\@IEEESAVESTATEfontbaselineskip}% +\fontencoding{\@IEEESAVESTATEfontencoding}% +\fontfamily{\@IEEESAVESTATEfontfamily}% +\fontseries{\@IEEESAVESTATEfontseries}% +\fontshape{\@IEEESAVESTATEfontshape}% +\selectfont} + + +% variable to indicate if the current block is the first block in the column +\newif\if@IEEEprevauthorblockincol \@IEEEprevauthorblockincolfalse + + +% the command places a strut with height and depth = \@IEEEauthorblockXinterlinespace +% we use this technique to have complete manual control over the spacing of the lines +% within the halign environment. +% We set the below baseline portion at 30%, the above +% baseline portion at 70% of the total length. +% Responds to changes in the document's \baselinestretch +\def\@IEEEauthorstrutrule{\@IEEEtrantmpdimenA\@IEEEauthorblockXinterlinespace% +\@IEEEtrantmpdimenA=\baselinestretch\@IEEEtrantmpdimenA% +\rule[-0.3\@IEEEtrantmpdimenA]{0pt}{\@IEEEtrantmpdimenA}} + + +% blocks to hold the authors' names and affilations. +% Makes formatting easy for conferences +% +% use real definitions in conference mode +% name block +\def\IEEEauthorblockN#1{\relax\@IEEEauthorblockNstyle% set the default text style +\gdef\@IEEEauthorblockXinterlinespace{0pt}% disable strut for spacer row +% the \expandafter hides the \cr in conditional tex, see the array.sty docs +% for details, probably not needed here as the \cr is in a macro +% do a spacer row if needed +\if@IEEEprevauthorblockincol\expandafter\@IEEEauthorblockNtopspaceline\fi +\global\@IEEEprevauthorblockincoltrue% we now have a block in this column +%restore the correct strut value +\gdef\@IEEEauthorblockXinterlinespace{\@IEEEauthorblockNinterlinespace}% +% input the author names +#1% +% end the row if the user did not already +\crcr} +% spacer row for names +\def\@IEEEauthorblockNtopspaceline{\cr\noalign{\vskip\@IEEEauthorblockNtopspace}} +% +% affiliation block +\def\IEEEauthorblockA#1{\relax\@IEEEauthorblockAstyle% set the default text style +\gdef\@IEEEauthorblockXinterlinespace{0pt}%disable strut for spacer row +% the \expandafter hides the \cr in conditional tex, see the array.sty docs +% for details, probably not needed here as the \cr is in a macro +% do a spacer row if needed +\if@IEEEprevauthorblockincol\expandafter\@IEEEauthorblockAtopspaceline\fi +\global\@IEEEprevauthorblockincoltrue% we now have a block in this column +%restore the correct strut value +\gdef\@IEEEauthorblockXinterlinespace{\@IEEEauthorblockAinterlinespace}% +% input the author affiliations +#1% +% end the row if the user did not already +\crcr +% V1.8 transmag does not use any additional affiliation spacing after the first author +\ifCLASSOPTIONtransmag\gdef\@IEEEauthorblockAtopspace{0pt}\fi} + +% spacer row for affiliations +\def\@IEEEauthorblockAtopspaceline{\cr\noalign{\vskip\@IEEEauthorblockAtopspace}} + + +% allow papers to compile even if author blocks are used in modes other +% than conference or peerreviewca. For such cases, we provide dummy blocks. +\ifCLASSOPTIONconference +\else + \ifCLASSOPTIONpeerreviewca\else + % not conference, peerreviewca or transmag mode + \ifCLASSOPTIONtransmag\else + \def\IEEEauthorblockN#1{#1}% + \def\IEEEauthorblockA#1{#1}% + \fi + \fi +\fi + + + +% we provide our own halign so as not to have to depend on tabular +\def\@IEEEauthorhalign{\@IEEEauthordefaulttextstyle% default text style + \lineskip=0pt\relax% disable line spacing + \lineskiplimit=0pt\relax% + \baselineskip=0pt\relax% + \@IEEEcurfontSAVE% save the current font + \mathsurround\z@\relax% no extra spacing around math + \let\\\@IEEEauthorhaligncr% replace newline with halign friendly one + \tabskip=0pt\relax% no column spacing + \everycr{}% ensure no problems here + \@IEEEprevauthorblockincolfalse% no author blocks yet + \def\@IEEEauthorblockXinterlinespace{2.7ex}% default interline space + \vtop\bgroup%vtop box + \halign\bgroup&\relax\hfil\@IEEEcurfontRESTORE\relax ##\relax + \hfil\@IEEEcurfontSAVE\@IEEEauthorstrutrule\cr} + +% ensure last line, exit from halign, close vbox +\def\end@IEEEauthorhalign{\crcr\egroup\egroup} + +% handle bogus star form +\def\@IEEEauthorhaligncr{{\ifnum0=`}\fi\@ifstar{\@@IEEEauthorhaligncr}{\@@IEEEauthorhaligncr}} + +% test and setup the optional argument to \\[] +\def\@@IEEEauthorhaligncr{\@testopt\@@@IEEEauthorhaligncr\z@skip} + +% end the line and do the optional spacer +\def\@@@IEEEauthorhaligncr[#1]{\ifnum0=`{\fi}\cr\noalign{\vskip#1\relax}} + + + +% flag to prevent multiple \and warning messages +\newif\if@IEEEWARNand +\@IEEEWARNandtrue + +% if in conference or peerreviewca modes, we support the use of \and as \author is a +% tabular environment, otherwise we warn the user that \and is invalid +% outside of conference or peerreviewca modes. +\def\and{\relax} % provide a bogus \and that we will then override + +\renewcommand{\and}[1][\relax]{\if@IEEEWARNand\typeout{** WARNING: \noexpand\and is valid only + when in conference or peerreviewca}\typeout{modes (line \the\inputlineno).}\fi\global\@IEEEWARNandfalse} + +\ifCLASSOPTIONconference% +\renewcommand{\and}[1][\hfill]{\end{@IEEEauthorhalign}#1\begin{@IEEEauthorhalign}}% +\fi +\ifCLASSOPTIONpeerreviewca +\renewcommand{\and}[1][\hfill]{\end{@IEEEauthorhalign}#1\begin{@IEEEauthorhalign}}% +\fi +% V1.8 transmag uses conference author format +\ifCLASSOPTIONtransmag +\renewcommand{\and}[1][\hfill]{\end{@IEEEauthorhalign}#1\begin{@IEEEauthorhalign}}% +\fi + +% page clearing command +% based on LaTeX2e's \cleardoublepage, but allows different page styles +% for the inserted blank pages +\def\@IEEEcleardoublepage#1{\clearpage\if@twoside\ifodd\c@page\else +\hbox{}\thispagestyle{#1}\newpage\if@twocolumn\hbox{}\thispagestyle{#1}\newpage\fi\fi\fi} + +% V1.8b hooks to allow adjustment of space above title +\def\IEEEtitletopspace{0.5\baselineskip} +% an added extra amount to allow for adjustment/offset +\def\IEEEtitletopspaceextra{0pt} + +% user command to invoke the title page +\def\maketitle{\par% + \begingroup% + \normalfont% + \def\thefootnote{}% the \thanks{} mark type is empty + \def\footnotemark{}% and kill space from \thanks within author + \let\@makefnmark\relax% V1.7, must *really* kill footnotemark to remove all \textsuperscript spacing as well. + \footnotesize% equal spacing between thanks lines + \footnotesep 0.7\baselineskip%see global setting of \footnotesep for more info + % V1.7 disable \thanks note indention for compsoc + \@IEEEcompsoconly{\long\def\@makefntext##1{\parindent 1em\noindent\hbox{\@makefnmark}##1}}% + \normalsize% + \ifCLASSOPTIONpeerreview + \newpage\global\@topnum\z@ \@maketitle\@IEEEstatictitlevskip\@IEEEaftertitletext% + \thispagestyle{IEEEpeerreviewcoverpagestyle}\@thanks% + \else + \if@twocolumn% + \ifCLASSOPTIONtechnote% + \newpage\global\@topnum\z@ \@maketitle\@IEEEstatictitlevskip\@IEEEaftertitletext% + \else + \twocolumn[{\IEEEquantizevspace{\@maketitle}[\IEEEquantizedisabletitlecmds]{0pt}[-\topskip]{\baselineskip}{\@IEEENORMtitlevspace}{\@IEEEMINtitlevspace}\@IEEEaftertitletext}]% + \fi + \else + \newpage\global\@topnum\z@ \@maketitle\@IEEEstatictitlevskip\@IEEEaftertitletext% + \fi + \thispagestyle{IEEEtitlepagestyle}\@thanks% + \fi + % pullup page for pubid if used. + \if@IEEEusingpubid + \enlargethispage{-\@IEEEpubidpullup}% + \fi + \endgroup + \setcounter{footnote}{0}\let\maketitle\relax\let\@maketitle\relax + \gdef\@thanks{}% + % v1.6b do not clear these as we will need the title again for peer review papers + % \gdef\@author{}\gdef\@title{}% + \let\thanks\relax} + + +% V1.8 parbox to format \@IEEEtitleabstractindextext +\long\def\@IEEEtitleabstractindextextbox#1{\parbox{1\textwidth}{#1}} +% V1.8 compsoc is partial width +\ifCLASSOPTIONcompsoc +% comparison with proofs suggests it's in the range of 92.1-92.3% +\long\def\@IEEEtitleabstractindextextbox#1{\parbox{0.922\textwidth}{\@IEEEcompsocnotconfonly{\rightskip\@flushglue\leftskip\z@skip}#1}} +\fi + +% formats the Title, authors names, affiliations and special paper notice +% THIS IS A CONTROLLED SPACING COMMAND! Do not allow blank lines or unintentional +% spaces to enter the definition - use % at the end of each line +\def\@maketitle{\newpage +\bgroup\par\vskip\IEEEtitletopspace\vskip\IEEEtitletopspaceextra\centering% +\ifCLASSOPTIONtechnote% technotes, V1.8a abstract and index terms are not treated differently for compsoc technotes + {\bfseries\large\@IEEEcompsoconly{\Large\sffamily}\@title\par}\vskip 1.3em{\lineskip .5em\@IEEEcompsoconly{\large\sffamily}\@author + \@IEEEspecialpapernotice\par}\relax +\else% not a technote + \vskip0.2em{\Huge\ifCLASSOPTIONtransmag\bfseries\LARGE\fi\@IEEEcompsoconly{\sffamily}\@IEEEcompsocconfonly{\normalfont\normalsize\vskip 2\@IEEEnormalsizeunitybaselineskip + \bfseries\Large}\@IEEEcompsocnotconfonly{\vskip 0.75\@IEEEnormalsizeunitybaselineskip}\@title\par}\relax + \@IEEEcompsocnotconfonly{\vskip 0.5\@IEEEnormalsizeunitybaselineskip}\vskip1.0em\par% + % V1.6 handle \author differently if in conference mode + \ifCLASSOPTIONconference% + {\@IEEEspecialpapernotice\mbox{}\vskip\@IEEEauthorblockconfadjspace% + \mbox{}\hfill\begin{@IEEEauthorhalign}\@author\end{@IEEEauthorhalign}\hfill\mbox{}\par}\relax + \else% peerreviewca, peerreview or journal + \ifCLASSOPTIONpeerreviewca + % peerreviewca handles author names just like conference mode + {\@IEEEcompsoconly{\sffamily}\@IEEEspecialpapernotice\mbox{}\vskip\@IEEEauthorblockconfadjspace% + \mbox{}\hfill\begin{@IEEEauthorhalign}\@author\end{@IEEEauthorhalign}\hfill\mbox{}\par + {\@IEEEcompsoconly{\vskip 1.5em\relax + \@IEEEtitleabstractindextextbox{\@IEEEtitleabstractindextext}\par\noindent\hfill + \IEEEcompsocdiamondline\hfill\hbox{}\par}}}\relax + \else% journal, peerreview or transmag + \ifCLASSOPTIONtransmag + % transmag also handles author names just like conference mode + % it also uses \@IEEEtitleabstractindextex, but with one line less + % space above, and one more below + {\@IEEEspecialpapernotice\mbox{}\vskip\@IEEEauthorblockconfadjspace% + \mbox{}\hfill\begin{@IEEEauthorhalign}\@author\end{@IEEEauthorhalign}\hfill\mbox{}\par + {\vspace{0.5\baselineskip}\relax\@IEEEtitleabstractindextextbox{\@IEEEtitleabstractindextext}\vspace{-1\baselineskip}\par}}\relax + \else% journal or peerreview + {\lineskip.5em\@IEEEcompsoconly{\sffamily}\sublargesize\@author\@IEEEspecialpapernotice\par + {\@IEEEcompsoconly{\vskip 1.5em\relax + \@IEEEtitleabstractindextextbox{\@IEEEtitleabstractindextext}\par\noindent\hfill + \IEEEcompsocdiamondline\hfill\hbox{}\par}}}\relax + \fi + \fi + \fi +\fi\par\addvspace{0.5\baselineskip}\egroup} + + +% V1.7 Computer Society "diamond line" which follows index terms for nonconference papers +% V1.8a full width diamond line for single column use +\def\@IEEEcompsocdiamondlinei{\vrule depth 0pt height 0.5pt width 4cm\nobreak\hspace{7.5pt}\nobreak +\raisebox{-3.5pt}{\fontfamily{pzd}\fontencoding{U}\fontseries{m}\fontshape{n}\fontsize{11}{12}\selectfont\char70}\nobreak +\hspace{7.5pt}\nobreak\vrule depth 0pt height 0.5pt width 4cm\relax} +% V1.8a narrower width diamond line for double column use +\def\@IEEEcompsocdiamondlineii{\vrule depth 0pt height 0.5pt width 2.5cm\nobreak\hspace{7.5pt}\nobreak +\raisebox{-3.5pt}{\fontfamily{pzd}\fontencoding{U}\fontseries{m}\fontshape{n}\fontsize{11}{12}\selectfont\char70}\nobreak +\hspace{7.5pt}\nobreak\vrule depth 0pt height 0.5pt width 2.5cm\relax} +% V1.8a bare core without rules to base a last resort on for very narrow linewidths +\def\@IEEEcompsocdiamondlineiii{\mbox{}\nobreak\hspace{7.5pt}\nobreak +\raisebox{-3.5pt}{\fontfamily{pzd}\fontencoding{U}\fontseries{m}\fontshape{n}\fontsize{11}{12}\selectfont\char70}\nobreak +\hspace{7.5pt}\nobreak\mbox{}\relax} + +% V1.8a allow \IEEEcompsocdiamondline to adjust for different linewidths. +% Use \@IEEEcompsocdiamondlinei if its width is less than 0.66\linewidth (0.487 nominal for single column) +% if not, fall back to \@IEEEcompsocdiamondlineii if its width is less than 0.75\linewidth (0.659 nominal for double column) +% if all else fails, try to make a custom diamondline based on the abnormally narrow linewidth +\def\IEEEcompsocdiamondline{\settowidth{\@IEEEtrantmpdimenA}{\@IEEEcompsocdiamondlinei}\relax +\ifdim\@IEEEtrantmpdimenA<0.66\linewidth\relax\@IEEEcompsocdiamondlinei\relax +\else +\settowidth{\@IEEEtrantmpdimenA}{\@IEEEcompsocdiamondlineii}\relax +\ifdim\@IEEEtrantmpdimenA<0.75\linewidth\relax\@IEEEcompsocdiamondlineii\relax +\else +\settowidth{\@IEEEtrantmpdimenA}{\@IEEEcompsocdiamondlineiii}\relax +\@IEEEtrantmpdimenB=\linewidth\relax +\addtolength{\@IEEEtrantmpdimenB}{-1\@IEEEtrantmpdimenA}\relax +\vrule depth 0pt height 0.5pt width 0.33\@IEEEtrantmpdimenB\@IEEEcompsocdiamondlineiii\vrule depth 0pt height 0.5pt width 0.33\@IEEEtrantmpdimenB\relax +\fi\fi} + + +% V1.7 standard LateX2e \thanks, but with \itshape under compsoc. Also make it a \long\def +% We also need to trigger the one-shot footnote rule +\def\@IEEEtriggeroneshotfootnoterule{\global\@IEEEenableoneshotfootnoteruletrue} + + +\long\def\thanks#1{\footnotemark + \protected@xdef\@thanks{\@thanks + \protect\footnotetext[\the\c@footnote]{\@IEEEcompsoconly{\itshape + \protect\@IEEEtriggeroneshotfootnoterule\relax}\ignorespaces#1}}} +\let\@thanks\@empty + + +% V1.7 allow \author to contain \par's. This is needed to allow \thanks to contain \par. +\long\def\author#1{\gdef\@author{#1}} + + +% in addition to setting up IEEEitemize, we need to remove a baselineskip space above and +% below it because \list's \pars introduce blank lines because of the footnote struts. +\def\@IEEEsetupcompsocitemizelist{\def\labelitemi{$\bullet$}% +\setlength{\IEEElabelindent}{0pt}\setlength{\labelsep}{1.2em}\setlength{\parskip}{0pt}% +\setlength{\partopsep}{0pt}\setlength{\topsep}{0.5\baselineskip}\vspace{-1\baselineskip}\relax} + + +% flag for fake non-compsoc \IEEEcompsocthanksitem - prevents line break on very first item +\newif\if@IEEEbreakcompsocthanksitem \@IEEEbreakcompsocthanksitemfalse + +\ifCLASSOPTIONcompsoc +% V1.7 compsoc bullet item \thanks +% also, we need to redefine this to destroy the argument in \IEEEquantizevspace +\long\def\IEEEcompsocitemizethanks#1{\relax\@IEEEbreakcompsocthanksitemfalse\footnotemark + \protected@xdef\@thanks{\@thanks + \protect\footnotetext[\the\c@footnote]{\itshape\protect\@IEEEtriggeroneshotfootnoterule + {\let\IEEEiedlistdecl\relax\protect\begin{IEEEitemize}[\protect\@IEEEsetupcompsocitemizelist]\ignorespaces#1\relax + \protect\end{IEEEitemize}}\protect\vspace{-1\baselineskip}}}} +\DeclareRobustCommand*{\IEEEcompsocthanksitem}{\item} +\else +% non-compsoc, allow for dual compilation via rerouting to normal \thanks +\long\def\IEEEcompsocitemizethanks#1{\thanks{#1}} +% redirect to "pseudo-par" \hfil\break\indent after swallowing [] from \IEEEcompsocthanksitem[] +\DeclareRobustCommand{\IEEEcompsocthanksitem}{\@ifnextchar [{\@IEEEthanksswallowoptionalarg}% +{\@IEEEthanksswallowoptionalarg[\relax]}} +% be sure and break only after first item, be sure and ignore spaces after optional argument +\def\@IEEEthanksswallowoptionalarg[#1]{\relax\if@IEEEbreakcompsocthanksitem\hfil\break +\indent\fi\@IEEEbreakcompsocthanksitemtrue\ignorespaces} +\fi + + +% V1.6b define the \IEEEpeerreviewmaketitle as needed +\ifCLASSOPTIONpeerreview +\def\IEEEpeerreviewmaketitle{\@IEEEcleardoublepage{empty}% +\ifCLASSOPTIONtwocolumn +\twocolumn[{\IEEEquantizevspace{\@IEEEpeerreviewmaketitle}[\IEEEquantizedisabletitlecmds]{0pt}[-\topskip]{\baselineskip}{\@IEEENORMtitlevspace}{\@IEEEMINtitlevspace}}] +\else +\newpage\@IEEEpeerreviewmaketitle\@IEEEstatictitlevskip +\fi +\thispagestyle{IEEEtitlepagestyle}} +\else +% \IEEEpeerreviewmaketitle does nothing if peer review option has not been selected +\def\IEEEpeerreviewmaketitle{\relax} +\fi + +% peerreview formats the repeated title like the title in journal papers. +\def\@IEEEpeerreviewmaketitle{\bgroup\par\addvspace{0.5\baselineskip}\centering\@IEEEcompsoconly{\sffamily}% +\normalfont\normalsize\vskip0.2em{\Huge\@title\par}\vskip1.0em\par +\par\addvspace{0.5\baselineskip}\egroup} + + + +% V1.6 +% this is a static rubber spacer between the title/authors and the main text +% used for single column text, or when the title appears in the first column +% of two column text (technotes). +\def\@IEEEstatictitlevskip{{\normalfont\normalsize +% adjust spacing to next text +% v1.6b handle peer review papers +\ifCLASSOPTIONpeerreview +% for peer review papers, the same value is used for both title pages +% regardless of the other paper modes + \vskip 1\baselineskip plus 0.375\baselineskip minus 0.1875\baselineskip +\else + \ifCLASSOPTIONconference% conference + \vskip 1\baselineskip plus 0.375\baselineskip minus 0.1875\baselineskip% + \else% + \ifCLASSOPTIONtechnote% technote + \vskip 1\baselineskip plus 0.375\baselineskip minus 0.1875\baselineskip% + \else% journal uses more space + \vskip 2.5\baselineskip plus 0.75\baselineskip minus 0.375\baselineskip% + \fi + \fi +\fi}} + + +% set the nominal and minimum values for the quantized title spacer +% the quantization algorithm will not allow the spacer size to +% become less than \@IEEEMINtitlevspace - instead it will be lengthened +% default to journal values +\def\@IEEENORMtitlevspace{2.5\baselineskip} +\def\@IEEEMINtitlevspace{2\baselineskip} +% conferences and technotes need tighter spacing +\ifCLASSOPTIONconference% conference + \def\@IEEENORMtitlevspace{1\baselineskip} + \def\@IEEEMINtitlevspace{0.75\baselineskip} +\fi +\ifCLASSOPTIONtechnote% technote + \def\@IEEENORMtitlevspace{1\baselineskip} + \def\@IEEEMINtitlevspace{0.75\baselineskip} +\fi + + +% V1.8a +\def\IEEEquantizevspace{\begingroup\@ifstar{\@IEEEquantizevspacestarformtrue\@IEEEquantizevspace}{\@IEEEquantizevspacestarformfalse\@IEEEquantizevspace}} +% \IEEEquantizevspace[output dimen register]{object}[object decl] +% {top baselineskip} +% [offset][prevdepth][lineskip limit][lineskip] +% {unit height}{nominal vspace}{minimum vspace} +% +% Calculates and creates the vspace needed to make the combined height with +% the given object an integer multiple of the given unit height. This command +% is more general than the older \@IEEEdynamictitlevspace it replaces. +% +% The star form has no effect at present, but is reserved for future use. +% +% If the optional argument [output dimen register] is given, the calculated +% vspace height is stored in the given output dimen (or skip) register +% and no other action is taken, otherwise the object followed by a vspace* +% of the appropriate height is evaluated/output. +% +% The optional object decl (declarations) is code that is evaluated just +% before the object's height is evaluated. Its intented purpose is to allow +% for the alteration or disabling of code within the object during internal +% height evaluation (e.g., \long\def\thanks#1{\relax} ). +% This special code is not invoked if/when the object is rendered at the end. +% +% The nominal vspace is the target value of the added vspace and the minimum +% vspace is the lower allowed limit. The vspacer will be the value that achieves +% integral overall height, in terms of the given unit height, that is closest +% to the nominal vspace and that is not less than the specified minimum vspace. +% +% The line spacing algorithm of TeX is somewhat involved and requires special +% care with regard to the first line of a vertical list (which is indicated +% when \prevdepth is -1000pt or less). top baselineskip specifies the +% baselineskip or topskip used prior to the object. If the height of the +% first line of the object is greater than the given top baselineskip, then +% the top baselineskip is subtracted from the height of the first line and +% that difference is considered along with the rest of the object height +% (because the object will be shifted down by an amount = +% top line height - top baselineskip). Otherwise, the height of the first line +% of the object is ignored as far as the calculations are concerned. +% This algorithm is adequate for objects that appear at the top of a page +% (e.g., titles) where \topskip spacing is used. +% +% However, as explained on page 78 of the TeXbook, interline spacing is more +% complex when \baselineskip is being used (indicated by \prevdepth > +% -1000pt). The four optional parameters offset, prevdepth, lineskip limit and +% lineskip are assumed to be equal to be 0pt, \prevdepth, \lineskiplimit and +% \lineskip, respectively, if they are omitted. +% +% The prevdepth is the depth of the line before the object, the lineskip limit +% specifies how close the top of the object can come to the bottom of the +% previous line before \baselineskip is ignored and \lineskip is inserted +% between the object and the line above it. Lineskip does not come into +% play unless the first line of the object is high enough to "get too close" +% (as specified by lineskiplimit) to the line before it. The the prevdepth, +% lineskip limit, and lineskip optional parameters are not needed for the +% first object/line on a page (i.e., prevdepth <= -1000pt) where the simplier +% \topskip spacing rules are in effect. +% +% Offset is a manual adjustment that is added to the height calculations of +% object irrespective of the value of \prevdepth. It is useful when the top +% baselineskip will result in a noninteger unit height object placement even +% if the object itself has integral height. e.g., a footnotesize baselineskip +% is used before the object, thus an offset of, say -3pt, can be given as a +% correction. + +% Common combinations of these parameters include: +% +% top baselineskip: (and default values for offset, prevdepth, etc.) +% \topskip % for objects that appear at the top of a page +% \maxdimen % always ignore the height of the top line +% 0pt % always consider any positive height of the top line +% +% for objects to appear inline in normal text: +% top baselineskip = \baselineskip +% +% set prevdepth = -1000pt and top baselineskip = 0pt to consider the +% overall height of the object without any other external skip +% consideration + +\newif\if@IEEEquantizevspacestarform % flag to indicate star form +\newif\if@IEEEquantizevspaceuseoutdimenreg % flag to indicate output dimen register is to be used +% Use our own private registers because the object could contain a +% structure that uses the existing tmp scratch pad registers +\newdimen\@IEEEquantizeheightA +\newdimen\@IEEEquantizeheightB +\newdimen\@IEEEquantizeheightC +\newdimen\@IEEEquantizeprevdepth % need to save this early as can change +\newcount\@IEEEquantizemultiple +\newbox\@IEEEquantizeboxA + + +\def\@IEEEquantizevspace{\@ifnextchar [{\@IEEEquantizevspaceuseoutdimenregtrue\@@IEEEquantizevspace}{\@IEEEquantizevspaceuseoutdimenregfalse\@@IEEEquantizevspace[]}} + + +\long\def\@@IEEEquantizevspace[#1]#2{\relax +% acquire and store +% #1 optional output dimen register +% #2 object +\edef\@IEEEquantizeoutdimenreg{#1}\relax +% allow for object specifications that contain parameters +\@IEEEtrantmptoksA={#2}\relax +\long\edef\@IEEEquantizeobject{\the\@IEEEtrantmptoksA}\relax +\@ifnextchar [{\@@@IEEEquantizevspace}{\@@@IEEEquantizevspace[\relax]}} + +\long\def\@@@IEEEquantizevspace[#1]#2{\relax +% acquire and store +% [#1] optional object decl, is \relax if not given by user +% #2 top baselineskip +% allow for object decl specifications that have parameters +\@IEEEtrantmptoksA={#1}\relax +\long\edef\@IEEEquantizeobjectdecl{\the\@IEEEtrantmptoksA}\relax +\edef\@IEEEquantizetopbaselineskip{#2}\ivIEEEquantizevspace} + +% acquire optional argument set and store +% [offset][prevdepth][lineskip limit][lineskip] +\def\ivIEEEquantizevspace{\@ifnextchar [{\@vIEEEquantizevspace}{\@vIEEEquantizevspace[0pt]}} +\def\@vIEEEquantizevspace[#1]{\edef\@IEEEquantizeoffset{#1}\@ifnextchar [{\@viIEEEquantizevspace}{\@viIEEEquantizevspace[\prevdepth]}} +\def\@viIEEEquantizevspace[#1]{\@IEEEquantizeprevdepth=#1\relax\@ifnextchar [{\@viiIEEEquantizevspace}{\@viiIEEEquantizevspace[\lineskiplimit]}} +\def\@viiIEEEquantizevspace[#1]{\edef\@IEEEquantizelineskiplimit{#1}\@ifnextchar [{\@viiiIEEEquantizevspace}{\@viiiIEEEquantizevspace[\lineskip]}} +\def\@viiiIEEEquantizevspace[#1]{\edef\@IEEEquantizelineskip{#1}\@ixIEEEquantizevspace} + +% main routine +\def\@ixIEEEquantizevspace#1#2#3{\relax +\edef\@IEEEquantizeunitheight{#1}\relax +\edef\@IEEEquantizenomvspace{#2}\relax +\edef\@IEEEquantizeminvspace{#3}\relax +% \@IEEEquantizeoutdimenreg +% \@IEEEquantizeobject +% \@IEEEquantizeobjectdecl +% \@IEEEquantizetopbaselineskip +% \@IEEEquantizeoffset +% \@IEEEquantizeprevdepth +% \@IEEEquantizelineskiplimit +% \@IEEEquantizelineskip +% \@IEEEquantizeunitheight +% \@IEEEquantizenomvspace +% \@IEEEquantizeminvspace +% get overall height of object +\setbox\@IEEEquantizeboxA\vbox{\begingroup\@IEEEquantizeobjectdecl\@IEEEquantizeobject\relax\endgroup}\relax +\@IEEEquantizeheightA\ht\@IEEEquantizeboxA\relax +% get height of first line of object +\setbox\@IEEEquantizeboxA\vtop{\begingroup\@IEEEquantizeobjectdecl\@IEEEquantizeobject\relax\endgroup}\relax +\@IEEEquantizeheightB\ht\@IEEEquantizeboxA\relax +\ifdim\@IEEEquantizeprevdepth>-1000pt\relax % prevdepth > -1000pf means full baselineskip\lineskip rules in effect +% lineskip spacing rule takes effect if height of top line > baselineskip - prevdepth - lineskiplimit, +% otherwise the baselineskip rule is in effect and the height of the first line does not matter at all. +\@IEEEquantizeheightC=\@IEEEquantizetopbaselineskip\relax +\advance\@IEEEquantizeheightC-\@IEEEquantizeprevdepth\relax +\advance\@IEEEquantizeheightC-\@IEEEquantizelineskiplimit\relax % this works even though \@IEEEquantizelineskiplimit is a macro because TeX allows --10pt notation +\ifdim\@IEEEquantizeheightB>\@IEEEquantizeheightC\relax +% lineskip spacing rule is in effect i.e., the object is going to be shifted down relative to the +% baselineskip set position by its top line height (already a part of the total height) + prevdepth + lineskip - baselineskip +\advance\@IEEEquantizeheightA\@IEEEquantizeprevdepth\relax +\advance\@IEEEquantizeheightA\@IEEEquantizelineskip\relax +\advance\@IEEEquantizeheightA-\@IEEEquantizetopbaselineskip\relax +\else +% height of first line <= \@IEEEquantizetopbaselineskip - \@IEEEquantizeprevdepth - \@IEEEquantizelineskiplimit +% standard baselineskip rules are in effect, so don't consider height of first line +\advance\@IEEEquantizeheightA-\@IEEEquantizeheightB\relax +\fi +% +\else % prevdepth <= -1000pt, simplier \topskip type rules in effect +\ifdim\@IEEEquantizeheightB>\@IEEEquantizetopbaselineskip +% height of top line (already included in the total height) in excess of +% baselineskip is the amount it will be downshifted +\advance\@IEEEquantizeheightA-\@IEEEquantizetopbaselineskip\relax +\else +% height of first line is irrelevant, remove it +\advance\@IEEEquantizeheightA-\@IEEEquantizeheightB\relax +\fi +\fi % prevdepth <= -1000pt +% +% adjust height for any manual offset +\advance\@IEEEquantizeheightA\@IEEEquantizeoffset\relax +% add in nominal spacer +\advance\@IEEEquantizeheightA\@IEEEquantizenomvspace\relax +% check for nonzero unitheight +\@IEEEquantizeheightB=\@IEEEquantizeunitheight\relax +\ifnum\@IEEEquantizeheightB=0\relax +\@IEEEclspkgerror{IEEEquantizevspace unit height cannot be zero. Assuming 10pt.}% +{Division by zero is not allowed.} +\@IEEEquantizeheightB=10pt\relax +\fi +% get integer number of lines +\@IEEEquantizemultiple=\@IEEEquantizeheightA\relax +\divide\@IEEEquantizemultiple\@IEEEquantizeheightB\relax +% set A to contain the excess height over the \@IEEEquantizemultiple of lines +% A = height - multiple*unitheight +\@IEEEquantizeheightC\@IEEEquantizeheightB\relax +\multiply\@IEEEquantizeheightC\@IEEEquantizemultiple\relax +\advance\@IEEEquantizeheightA-\@IEEEquantizeheightC\relax +% set B to contain the height short of \@IEEEquantizemultiple+1 of lines +% B = unitheight - A +\advance\@IEEEquantizeheightB-\@IEEEquantizeheightA\relax +% choose A or B based on which is closer +\@IEEEquantizeheightC\@IEEEquantizenomvspace\relax +\ifdim\@IEEEquantizeheightA<\@IEEEquantizeheightB\relax +% C = nomvspace - A, go with lower +\advance\@IEEEquantizeheightC-\@IEEEquantizeheightA\relax +\else +% C = nomvspace + B, go with upper +\advance\@IEEEquantizeheightC\@IEEEquantizeheightB\relax +\fi +% if violate lower bound, use next integer bound +\ifdim\@IEEEquantizeheightC<\@IEEEquantizeminvspace\relax +% A + B = unitheight +\advance\@IEEEquantizeheightC\@IEEEquantizeheightA\relax +\advance\@IEEEquantizeheightC\@IEEEquantizeheightB\relax +\fi +% export object and spacer outside of group +\global\let\@IEEEquantizeobjectout\@IEEEquantizeobject\relax +\global\@IEEEquantizeheightC\@IEEEquantizeheightC\relax +\endgroup +\if@IEEEquantizevspaceuseoutdimenreg +\@IEEEquantizeoutdimenreg=\@IEEEquantizeheightC\relax +\else +\@IEEEquantizeobjectout\relax +\vskip\@IEEEquantizeheightC\relax +\fi} + + +% user command to disable all global assignments, possible use within object decl +\def\IEEEquantizedisableglobal{\let\global\relax +\let\gdef\def +\let\xdef\edef} +% user command to allow for the disabling of \thanks and other commands, possible use within object decl +\def\IEEEquantizedisabletitlecmds{\long\def\thanks##1{\relax}\relax +\long\def\IEEEcompsocitemizethanks##1{\relax}\def\newpage{\relax}} + + + + + +% V1.6 +% we allow the user access to the last part of the title area +% useful in emergencies such as when a different spacing is needed +% This text is NOT compensated for in the dynamic sizer. +\let\@IEEEaftertitletext=\relax +\long\def\IEEEaftertitletext#1{\def\@IEEEaftertitletext{#1}} + + +% V1.7 provide a way for users to enter abstract and keywords +% into the onecolumn title are. This text is compensated for +% in the dynamic sizer. +\let\@IEEEtitleabstractindextext=\relax +\long\def\IEEEtitleabstractindextext#1{\def\@IEEEtitleabstractindextext{#1}} + +% V1.7 provide a way for users to get the \@IEEEtitleabstractindextext if +% not in compsoc or transmag journal mode - this way abstract and keywords +% can still be placed in their conventional position if not in those modes. +\def\IEEEdisplaynontitleabstractindextext{% +% display for all conference formats +\ifCLASSOPTIONconference\@IEEEtitleabstractindextext\relax +\else% non-conferences + % V1.8a display for all technotes + \ifCLASSOPTIONtechnote\@IEEEtitleabstractindextext\relax + % V1.8a add diamond line after abstract and index terms for compsoc technotes + \@IEEEcompsoconly{\noindent\hfill\IEEEcompsocdiamondline\hfill\hbox{}\par}\relax + \else % non-conferences and non-technotes + \ifCLASSOPTIONcompsoc% display if not compsoc and not transmag + \else + \ifCLASSOPTIONtransmag + \else% not compsoc journal nor transmag journal + \@IEEEtitleabstractindextext\relax + \fi + \fi + \fi +\fi} + + +% command to allow alteration of baselinestretch, but only if the current +% baselineskip is unity. Used to tweak the compsoc abstract and keywords line spacing. +\def\@IEEEtweakunitybaselinestretch#1{{\def\baselinestretch{1}\selectfont +\global\@tempskipa\baselineskip}\ifnum\@tempskipa=\baselineskip% +\def\baselinestretch{#1}\selectfont\fi\relax} + + +% abstract and keywords are in \small, except +% for 9pt docs in which they are in \footnotesize +% Because 9pt docs use an 8pt footnotesize, \small +% becomes a rather awkward 8.5pt +\def\@IEEEabskeysecsize{\small} +\ifx\CLASSOPTIONpt\@IEEEptsizenine + \def\@IEEEabskeysecsize{\footnotesize} +\fi + +% compsoc journals use \footnotesize, compsoc conferences use normalsize +\@IEEEcompsoconly{\def\@IEEEabskeysecsize{\footnotesize}} +\@IEEEcompsocconfonly{\def\@IEEEabskeysecsize{\small}} + + +% V1.6 have abstract and keywords strip leading spaces, pars and newlines +% so that spacing is more tightly controlled. +\def\abstract{\normalfont + \if@twocolumn + \@IEEEabskeysecsize\bfseries\textit{\abstractname}---\relax + \else + \bgroup\par\addvspace{0.5\baselineskip}\centering\vspace{-1.78ex}\@IEEEabskeysecsize\textbf{\abstractname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize + \fi\@IEEEgobbleleadPARNLSP} +% V1.6 The IEEE wants only 1 pica from end of abstract to introduction heading when in +% conference mode (the heading already has this much above it) +\def\endabstract{\relax\ifCLASSOPTIONconference\vspace{0ex}\else\vspace{1.34ex}\fi\par\if@twocolumn\else\endquotation\fi + \normalfont\normalsize} + +\def\IEEEkeywords{\normalfont + \if@twocolumn + \@IEEEabskeysecsize\bfseries\textit{\IEEEkeywordsname}---\relax + \else + \bgroup\par\addvspace{0.5\baselineskip}\centering\@IEEEabskeysecsize\textbf{\IEEEkeywordsname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize + \fi\@IEEEgobbleleadPARNLSP} +\def\endIEEEkeywords{\relax\ifCLASSOPTIONtechnote\vspace{1.34ex}\else\vspace{0.67ex}\fi + \par\if@twocolumn\else\endquotation\fi% + \normalfont\normalsize} + +% V1.7 compsoc keywords index terms +\ifCLASSOPTIONcompsoc + \ifCLASSOPTIONconference% compsoc conference +\def\abstract{\normalfont\@IEEEtweakunitybaselinestretch{1.15}\bfseries + \if@twocolumn + \@IEEEabskeysecsize\noindent\textit{\abstractname}---\relax + \else + \bgroup\par\addvspace{0.5\baselineskip}\centering\vspace{-1.78ex}\@IEEEabskeysecsize\textbf{\abstractname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize% + \fi\@IEEEgobbleleadPARNLSP} +\def\IEEEkeywords{\normalfont\@IEEEtweakunitybaselinestretch{1.15}\bfseries + \if@twocolumn + \@IEEEabskeysecsize\vskip 0.5\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip\noindent + \textit{\IEEEkeywordsname}---\relax + \else + \bgroup\par\addvspace{0.5\baselineskip}\centering\@IEEEabskeysecsize\textbf{\IEEEkeywordsname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize% + \fi\@IEEEgobbleleadPARNLSP} + \else% compsoc not conference +\def\abstract{\normalfont\@IEEEtweakunitybaselinestretch{1.15}\sffamily + \if@twocolumn + \@IEEEabskeysecsize\noindent\textbf{\abstractname}---\relax + \else + \bgroup\par\addvspace{0.5\baselineskip}\centering\vspace{-1.78ex}\@IEEEabskeysecsize\textbf{\abstractname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize% + \fi\@IEEEgobbleleadPARNLSP} +\def\IEEEkeywords{\normalfont\@IEEEtweakunitybaselinestretch{1.15}\sffamily + \if@twocolumn + \@IEEEabskeysecsize\vskip 0.5\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip\noindent + \textbf{\IEEEkeywordsname}---\relax + \else + \bgroup\par\addvspace{0.5\baselineskip}\centering\@IEEEabskeysecsize\textbf{\IEEEkeywordsname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize% + \fi\@IEEEgobbleleadPARNLSP} + \fi +\fi + +% V1.8 transmag keywords index terms +% no abstract name, use indentation +\ifCLASSOPTIONtransmag +\def\abstract{\normalfont\parindent 1em\relax + \if@twocolumn + \@IEEEabskeysecsize\bfseries\indent + \else + \bgroup\par\addvspace{0.5\baselineskip}\centering\vspace{-1.78ex}\@IEEEabskeysecsize + \textbf{\abstractname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize + \fi\@IEEEgobbleleadPARNLSP} + +\def\IEEEkeywords{\normalfont\parindent 1em\relax + \if@twocolumn + \@IEEEabskeysecsize\vspace{1\baselineskip}\bfseries\indent\textit{\IEEEkeywordsname}---\relax + \else + \bgroup\par\vspace{1\baselineskip}\centering\@IEEEabskeysecsize + \textbf{\IEEEkeywordsname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize + \fi\@IEEEgobbleleadPARNLSP} +\fi + + + +% gobbles all leading \, \\ and \par, upon finding first token that +% is not a \ , \\ or a \par, it ceases and returns that token +% +% used to strip leading \, \\ and \par from the input +% so that such things in the beginning of an environment will not +% affect the formatting of the text +\long\def\@IEEEgobbleleadPARNLSP#1{\let\@IEEEswallowthistoken=0% +\let\@IEEEgobbleleadPARNLSPtoken#1% +\let\@IEEEgobbleleadPARtoken=\par% +\let\@IEEEgobbleleadNLtoken=\\% +\let\@IEEEgobbleleadSPtoken=\ % +\def\@IEEEgobbleleadSPMACRO{\ }% +\ifx\@IEEEgobbleleadPARNLSPtoken\@IEEEgobbleleadPARtoken% +\let\@IEEEswallowthistoken=1% +\fi% +\ifx\@IEEEgobbleleadPARNLSPtoken\@IEEEgobbleleadNLtoken% +\let\@IEEEswallowthistoken=1% +\fi% +\ifx\@IEEEgobbleleadPARNLSPtoken\@IEEEgobbleleadSPtoken% +\let\@IEEEswallowthistoken=1% +\fi% +% a control space will come in as a macro +% when it is the last one on a line +\ifx\@IEEEgobbleleadPARNLSPtoken\@IEEEgobbleleadSPMACRO% +\let\@IEEEswallowthistoken=1% +\fi% +% if we have to swallow this token, do so and taste the next one +% else spit it out and stop gobbling +\ifx\@IEEEswallowthistoken 1\let\@IEEEnextgobbleleadPARNLSP=\@IEEEgobbleleadPARNLSP\else% +\let\@IEEEnextgobbleleadPARNLSP=#1\fi% +\@IEEEnextgobbleleadPARNLSP}% + + + + +% TITLING OF SECTIONS +\def\@IEEEsectpunct{:\ \,} % Punctuation after run-in section heading (headings which are + % part of the paragraphs), need little bit more than a single space + % spacing from section number to title +% compsoc conferences use regular period/space punctuation +\ifCLASSOPTIONcompsoc +\ifCLASSOPTIONconference +\def\@IEEEsectpunct{.\ } +\fi\fi + + +\def\@seccntformat#1{\csname the#1dis\endcsname\hskip 0.5em\relax} + +\ifCLASSOPTIONcompsoc +% compsoc journals need extra spacing +\ifCLASSOPTIONconference\else +\def\@seccntformat#1{\csname the#1dis\endcsname\hskip 1em\relax} +\fi\fi + +%v1.7 put {} after #6 to allow for some types of user font control +%and use \@@par rather than \par +\def\@sect#1#2#3#4#5#6[#7]#8{% + \ifnum #2>\c@secnumdepth + \let\@svsec\@empty + \else + \refstepcounter{#1}% + % load section label and spacer into \@svsec + \protected@edef\@svsec{\@seccntformat{#1}\relax}% + \fi% + \@tempskipa #5\relax + \ifdim \@tempskipa>\z@% tempskipa determines whether is treated as a high + \begingroup #6{\relax% or low level heading + \noindent % subsections are NOT indented + % print top level headings. \@svsec is label, #8 is heading title + % The IEEE does not block indent the section title text, it flows like normal + {\hskip #3\relax\@svsec}{\interlinepenalty \@M #8\@@par}}% + \endgroup + \addcontentsline{toc}{#1}{\ifnum #2>\c@secnumdepth\relax\else + \protect\numberline{\csname the#1\endcsname}\fi#7}% + \else % printout low level headings + % svsechd seems to swallow the trailing space, protect it with \mbox{} + % got rid of sectionmark stuff + \def\@svsechd{#6{\hskip #3\relax\@svsec #8\@IEEEsectpunct\mbox{}}% + \addcontentsline{toc}{#1}{\ifnum #2>\c@secnumdepth\relax\else + \protect\numberline{\csname the#1\endcsname}\fi#7}}% + \fi%skip down + \@xsect{#5}} + + +% section* handler +%v1.7 put {} after #4 to allow for some types of user font control +%and use \@@par rather than \par +\def\@ssect#1#2#3#4#5{\@tempskipa #3\relax + \ifdim \@tempskipa>\z@ + %\begingroup #4\@hangfrom{\hskip #1}{\interlinepenalty \@M #5\par}\endgroup + % The IEEE does not block indent the section title text, it flows like normal + \begingroup \noindent #4{\relax{\hskip #1}{\interlinepenalty \@M #5\@@par}}\endgroup + % svsechd swallows the trailing space, protect it with \mbox{} + \else \def\@svsechd{#4{\hskip #1\relax #5\@IEEEsectpunct\mbox{}}}\fi + \@xsect{#3}} + + +%% SECTION heading spacing and font +%% +% arguments are: #1 - sectiontype name +% (for \@sect) #2 - section level +% #3 - section heading indent +% #4 - top separation (absolute value used, neg indicates not to indent main text) +% If negative, make stretch parts negative too! +% #5 - (absolute value used) positive: bottom separation after heading, +% negative: amount to indent main text after heading +% Both #4 and #5 negative means to indent main text and use negative top separation +% #6 - font control +% You've got to have \normalfont\normalsize in the font specs below to prevent +% trouble when you do something like: +% \section{Note}{\ttfamily TT-TEXT} is known to ... +% The IEEE sometimes REALLY stretches the area before a section +% heading by up to about 0.5in. However, it may not be a good +% idea to let LaTeX have quite this much rubber. +\ifCLASSOPTIONconference% +% The IEEE wants section heading spacing to decrease for conference mode +\def\section{\@startsection{section}{1}{\z@}{1.5ex plus 1.5ex minus 0.5ex}% +{0.7ex plus 1ex minus 0ex}{\normalfont\normalsize\centering\scshape}}% +\def\subsection{\@startsection{subsection}{2}{\z@}{1.5ex plus 1.5ex minus 0.5ex}% +{0.7ex plus .5ex minus 0ex}{\normalfont\normalsize\itshape}}% +\else % for journals +\def\section{\@startsection{section}{1}{\z@}{3.0ex plus 1.5ex minus 1.5ex}% V1.6 3.0ex from 3.5ex +{0.7ex plus 1ex minus 0ex}{\normalfont\normalsize\centering\scshape}}% +\def\subsection{\@startsection{subsection}{2}{\z@}{3.5ex plus 1.5ex minus 1.5ex}% +{0.7ex plus .5ex minus 0ex}{\normalfont\normalsize\itshape}}% +\fi + +% for both journals and conferences +% decided to put in a little rubber above the section, might help somebody +\def\subsubsection{\@startsection{subsubsection}{3}{\parindent}{0ex plus 0.1ex minus 0.1ex}% +{0ex}{\normalfont\normalsize\itshape}}% +\def\paragraph{\@startsection{paragraph}{4}{2\parindent}{0ex plus 0.1ex minus 0.1ex}% +{0ex}{\normalfont\normalsize\itshape}}% + + +% compsoc +\ifCLASSOPTIONcompsoc +\ifCLASSOPTIONconference +% compsoc conference +\def\section{\@startsection{section}{1}{\z@}{1\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip}% +{1\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip}{\normalfont\large\bfseries}}% +\def\subsection{\@startsection{subsection}{2}{\z@}{1\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip}% +{1\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip}{\normalfont\sublargesize\bfseries}}% +\def\subsubsection{\@startsection{subsubsection}{3}{\z@}{1\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip}% +{0ex}{\normalfont\normalsize\bfseries}}% +\def\paragraph{\@startsection{paragraph}{4}{2\parindent}{0ex plus 0.1ex minus 0.1ex}% +{0ex}{\normalfont\normalsize}}% +\else% compsoc journals +% use negative top separation as compsoc journals do not indent paragraphs after section titles +\def\section{\@startsection{section}{1}{\z@}{-3.5ex plus -2ex minus -1.5ex}% +{0.7ex plus 1ex minus 0ex}{\normalfont\sublargesize\sffamily\bfseries\scshape}}% +% Note that subsection and smaller may not be correct for the Computer Society, +% I have to look up an example. +\def\subsection{\@startsection{subsection}{2}{\z@}{-3.5ex plus -1.5ex minus -1.5ex}% +{0.7ex plus .5ex minus 0ex}{\normalfont\normalsize\sffamily\bfseries}}% +\def\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex plus -1ex minus -1ex}% +{0.5ex plus 0.5ex minus 0ex}{\normalfont\normalsize\sffamily\itshape}}% +\def\paragraph{\@startsection{paragraph}{4}{2\parindent}{-0ex plus -0.1ex minus -0.1ex}% +{0ex}{\normalfont\normalsize}}% +\fi\fi + +% transmag +\ifCLASSOPTIONtransmag +\def\subsection{\@startsection{subsection}{2}{0.75\parindent}{3.5ex plus 1.5ex minus 1.5ex}% +{0.7ex plus .5ex minus 0ex}{\normalfont\normalsize\itshape}}% +\def\subsubsection{\@startsection{subsubsection}{3}{1.25\parindent}{0.1ex plus 0.1ex minus 0.1ex}% +{0.1ex}{\normalfont\normalsize\itshape}}% +\fi + + +% V1.8a provide for a raised line Introduction section for use with Computer +% Society papers. We have to remove any spacing glue after the section +% heading and then remove the blank line for the new paragraph after it. +% LaTeX's section handler alters \everypar and we need to propogate those +% changes outside of the \parbox lest there be spacing problems at the top +% of the next section. +\def\IEEEraisesectionheading#1{\noindent\raisebox{1.5\baselineskip}[0pt][0pt]{\parbox[b]{\columnwidth}{#1\unskip\global\everypar=\everypar}}\vspace{-1\baselineskip}\vspace{-\parskip}\par} + + + +%% ENVIRONMENTS +% "box" symbols at end of proofs +\def\IEEEQEDclosed{\mbox{\rule[0pt]{1.3ex}{1.3ex}}} % for a filled box +% V1.6 some journals use an open box instead that will just fit around a closed one +\def\IEEEQEDopen{{\setlength{\fboxsep}{0pt}\setlength{\fboxrule}{0.2pt}\fbox{\rule[0pt]{0pt}{1.3ex}\rule[0pt]{1.3ex}{0pt}}}} +\ifCLASSOPTIONcompsoc +\def\IEEEQED{\IEEEQEDopen} % default to open for compsoc +\else +\def\IEEEQED{\IEEEQEDclosed} % otherwise default to closed +\fi + +%V1.8 flag to indicate if QED symbol is to be shown +\newif\if@IEEEQEDshow \@IEEEQEDshowtrue +\def\IEEEproofindentspace{2\parindent}% V1.8 allow user to change indentation amount if desired +% v1.7 name change to avoid namespace collision with amsthm. Also add support +% for an optional argument. +\def\IEEEproof{\@ifnextchar[{\@IEEEproof}{\@IEEEproof[\IEEEproofname]}} +\def\@IEEEproof[#1]{\@IEEEQEDshowtrue\par\noindent\hspace{\IEEEproofindentspace}{\itshape #1: }} +\def\endIEEEproof{\if@IEEEQEDshow\hspace*{\fill}\nobreakspace\IEEEQED\fi\par} +% qedhere for equation environments, similar to AMS \qedhere +\def\IEEEQEDhereeqn{\global\@IEEEQEDshowfalse\eqno\let\eqno\relax\let\leqno\relax + \let\veqno\relax\hbox{\IEEEQED}} +% IEEE style qedhere for IEEEeqnarray and other environments +\def\IEEEQEDhere{\global\@IEEEQEDshowfalse\IEEEQED} +% command to disable QED at end of IEEEproof +\def\IEEEQEDoff{\global\@IEEEQEDshowfalse} + + +%\itemindent is set to \z@ by list, so define new temporary variable +\newdimen\@IEEEtmpitemindent + +\ifCLASSOPTIONcompsoc +% V1.8a compsoc uses bold theorem titles, a period instead of a colon, vertical spacing, and hanging indentation +% V1.8 allow long theorem names to break across lines. +% Thanks to Miquel Payaro for reporting this. +\def\@begintheorem#1#2{\@IEEEtmpitemindent\itemindent\relax + \topsep 0.2\@IEEEnormalsizeunitybaselineskip plus 0.26\@IEEEnormalsizeunitybaselineskip minus 0.05\@IEEEnormalsizeunitybaselineskip + \rmfamily\trivlist\hangindent\parindent% + \item[]\textit{\bfseries\noindent #1\ #2.} \itemindent\@IEEEtmpitemindent\relax} +\def\@opargbegintheorem#1#2#3{\@IEEEtmpitemindent\itemindent\relax +\topsep 0.2\@IEEEnormalsizeunitybaselineskip plus 0.26\@IEEEnormalsizeunitybaselineskip minus 0.05\@IEEEnormalsizeunitybaselineskip +\rmfamily\trivlist\hangindent\parindent% +% V1.6 The IEEE is back to using () around theorem names which are also in italics +% Thanks to Christian Peel for reporting this. + \item[]\textit{\bfseries\noindent #1\ #2\ (#3).} \itemindent\@IEEEtmpitemindent\relax} +% V1.7 remove bogus \unskip that caused equations in theorems to collide with +% lines below. +\def\@endtheorem{\endtrivlist\vskip 0.25\@IEEEnormalsizeunitybaselineskip plus 0.26\@IEEEnormalsizeunitybaselineskip minus 0.05\@IEEEnormalsizeunitybaselineskip} +\else +% +% noncompsoc +% +% V1.8 allow long theorem names to break across lines. +% Thanks to Miquel Payaro for reporting this. +\def\@begintheorem#1#2{\@IEEEtmpitemindent\itemindent\relax\topsep 0pt\rmfamily\trivlist% + \item[]\textit{\indent #1\ #2:} \itemindent\@IEEEtmpitemindent\relax} +\def\@opargbegintheorem#1#2#3{\@IEEEtmpitemindent\itemindent\relax\topsep 0pt\rmfamily \trivlist% +% V1.6 The IEEE is back to using () around theorem names which are also in italics +% Thanks to Christian Peel for reporting this. + \item[]\textit{\indent #1\ #2\ (#3):} \itemindent\@IEEEtmpitemindent\relax} +% V1.7 remove bogus \unskip that caused equations in theorems to collide with +% lines below. +\def\@endtheorem{\endtrivlist} +\fi + + + +% V1.6 +% display command for the section the theorem is in - so that \thesection +% is not used as this will be in Roman numerals when we want arabic. +% LaTeX2e uses \def\@thmcounter#1{\noexpand\arabic{#1}} for the theorem number +% (second part) display and \def\@thmcountersep{.} as a separator. +% V1.7 intercept calls to the section counter and reroute to \@IEEEthmcounterinsection +% to allow \appendix(ices} to override as needed. +% +% special handler for sections, allows appendix(ices) to override +\gdef\@IEEEthmcounterinsection#1{\arabic{#1}} +% string macro +\edef\@IEEEstringsection{section} + +% redefine the #1#2[#3] form of newtheorem to use a hook to \@IEEEthmcounterinsection +% if section in_counter is used +\def\@xnthm#1#2[#3]{% + \expandafter\@ifdefinable\csname #1\endcsname + {\@definecounter{#1}\@newctr{#1}[#3]% + \edef\@IEEEstringtmp{#3} + \ifx\@IEEEstringtmp\@IEEEstringsection + \expandafter\xdef\csname the#1\endcsname{% + \noexpand\@IEEEthmcounterinsection{#3}\@thmcountersep + \@thmcounter{#1}}% + \else + \expandafter\xdef\csname the#1\endcsname{% + \expandafter\noexpand\csname the#3\endcsname \@thmcountersep + \@thmcounter{#1}}% + \fi + \global\@namedef{#1}{\@thm{#1}{#2}}% + \global\@namedef{end#1}{\@endtheorem}}} + + + +%% SET UP THE DEFAULT PAGESTYLE +\pagestyle{headings} +\pagenumbering{arabic} + +% normally the page counter starts at 1 +\setcounter{page}{1} +% however, for peerreview the cover sheet is page 0 or page -1 +% (for duplex printing) +\ifCLASSOPTIONpeerreview + \if@twoside + \setcounter{page}{-1} + \else + \setcounter{page}{0} + \fi +\fi + +% standard book class behavior - let bottom line float up and down as +% needed when single sided +\ifCLASSOPTIONtwoside\else\raggedbottom\fi +% if two column - turn on twocolumn, allow word spacings to stretch more and +% enforce a rigid position for the last lines +\ifCLASSOPTIONtwocolumn +% the peer review option delays invoking twocolumn + \ifCLASSOPTIONpeerreview\else + \twocolumn + \fi +\sloppy +\flushbottom +\fi + + + + +% \APPENDIX and \APPENDICES definitions + +% This is the \@ifmtarg command from the LaTeX ifmtarg package +% by Peter Wilson (CUA) and Donald Arseneau +% \@ifmtarg is used to determine if an argument to a command +% is present or not. +% For instance: +% \@ifmtarg{#1}{\typeout{empty}}{\typeout{has something}} +% \@ifmtarg is used with our redefined \section command if +% \appendices is invoked. +% The command \section will behave slightly differently depending +% on whether the user specifies a title: +% \section{My appendix title} +% or not: +% \section{} +% This way, we can eliminate the blank lines where the title +% would be, and the unneeded : after Appendix in the table of +% contents +\begingroup +\catcode`\Q=3 +\long\gdef\@ifmtarg#1{\@xifmtarg#1QQ\@secondoftwo\@firstoftwo\@nil} +\long\gdef\@xifmtarg#1#2Q#3#4#5\@nil{#4} +\endgroup +% end of \@ifmtarg defs + + +% V1.7 +% command that allows the one time saving of the original definition +% of section to \@IEEEappendixsavesection for \appendix or \appendices +% we don't save \section here as it may be redefined later by other +% packages (hyperref.sty, etc.) +\def\@IEEEsaveoriginalsectiononce{\let\@IEEEappendixsavesection\section +\let\@IEEEsaveoriginalsectiononce\relax} + +% neat trick to grab and process the argument from \section{argument} +% we process differently if the user invoked \section{} with no +% argument (title) +% note we reroute the call to the old \section* +\def\@IEEEprocessthesectionargument#1{% +\@ifmtarg{#1}{% +\@IEEEappendixsavesection*{\appendixname\nobreakspace\thesectiondis}% +\addcontentsline{toc}{section}{\appendixname\nobreakspace\thesection}}{% +\@IEEEappendixsavesection*{\appendixname\nobreakspace\thesectiondis\\* #1}% +\addcontentsline{toc}{section}{\appendixname\nobreakspace\thesection: #1}}} + +% we use this if the user calls \section{} after +% \appendix-- which has no meaning. So, we ignore the +% command and its argument. Then, warn the user. +\def\@IEEEdestroythesectionargument#1{\typeout{** WARNING: Ignoring useless +\protect\section\space in Appendix (line \the\inputlineno).}} + + +% remember \thesection forms will be displayed in \ref calls +% and in the Table of Contents. +% The \sectiondis form is used in the actual heading itself + +% appendix command for one single appendix +% normally has no heading. However, if you want a +% heading, you can do so via the optional argument: +% \appendix[Optional Heading] +\def\appendix{\relax} +\renewcommand{\appendix}[1][]{\@IEEEsaveoriginalsectiononce\par + % v1.6 keep hyperref's identifiers unique + \gdef\theHsection{Appendix.A}% + % v1.6 adjust hyperref's string name for the section + \xdef\Hy@chapapp{appendix}% + \setcounter{section}{0}% + \setcounter{subsection}{0}% + \setcounter{subsubsection}{0}% + \setcounter{paragraph}{0}% + \gdef\thesection{A}% + \gdef\thesectiondis{}% + \gdef\thesubsection{\Alph{subsection}}% + \gdef\@IEEEthmcounterinsection##1{A} + \refstepcounter{section}% update the \ref counter + \@ifmtarg{#1}{\@IEEEappendixsavesection*{\appendixname}% + \addcontentsline{toc}{section}{\appendixname}}{% + \@IEEEappendixsavesection*{\appendixname\nobreakspace\\* #1}% + \addcontentsline{toc}{section}{\appendixname: #1}}% + % redefine \section command for appendix + % leave \section* as is + \def\section{\@ifstar{\@IEEEappendixsavesection*}{% + \@IEEEdestroythesectionargument}}% throw out the argument + % of the normal form +} + + + +% appendices command for multiple appendices +% user then calls \section with an argument (possibly empty) to +% declare the individual appendices +\def\appendices{\@IEEEsaveoriginalsectiononce\par + % v1.6 keep hyperref's identifiers unique + \gdef\theHsection{Appendix.\Alph{section}}% + % v1.6 adjust hyperref's string name for the section + \xdef\Hy@chapapp{appendix}% + \setcounter{section}{-1}% we want \refstepcounter to use section 0 + \setcounter{subsection}{0}% + \setcounter{subsubsection}{0}% + \setcounter{paragraph}{0}% + \ifCLASSOPTIONromanappendices% + \gdef\thesection{\Roman{section}}% + \gdef\thesectiondis{\Roman{section}}% + \@IEEEcompsocconfonly{\gdef\thesectiondis{\Roman{section}.}}% + \gdef\@IEEEthmcounterinsection##1{A\arabic{##1}} + \else% + \gdef\thesection{\Alph{section}}% + \gdef\thesectiondis{\Alph{section}}% + \@IEEEcompsocconfonly{\gdef\thesectiondis{\Alph{section}.}}% + \gdef\@IEEEthmcounterinsection##1{\Alph{##1}} + \fi% + \refstepcounter{section}% update the \ref counter + \setcounter{section}{0}% NEXT \section will be the FIRST appendix + % redefine \section command for appendices + % leave \section* as is + \def\section{\@ifstar{\@IEEEappendixsavesection*}{% process the *-form + \refstepcounter{section}% or is a new section so, + \@IEEEprocessthesectionargument}}% process the argument + % of the normal form +} + + + +% V1.7 compoc uses nonbold drop cap and small caps word style +\ifCLASSOPTIONcompsoc + \def\IEEEPARstartFONTSTYLE{\mdseries} + \def\IEEEPARstartWORDFONTSTYLE{\scshape} + \def\IEEEPARstartWORDCAPSTYLE{\relax} +\fi +% +% +% \IEEEPARstart +% Definition for the big two line drop cap letter at the beginning of the +% first paragraph of journal papers. The first argument is the first letter +% of the first word, the second argument is the remaining letters of the +% first word which will be rendered in upper case. +% In V1.6 this has been completely rewritten to: +% +% 1. no longer have problems when the user begins an environment +% within the paragraph that uses \IEEEPARstart. +% 2. auto-detect and use the current font family +% 3. revise handling of the space at the end of the first word so that +% interword glue will now work as normal. +% 4. produce correctly aligned edges for the (two) indented lines. +% +% We generalize things via control macros - playing with these is fun too. +% +% V1.7 added more control macros to make it easy for IEEEtrantools.sty users +% to change the font style. +% +% the number of lines that are indented to clear it +% may need to increase if using decenders +\providecommand{\IEEEPARstartDROPLINES}{2} +% minimum number of lines left on a page to allow a \@IEEEPARstart +% Does not take into consideration rubber shrink, so it tends to +% be overly cautious +\providecommand{\IEEEPARstartMINPAGELINES}{2} +% V1.7 the height of the drop cap is adjusted to match the height of this text +% in the current font (when \IEEEPARstart is called). +\providecommand{\IEEEPARstartHEIGHTTEXT}{T} +% the depth the letter is lowered below the baseline +% the height (and size) of the letter is determined by the sum +% of this value and the height of the \IEEEPARstartHEIGHTTEXT in the current +% font. It is a good idea to set this value in terms of the baselineskip +% so that it can respond to changes therein. +\providecommand{\IEEEPARstartDROPDEPTH}{1.1\baselineskip} +% V1.7 the font the drop cap will be rendered in, +% can take zero or one argument. +\providecommand{\IEEEPARstartFONTSTYLE}{\bfseries} +% V1.7 any additional, non-font related commands needed to modify +% the drop cap letter, can take zero or one argument. +\providecommand{\IEEEPARstartCAPSTYLE}{\MakeUppercase} +% V1.7 the font that will be used to render the rest of the word, +% can take zero or one argument. +\providecommand{\IEEEPARstartWORDFONTSTYLE}{\relax} +% V1.7 any additional, non-font related commands needed to modify +% the rest of the word, can take zero or one argument. +\providecommand{\IEEEPARstartWORDCAPSTYLE}{\MakeUppercase} +% This is the horizontal separation distance from the drop letter to the main text. +% Lengths that depend on the font (e.g., ex, em, etc.) will be referenced +% to the font that is active when \IEEEPARstart is called. +\providecommand{\IEEEPARstartSEP}{0.15em} +% V1.7 horizontal offset applied to the left of the drop cap. +\providecommand{\IEEEPARstartHOFFSET}{0em} +% V1.7 Italic correction command applied at the end of the drop cap. +\providecommand{\IEEEPARstartITLCORRECT}{\/} + +% width of the letter output, set globally. Can be used in \IEEEPARstartSEP +% or \IEEEPARstartHOFFSET, but not the height lengths. +\newdimen\IEEEPARstartletwidth +\IEEEPARstartletwidth 0pt\relax + +% definition of \IEEEPARstart +% THIS IS A CONTROLLED SPACING AREA, DO NOT ALLOW SPACES WITHIN THESE LINES +% +% The token \@IEEEPARstartfont will be globally defined after the first use +% of \IEEEPARstart and will be a font command which creates the big letter +% The first argument is the first letter of the first word and the second +% argument is the rest of the first word(s). +\def\IEEEPARstart#1#2{\par{% +% if this page does not have enough space, break it and lets start +% on a new one +\@IEEEtranneedspace{\IEEEPARstartMINPAGELINES\baselineskip}{\relax}% +% V1.7 move this up here in case user uses \textbf for \IEEEPARstartFONTSTYLE +% which uses command \leavevmode which causes an unwanted \indent to be issued +\noindent +% calculate the desired height of the big letter +% it extends from the top of \IEEEPARstartHEIGHTTEXT in the current font +% down to \IEEEPARstartDROPDEPTH below the current baseline +\settoheight{\@IEEEtrantmpdimenA}{\IEEEPARstartHEIGHTTEXT}% +\addtolength{\@IEEEtrantmpdimenA}{\IEEEPARstartDROPDEPTH}% +% extract the name of the current font in bold +% and place it in \@IEEEPARstartFONTNAME +\def\@IEEEPARstartGETFIRSTWORD##1 ##2\relax{##1}% +{\IEEEPARstartFONTSTYLE{\selectfont\edef\@IEEEPARstartFONTNAMESPACE{\fontname\font\space}% +\xdef\@IEEEPARstartFONTNAME{\expandafter\@IEEEPARstartGETFIRSTWORD\@IEEEPARstartFONTNAMESPACE\relax}}}% +% define a font based on this name with a point size equal to the desired +% height of the drop letter +\font\@IEEEPARstartsubfont\@IEEEPARstartFONTNAME\space at \@IEEEtrantmpdimenA\relax% +% save this value as a counter (integer) value (sp points) +\@IEEEtrantmpcountA=\@IEEEtrantmpdimenA% +% now get the height of the actual letter produced by this font size +\settoheight{\@IEEEtrantmpdimenB}{\@IEEEPARstartsubfont\IEEEPARstartCAPSTYLE{#1}}% +% If something bogus happens like the first argument is empty or the +% current font is strange, do not allow a zero height. +\ifdim\@IEEEtrantmpdimenB=0pt\relax% +\typeout{** WARNING: IEEEPARstart drop letter has zero height! (line \the\inputlineno)}% +\typeout{ Forcing the drop letter font size to 10pt.}% +\@IEEEtrantmpdimenB=10pt% +\fi% +% and store it as a counter +\@IEEEtrantmpcountB=\@IEEEtrantmpdimenB% +% Since a font size doesn't exactly correspond to the height of the capital +% letters in that font, the actual height of the letter, \@IEEEtrantmpcountB, +% will be less than that desired, \@IEEEtrantmpcountA +% we need to raise the font size, \@IEEEtrantmpdimenA +% by \@IEEEtrantmpcountA / \@IEEEtrantmpcountB +% But, TeX doesn't have floating point division, so we have to use integer +% division. Hence the use of the counters. +% We need to reduce the denominator so that the loss of the remainder will +% have minimal affect on the accuracy of the result +\divide\@IEEEtrantmpcountB by 200% +\divide\@IEEEtrantmpcountA by \@IEEEtrantmpcountB% +% Then reequalize things when we use TeX's ability to multiply by +% floating point values +\@IEEEtrantmpdimenB=0.005\@IEEEtrantmpdimenA% +\multiply\@IEEEtrantmpdimenB by \@IEEEtrantmpcountA% +% \@IEEEPARstartfont is globaly set to the calculated font of the big letter +% We need to carry this out of the local calculation area to to create the +% big letter. +\global\font\@IEEEPARstartfont\@IEEEPARstartFONTNAME\space at \@IEEEtrantmpdimenB% +% Now set \@IEEEtrantmpdimenA to the width of the big letter +% We need to carry this out of the local calculation area to set the +% hanging indent +\settowidth{\global\@IEEEtrantmpdimenA}{\@IEEEPARstartfont +\IEEEPARstartCAPSTYLE{#1\IEEEPARstartITLCORRECT}}}% +% end of the isolated calculation environment +\global\IEEEPARstartletwidth\@IEEEtrantmpdimenA\relax% +% add in the extra clearance we want +\advance\@IEEEtrantmpdimenA by \IEEEPARstartSEP\relax% +% add in the optional offset +\advance\@IEEEtrantmpdimenA by \IEEEPARstartHOFFSET\relax% +% V1.7 don't allow negative offsets to produce negative hanging indents +\@IEEEtrantmpdimenB\@IEEEtrantmpdimenA +\ifnum\@IEEEtrantmpdimenB < 0 \@IEEEtrantmpdimenB 0pt\fi +% \@IEEEtrantmpdimenA has the width of the big letter plus the +% separation space and \@IEEEPARstartfont is the font we need to use +% Now, we make the letter and issue the hanging indent command +% The letter is placed in a box of zero width and height so that other +% text won't be displaced by it. +\hangindent\@IEEEtrantmpdimenB\hangafter=-\IEEEPARstartDROPLINES% +\makebox[0pt][l]{\hspace{-\@IEEEtrantmpdimenA}% +\raisebox{-\IEEEPARstartDROPDEPTH}[0pt][0pt]{\hspace{\IEEEPARstartHOFFSET}% +\@IEEEPARstartfont\IEEEPARstartCAPSTYLE{#1\IEEEPARstartITLCORRECT}% +\hspace{\IEEEPARstartSEP}}}% +{\IEEEPARstartWORDFONTSTYLE{\IEEEPARstartWORDCAPSTYLE{\selectfont#2}}}} + + + + +% determines if the space remaining on a given page is equal to or greater +% than the specified space of argument one +% if not, execute argument two (only if the remaining space is greater than zero) +% and issue a \newpage +% +% example: \@IEEEtranneedspace{2in}{\vfill} +% +% Does not take into consideration rubber shrinkage, so it tends to +% be overly cautious +% Based on an example posted by Donald Arseneau +% Note this macro uses \@IEEEtrantmpdimenB internally for calculations, +% so DO NOT PASS \@IEEEtrantmpdimenB to this routine +% if you need a dimen register, import with \@IEEEtrantmpdimenA instead +\def\@IEEEtranneedspace#1#2{\penalty-100\begingroup%shield temp variable +\@IEEEtrantmpdimenB\pagegoal\advance\@IEEEtrantmpdimenB-\pagetotal% space left +\ifdim #1>\@IEEEtrantmpdimenB\relax% not enough space left +\ifdim\@IEEEtrantmpdimenB>\z@\relax #2\fi% +\newpage% +\fi\endgroup} + + + +% IEEEbiography ENVIRONMENT +% Allows user to enter biography leaving place for picture (adapts to font size) +% As of V1.5, a new optional argument allows you to have a real graphic! +% V1.5 and later also fixes the "colliding biographies" which could happen when a +% biography's text was shorter than the space for the photo. +% MDS 7/2001 +% V1.6 prevent multiple biographies from making multiple TOC entries +\newif\if@IEEEbiographyTOCentrynotmade +\global\@IEEEbiographyTOCentrynotmadetrue + +% biography counter so hyperref can jump directly to the biographies +% and not just the previous section +\newcounter{IEEEbiography} +\setcounter{IEEEbiography}{0} + +% photo area size +\def\@IEEEBIOphotowidth{1.0in} % width of the biography photo area +\def\@IEEEBIOphotodepth{1.25in} % depth (height) of the biography photo area +% area cleared for photo +\def\@IEEEBIOhangwidth{1.14in} % width cleared for the biography photo area +\def\@IEEEBIOhangdepth{1.25in} % depth cleared for the biography photo area + % actual depth will be a multiple of + % \baselineskip, rounded up +\def\@IEEEBIOskipN{4\baselineskip}% nominal value of the vskip above the biography + +\newenvironment{IEEEbiography}[2][]{\normalfont\@IEEEcompsoconly{\sffamily}\footnotesize% +\unitlength 1in\parskip=0pt\par\parindent 1em\interlinepenalty500% +% we need enough space to support the hanging indent +% the nominal value of the spacer +% and one extra line for good measure +\@IEEEtrantmpdimenA=\@IEEEBIOhangdepth% +\advance\@IEEEtrantmpdimenA by \@IEEEBIOskipN% +\advance\@IEEEtrantmpdimenA by 1\baselineskip% +% if this page does not have enough space, break it and lets start +% with a new one +\@IEEEtranneedspace{\@IEEEtrantmpdimenA}{\relax}% +% nominal spacer can strech, not shrink use 1fil so user can out stretch with \vfill +\vskip \@IEEEBIOskipN plus 1fil minus 0\baselineskip% +% the default box for where the photo goes +\def\@IEEEtempbiographybox{{\setlength{\fboxsep}{0pt}\framebox{% +\begin{minipage}[b][\@IEEEBIOphotodepth][c]{\@IEEEBIOphotowidth}\centering PLACE\\ PHOTO\\ HERE \end{minipage}}}}% +% +% detect if the optional argument was supplied, this requires the +% \@ifmtarg command as defined in the appendix section above +% and if so, override the default box with what they want +\@ifmtarg{#1}{\relax}{\def\@IEEEtempbiographybox{\mbox{\begin{minipage}[b][\@IEEEBIOphotodepth][c]{\@IEEEBIOphotowidth}% +\centering% +#1% +\end{minipage}}}}% end if optional argument supplied +% Make an entry into the table of contents only if we have not done so before +\if@IEEEbiographyTOCentrynotmade% +% link labels to the biography counter so hyperref will jump +% to the biography, not the previous section +\setcounter{IEEEbiography}{-1}% +\refstepcounter{IEEEbiography}% +\addcontentsline{toc}{section}{Biographies}% +\global\@IEEEbiographyTOCentrynotmadefalse% +\fi% +% one more biography +\refstepcounter{IEEEbiography}% +% Make an entry for this name into the table of contents +\addcontentsline{toc}{subsection}{#2}% +% V1.6 properly handle if a new paragraph should occur while the +% hanging indent is still active. Do this by redefining \par so +% that it will not start a new paragraph. (But it will appear to the +% user as if it did.) Also, strip any leading pars, newlines, or spaces. +\let\@IEEEBIOORGparCMD=\par% save the original \par command +\edef\par{\hfil\break\indent}% the new \par will not be a "real" \par +\settoheight{\@IEEEtrantmpdimenA}{\@IEEEtempbiographybox}% get height of biography box +\@IEEEtrantmpdimenB=\@IEEEBIOhangdepth% +\@IEEEtrantmpcountA=\@IEEEtrantmpdimenB% countA has the hang depth +\divide\@IEEEtrantmpcountA by \baselineskip% calculates lines needed to produce the hang depth +\advance\@IEEEtrantmpcountA by 1% ensure we overestimate +% set the hanging indent +\hangindent\@IEEEBIOhangwidth% +\hangafter-\@IEEEtrantmpcountA% +% reference the top of the photo area to the top of a capital T +\settoheight{\@IEEEtrantmpdimenB}{\mbox{T}}% +% set the photo box, give it zero width and height so as not to disturb anything +\noindent\makebox[0pt][l]{\hspace{-\@IEEEBIOhangwidth}\raisebox{\@IEEEtrantmpdimenB}[0pt][0pt]{% +\raisebox{-\@IEEEBIOphotodepth}[0pt][0pt]{\@IEEEtempbiographybox}}}% +% now place the author name and begin the bio text +\noindent\textbf{#2\ }\@IEEEgobbleleadPARNLSP}{\relax\let\par=\@IEEEBIOORGparCMD\par% +% 7/2001 V1.5 detect when the biography text is shorter than the photo area +% and pad the unused area - preventing a collision from the next biography entry +% MDS +\ifnum \prevgraf <\@IEEEtrantmpcountA\relax% detect when the biography text is shorter than the photo + \advance\@IEEEtrantmpcountA by -\prevgraf% calculate how many lines we need to pad + \advance\@IEEEtrantmpcountA by -1\relax% we compensate for the fact that we indented an extra line + \@IEEEtrantmpdimenA=\baselineskip% calculate the length of the padding + \multiply\@IEEEtrantmpdimenA by \@IEEEtrantmpcountA% + \noindent\rule{0pt}{\@IEEEtrantmpdimenA}% insert an invisible support strut +\fi% +\par\normalfont} + + + +% V1.6 +% added biography without a photo environment +\newenvironment{IEEEbiographynophoto}[1]{% +% Make an entry into the table of contents only if we have not done so before +\if@IEEEbiographyTOCentrynotmade% +% link labels to the biography counter so hyperref will jump +% to the biography, not the previous section +\setcounter{IEEEbiography}{-1}% +\refstepcounter{IEEEbiography}% +\addcontentsline{toc}{section}{Biographies}% +\global\@IEEEbiographyTOCentrynotmadefalse% +\fi% +% one more biography +\refstepcounter{IEEEbiography}% +% Make an entry for this name into the table of contents +\addcontentsline{toc}{subsection}{#1}% +\normalfont\@IEEEcompsoconly{\sffamily}\footnotesize\interlinepenalty500% +\vskip 4\baselineskip plus 1fil minus 0\baselineskip% +\parskip=0pt\par% +\noindent\textbf{#1\ }\@IEEEgobbleleadPARNLSP}{\relax\par\normalfont} + + +% provide the user with some old font commands +% got this from article.cls +\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm} +\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} +\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt} +\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf} +\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit} +\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl} +\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc} +\DeclareRobustCommand*\cal{\@fontswitch\relax\mathcal} +\DeclareRobustCommand*\mit{\@fontswitch\relax\mathnormal} + + +% SPECIAL PAPER NOTICE COMMANDS +% +% holds the special notice text +\def\@IEEEspecialpapernotice{\relax} + +% for special papers, like invited papers, the user can do: +% \IEEEspecialpapernotice{(Invited Paper)} before \maketitle +\def\IEEEspecialpapernotice#1{\ifCLASSOPTIONconference% +\def\@IEEEspecialpapernotice{{\sublargesize\textit{#1}\vspace*{1em}}}% +\else% +\def\@IEEEspecialpapernotice{{\\*[1.5ex]\sublargesize\textit{#1}}\vspace*{-2ex}}% +\fi} + + + + +% PUBLISHER ID COMMANDS +% to insert a publisher's ID footer +% V1.6 \IEEEpubid has been changed so that the change in page size and style +% occurs in \maketitle. \IEEEpubid must now be issued prior to \maketitle +% use \IEEEpubidadjcol as before - in the second column of the title page +% These changes allow \maketitle to take the reduced page height into +% consideration when dynamically setting the space between the author +% names and the maintext. +% +% the amount the main text is pulled up to make room for the +% publisher's ID footer +% The IEEE uses about 1.3\baselineskip for journals, +% dynamic title spacing will clean up the fraction +\def\@IEEEpubidpullup{1.3\baselineskip} +\ifCLASSOPTIONtechnote +% for technotes it must be an integer of baselineskip as there can be no +% dynamic title spacing for two column mode technotes (the title is in the +% in first column) and we should maintain an integer number of lines in the +% second column +% There are some examples (such as older issues of "Transactions on +% Information Theory") in which the IEEE really pulls the text off the ID for +% technotes - about 0.55in (or 4\baselineskip). We'll use 2\baselineskip +% and call it even. +\def\@IEEEpubidpullup{2\baselineskip} +\fi + +% V1.7 compsoc does not use a pullup +\ifCLASSOPTIONcompsoc +\def\@IEEEpubidpullup{0pt} +\fi + +% holds the ID text +\def\@IEEEpubid{\relax} + +% flag so \maketitle can tell if \IEEEpubid was called +\newif\if@IEEEusingpubid +\global\@IEEEusingpubidfalse +% issue this command in the page to have the ID at the bottom +% V1.6 use before \maketitle +\def\IEEEpubid#1{\def\@IEEEpubid{#1}\global\@IEEEusingpubidtrue} + + +% command which will pull up (shorten) the column it is executed in +% to make room for the publisher ID. Place in the second column of +% the title page when using \IEEEpubid +% Is smart enough not to do anything when in single column text or +% if the user hasn't called \IEEEpubid +% currently needed in for the second column of a page with the +% publisher ID. If not needed in future releases, please provide this +% command and define it as \relax for backward compatibility +% v1.6b do not allow command to operate if the peer review option has been +% selected because \IEEEpubidadjcol will not be on the cover page. +% V1.7 do nothing if compsoc +\def\IEEEpubidadjcol{\ifCLASSOPTIONcompsoc\else\ifCLASSOPTIONpeerreview\else +\if@twocolumn\if@IEEEusingpubid\enlargethispage{-\@IEEEpubidpullup}\fi\fi\fi\fi} + +% Special thanks to Peter Wilson, Daniel Luecking, and the other +% gurus at comp.text.tex, for helping me to understand how best to +% implement the IEEEpubid command in LaTeX. + + + +%% Lockout some commands under various conditions + +% general purpose bit bucket +\newsavebox{\@IEEEtranrubishbin} + +% flags to prevent multiple warning messages +\newif\if@IEEEWARNthanks +\newif\if@IEEEWARNIEEEPARstart +\newif\if@IEEEWARNIEEEbiography +\newif\if@IEEEWARNIEEEbiographynophoto +\newif\if@IEEEWARNIEEEpubid +\newif\if@IEEEWARNIEEEpubidadjcol +\newif\if@IEEEWARNIEEEmembership +\newif\if@IEEEWARNIEEEaftertitletext +\@IEEEWARNthankstrue +\@IEEEWARNIEEEPARstarttrue +\@IEEEWARNIEEEbiographytrue +\@IEEEWARNIEEEbiographynophototrue +\@IEEEWARNIEEEpubidtrue +\@IEEEWARNIEEEpubidadjcoltrue +\@IEEEWARNIEEEmembershiptrue +\@IEEEWARNIEEEaftertitletexttrue + + +%% Lockout some commands when in various modes, but allow them to be restored if needed +%% +% save commands which might be locked out +% so that the user can later restore them if needed +\let\@IEEESAVECMDthanks\thanks +\let\@IEEESAVECMDIEEEPARstart\IEEEPARstart +\let\@IEEESAVECMDIEEEbiography\IEEEbiography +\let\@IEEESAVECMDendIEEEbiography\endIEEEbiography +\let\@IEEESAVECMDIEEEbiographynophoto\IEEEbiographynophoto +\let\@IEEESAVECMDendIEEEbiographynophoto\endIEEEbiographynophoto +\let\@IEEESAVECMDIEEEpubid\IEEEpubid +\let\@IEEESAVECMDIEEEpubidadjcol\IEEEpubidadjcol +\let\@IEEESAVECMDIEEEmembership\IEEEmembership +\let\@IEEESAVECMDIEEEaftertitletext\IEEEaftertitletext + + +% disable \IEEEPARstart when in draft mode +% This may have originally been done because the pre-V1.6 drop letter +% algorithm had problems with a non-unity baselinestretch +% At any rate, it seems too formal to have a drop letter in a draft +% paper. +\ifCLASSOPTIONdraftcls +\def\IEEEPARstart#1#2{#1#2\if@IEEEWARNIEEEPARstart\typeout{** ATTENTION: \noexpand\IEEEPARstart + is disabled in draft mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEPARstartfalse} +\fi +% and for technotes +\ifCLASSOPTIONtechnote +\def\IEEEPARstart#1#2{#1#2\if@IEEEWARNIEEEPARstart\typeout{** WARNING: \noexpand\IEEEPARstart + is locked out for technotes (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEPARstartfalse} +\fi + + +% lockout unneeded commands when in conference mode +\ifCLASSOPTIONconference +% when locked out, \thanks, \IEEEbiography, \IEEEbiographynophoto, \IEEEpubid, +% \IEEEmembership and \IEEEaftertitletext will all swallow their given text. +% \IEEEPARstart will output a normal character instead +% warn the user about these commands only once to prevent the console screen +% from filling up with redundant messages +\def\thanks#1{\if@IEEEWARNthanks\typeout{** WARNING: \noexpand\thanks + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNthanksfalse} +\def\IEEEPARstart#1#2{#1#2\if@IEEEWARNIEEEPARstart\typeout{** WARNING: \noexpand\IEEEPARstart + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEPARstartfalse} + + +% LaTeX treats environments and commands with optional arguments differently. +% the actual ("internal") command is stored as \\commandname +% (accessed via \csname\string\commandname\endcsname ) +% the "external" command \commandname is a macro with code to determine +% whether or not the optional argument is presented and to provide the +% default if it is absent. So, in order to save and restore such a command +% we would have to save and restore \\commandname as well. But, if LaTeX +% ever changes the way it names the internal names, the trick would break. +% Instead let us just define a new environment so that the internal +% name can be left undisturbed. +\newenvironment{@IEEEbogusbiography}[2][]{\if@IEEEWARNIEEEbiography\typeout{** WARNING: \noexpand\IEEEbiography + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEbiographyfalse% +\setbox\@IEEEtranrubishbin\vbox\bgroup}{\egroup\relax} +% and make biography point to our bogus biography +\let\IEEEbiography=\@IEEEbogusbiography +\let\endIEEEbiography=\end@IEEEbogusbiography + +\renewenvironment{IEEEbiographynophoto}[1]{\if@IEEEWARNIEEEbiographynophoto\typeout{** WARNING: \noexpand\IEEEbiographynophoto + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEbiographynophotofalse% +\setbox\@IEEEtranrubishbin\vbox\bgroup}{\egroup\relax} + +\def\IEEEpubid#1{\if@IEEEWARNIEEEpubid\typeout{** WARNING: \noexpand\IEEEpubid + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEpubidfalse} +\def\IEEEpubidadjcol{\if@IEEEWARNIEEEpubidadjcol\typeout{** WARNING: \noexpand\IEEEpubidadjcol + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEpubidadjcolfalse} +\def\IEEEmembership#1{\if@IEEEWARNIEEEmembership\typeout{** WARNING: \noexpand\IEEEmembership + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEmembershipfalse} +\def\IEEEaftertitletext#1{\if@IEEEWARNIEEEaftertitletext\typeout{** WARNING: \noexpand\IEEEaftertitletext + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEaftertitletextfalse} +\fi + + +% provide a way to restore the commands that are locked out +\def\IEEEoverridecommandlockouts{% +\typeout{** ATTENTION: Overriding command lockouts (line \the\inputlineno).}% +\let\thanks\@IEEESAVECMDthanks% +\let\IEEEPARstart\@IEEESAVECMDIEEEPARstart% +\let\IEEEbiography\@IEEESAVECMDIEEEbiography% +\let\endIEEEbiography\@IEEESAVECMDendIEEEbiography% +\let\IEEEbiographynophoto\@IEEESAVECMDIEEEbiographynophoto% +\let\endIEEEbiographynophoto\@IEEESAVECMDendIEEEbiographynophoto% +\let\IEEEpubid\@IEEESAVECMDIEEEpubid% +\let\IEEEpubidadjcol\@IEEESAVECMDIEEEpubidadjcol% +\let\IEEEmembership\@IEEESAVECMDIEEEmembership% +\let\IEEEaftertitletext\@IEEESAVECMDIEEEaftertitletext} + + + +% need a backslash character for typeout output +{\catcode`\|=0 \catcode`\\=12 +|xdef|@IEEEbackslash{\}} + + +% hook to allow easy disabling of all legacy warnings +\def\@IEEElegacywarn#1#2{\typeout{** ATTENTION: \@IEEEbackslash #1 is deprecated (line \the\inputlineno). +Use \@IEEEbackslash #2 instead.}} + + +% provide some legacy IEEEtran commands +\def\IEEEcompsoctitleabstractindextext{\@IEEElegacywarn{IEEEcompsoctitleabstractindextext}{IEEEtitleabstractindextext}\IEEEtitleabstractindextext} +\def\IEEEdisplaynotcompsoctitleabstractindextext{\@IEEElegacywarn{IEEEdisplaynotcompsoctitleabstractindextext}{IEEEdisplaynontitleabstractindextext}\IEEEdisplaynontitleabstractindextext} +% provide some legacy IEEEtran environments + + +% V1.8a no more support for these legacy commands +%\def\authorblockA{\@IEEElegacywarn{authorblockA}{IEEEauthorblockA}\IEEEauthorblockA} +%\def\authorblockN{\@IEEElegacywarn{authorblockN}{IEEEauthorblockN}\IEEEauthorblockN} +%\def\authorrefmark{\@IEEElegacywarn{authorrefmark}{IEEEauthorrefmark}\IEEEauthorrefmark} +%\def\PARstart{\@IEEElegacywarn{PARstart}{IEEEPARstart}\IEEEPARstart} +%\def\pubid{\@IEEElegacywarn{pubid}{IEEEpubid}\IEEEpubid} +%\def\pubidadjcol{\@IEEElegacywarn{pubidadjcol}{IEEEpubidadjcol}\IEEEpubidadjcol} +%\def\specialpapernotice{\@IEEElegacywarn{specialpapernotice}{IEEEspecialpapernotice}\IEEEspecialpapernotice} +% and environments +%\def\keywords{\@IEEElegacywarn{keywords}{IEEEkeywords}\IEEEkeywords} +%\def\endkeywords{\endIEEEkeywords} +% V1.8 no more support for legacy IED list commands +%\let\labelindent\IEEElabelindent +%\def\calcleftmargin{\@IEEElegacywarn{calcleftmargin}{IEEEcalcleftmargin}\IEEEcalcleftmargin} +%\def\setlabelwidth{\@IEEElegacywarn{setlabelwidth}{IEEEsetlabelwidth}\IEEEsetlabelwidth} +%\def\usemathlabelsep{\@IEEElegacywarn{usemathlabelsep}{IEEEusemathlabelsep}\IEEEusemathlabelsep} +%\def\iedlabeljustifyc{\@IEEElegacywarn{iedlabeljustifyc}{IEEEiedlabeljustifyc}\IEEEiedlabeljustifyc} +%\def\iedlabeljustifyl{\@IEEElegacywarn{iedlabeljustifyl}{IEEEiedlabeljustifyl}\IEEEiedlabeljustifyl} +%\def\iedlabeljustifyr{\@IEEElegacywarn{iedlabeljustifyr}{IEEEiedlabeljustifyr}\IEEEiedlabeljustifyr} +% V1.8 no more support for QED and proof stuff +%\def\QED{\@IEEElegacywarn{QED}{IEEEQED}\IEEEQED} +%\def\QEDclosed{\@IEEElegacywarn{QEDclosed}{IEEEQEDclosed}\IEEEQEDclosed} +%\def\QEDopen{\@IEEElegacywarn{QEDopen}{IEEEQEDopen}\IEEEQEDopen} +%\AtBeginDocument{\def\proof{\@IEEElegacywarn{proof}{IEEEproof}\IEEEproof}\def\endproof{\endIEEEproof}} +% V1.8 no longer support biography or biographynophoto +%\def\biography{\@IEEElegacywarn{biography}{IEEEbiography}\IEEEbiography} +%\def\biographynophoto{\@IEEElegacywarn{biographynophoto}{IEEEbiographynophoto}\IEEEbiographynophoto} +%\def\endbiography{\endIEEEbiography} +%\def\endbiographynophoto{\endIEEEbiographynophoto} +% V1.7 and later no longer supports \overrideIEEEmargins +%\def\overrideIEEEmargins{% +%\typeout{** WARNING: \string\overrideIEEEmargins \space no longer supported (line \the\inputlineno).}% +%\typeout{** Use the \string\CLASSINPUTinnersidemargin, \string\CLASSINPUToutersidemargin \space controls instead.}} + +\endinput + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% End of IEEEtran.cls %%%%%%%%%%%%%%%%%%%%%%%%%%%% +% That's all folks! + diff --git a/cs_capstone_documents/spring_final_report/cs_group30_capstone_final_report.pdf b/cs_capstone_documents/spring_final_report/cs_group30_capstone_final_report.pdf new file mode 100644 index 0000000..3f3a9c4 Binary files /dev/null and b/cs_capstone_documents/spring_final_report/cs_group30_capstone_final_report.pdf differ diff --git a/cs_capstone_documents/spring_final_report/figures/OSURCLogoOrange.png b/cs_capstone_documents/spring_final_report/figures/OSURCLogoOrange.png new file mode 100644 index 0000000..5aa6b92 Binary files /dev/null and b/cs_capstone_documents/spring_final_report/figures/OSURCLogoOrange.png differ diff --git a/cs_capstone_documents/spring_final_report/figures/Oregon_State_College_of_Engineering_Logo.jpg b/cs_capstone_documents/spring_final_report/figures/Oregon_State_College_of_Engineering_Logo.jpg new file mode 100644 index 0000000..a96c00d Binary files /dev/null and b/cs_capstone_documents/spring_final_report/figures/Oregon_State_College_of_Engineering_Logo.jpg differ diff --git a/cs_capstone_documents/spring_final_report/figures/centered.png b/cs_capstone_documents/spring_final_report/figures/centered.png new file mode 100644 index 0000000..aab7878 Binary files /dev/null and b/cs_capstone_documents/spring_final_report/figures/centered.png differ diff --git a/cs_capstone_documents/spring_final_report/figures/gantt_image.pdf b/cs_capstone_documents/spring_final_report/figures/gantt_image.pdf new file mode 100644 index 0000000..bd8d1ae Binary files /dev/null and b/cs_capstone_documents/spring_final_report/figures/gantt_image.pdf differ diff --git a/cs_capstone_documents/spring_final_report/figures/iris.jpg b/cs_capstone_documents/spring_final_report/figures/iris.jpg new file mode 100644 index 0000000..36aa712 Binary files /dev/null and b/cs_capstone_documents/spring_final_report/figures/iris.jpg differ diff --git a/cs_capstone_documents/spring_final_report/figures/unzoomed.png b/cs_capstone_documents/spring_final_report/figures/unzoomed.png new file mode 100644 index 0000000..f40a0c6 Binary files /dev/null and b/cs_capstone_documents/spring_final_report/figures/unzoomed.png differ diff --git a/cs_capstone_documents/spring_final_report/figures/video_working.jpg b/cs_capstone_documents/spring_final_report/figures/video_working.jpg new file mode 100644 index 0000000..5cd77ce Binary files /dev/null and b/cs_capstone_documents/spring_final_report/figures/video_working.jpg differ diff --git a/cs_capstone_documents/spring_final_report/final_report.tex b/cs_capstone_documents/spring_final_report/final_report.tex new file mode 100644 index 0000000..1cb171b --- /dev/null +++ b/cs_capstone_documents/spring_final_report/final_report.tex @@ -0,0 +1,165 @@ +\documentclass[onecolumn, draftclsnofoot, 10pt, compsoc]{IEEEtran} +\usepackage{graphicx} +\graphicspath{{./figures/}} + +\usepackage{url} +\usepackage{setspace} +\usepackage{multicol} +\usepackage{pdflscape} +\usepackage{pdfpages} +\usepackage[british]{babel} +\usepackage{listings} +\usepackage{xcolor} +\usepackage{listings} +\usepackage{hyperref} +\usepackage{subfig} +\usepackage{pdfpages} +\usepackage{longtable} + +\usepackage{geometry} +\geometry{textheight=9.5in, textwidth=7in} + +\hypersetup{ + colorlinks=true, + linkcolor=blue, + filecolor=magenta, + urlcolor=cyan, +} + +% \overfullrule=2in + +% 1. Fill in these details +\def \CapstoneTeamName{ Ground Station Software Team} +\def \CapstoneTeamNumber{ 30} +\def \GroupMemberOne{ Kenneth Steinfeldt} +\def \GroupMemberTwo{ Christopher Pham} +\def \GroupMemberThree{ Corwin Perren} +\def \CapstoneProjectName{ OSU Robotics Club\\Mars Rover Ground Station} +\def \CapstoneSponsorCompany{ OSU Robotics Club} +\def \CapstoneSponsorPerson{ Nick McComb} + + + +%Personal \newcommands + +\newcommand{\functRequ}[4]{ +\item #1% +\par +\begin{itemize} +\item \textit{Description:} #2.% +\item \textit{Rationale:} #3.% +\item \textit{Dependencies:} #4% +\end{itemize} +} +\definecolor{backcolor}{rgb}{0.95,0.95,0.92} +\lstset{basicstyle=\ttfamily, + backgroundcolor=\color{backcolor}, + showstringspaces=false, + commentstyle=\color{red}, + keywordstyle=\color{blue}, + columns=fullflexible, + breaklines=true, + postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space}, +} + + +% 2. Uncomment the appropriate line below so that the document type works +\def \DocType{ %Problem Statement + %Requirements Document + %Technology Review + %Design Document + Final Report + } + +\newcommand{\NameSigPair}[1]{ + \par + \makebox[2.75in][r]{#1} + \hfill + \makebox[3.25in]{ + \makebox[2.25in]{\hrulefill} + \hfill + \makebox[.75in]{\hrulefill} + } + \par\vspace{-12pt} + \textit{ + \tiny\noindent + \makebox[2.75in]{} + \hfill + \makebox[3.25in]{ + \makebox[2.25in][r]{Signature} + \hfill + \makebox[.75in][r]{Date} + } + } +} +% 3. If the document is not to be signed, uncomment the command below +\renewcommand{\NameSigPair}[1]{#1} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{document} +\begin{titlepage} + \pagenumbering{gobble} + \begin{singlespace} + % 4. If you have a logo, use this includegraphics command to put it on the coversheet. + \begin{minipage}{7in} + \centering + \hspace*{-.7in} + $\vcenter{\hbox{\includegraphics[height=4cm]{Oregon_State_College_of_Engineering_Logo}}}$ + \hspace*{.2in} + $\vcenter{\hbox{\includegraphics[height=2.5cm]{OSURCLogoOrange}}}$ + \end{minipage} + + \par\vspace{.35in} + \centering + \scshape{ + \huge CS Capstone \DocType \par + {\large\today}\par + \vspace{.5in} + \textbf{\Huge\CapstoneProjectName}\par + \vfill + {\large Prepared for}\par + \Huge \CapstoneSponsorCompany\par + \vspace{5pt} + {\Large\NameSigPair{\CapstoneSponsorPerson}\par} + {\large Prepared by }\par + Group\CapstoneTeamNumber\par + % 5. comment out the line below this one if you do not wish to name your team + \CapstoneTeamName\par + \vspace{5pt} + {\Large + \NameSigPair{\GroupMemberOne}\par + \NameSigPair{\GroupMemberTwo}\par + \NameSigPair{\GroupMemberThree}\par + } + \vspace{20pt} + \begin{abstract} + % 6. Fill in your abstract + This document contains all of the useful documentation about the OSURC Mars Rover ground station project as it has progressed throughout the year. This includes all technical documents (with revisions), weekly blog posts, code documentation, and lessons learned. + + \end{abstract} + } + \end{singlespace} +\end{titlepage} +\newpage +\pagenumbering{arabic} +\tableofcontents +\clearpage + +% Write stuff here.... +\input{01-introduction/introduction} +\input{02-requirementsdoc/requirementsdoc} +\input{03-designdoc/designdoc} +\input{04-techreviewdocs/techreviewdocs} +\input{05-blogposts/blogposts} +\input{06-poster/poster} +\input{07-documentation/documentation} +\input{08-technicalresources/technicalresources} +\input{09-conclusions/conclusions} +\input{10-codelistings/codelistings} +\input{11-miscellaneous/miscellaneous} +\end{document} + + + + + diff --git a/cs_capstone_documents/spring_final_report/latexmk.pl b/cs_capstone_documents/spring_final_report/latexmk.pl new file mode 100644 index 0000000..0a84e0e --- /dev/null +++ b/cs_capstone_documents/spring_final_report/latexmk.pl @@ -0,0 +1,8802 @@ +#!/usr/bin/env perl + +# ?? Still need to fix bcf error issue. +# Don't keep looping after error +# pvc: Only re-run on USER FILE CHANGE. +# See # ??????? BCF + + +#!!!!!!!!??? Check @pwd_log + + +# !!!!!!!!!! Don't forget to document $silence_logfile_warnings.!!! + +# N.B. !!!!!!!!!!! See 17 July 2012 comments !!!!!!!!!!!!!!!!!! + +# On a UNIX-like system, the above enables latexmk to run independently +# of the location of the perl executable. This line relies on the +# existence of the program /usr/bin/env +# If there is a problem for any reason, you can replace the first line of +# this file by: + +#!/usr/bin/perl -w + +# with the path of the perl executable adjusted for your system. + +use warnings; + +# Delete #??!! when working + +# See ?? <=============================== + +## ?? Issues with clean-up +## List of aux files deleted is those read, not those generated. +## Other files are generated by (pdf)latex; should they be deleted? +## (I have hooks for this). + + + +#======================================= + +#?? Force mode doesn't appear to do force (if error in latex file) +#??? Get banner back in. +#?? CORRECT DIAGNOSTICS ON CHANGED FILES IF THEY DIDN'T EXIST BEFORE +#?? Further corrections to deal with disappeared source files for custom dependencies. +# Message repeatedly appears about remake when source file of cusdep doesn't exist. +#?? logfile w/o fdb file: don't set changed file, perhaps for generated exts. +# Reconsider +#?? Do proper run-stuff for bibtex, makeindex, cus-deps. OK I think +# Parse and correctly find ist files + + +# ATTEMPT TO ALLOW FILENAMES WITH SPACES: +# (as of 1 Apr 2006, and then 14 Sep. 2007) + +# Problems: +# A. Quoting filenames will not always work. +# a. Under UNIX, quotes are legal in filenames, so when PERL +# directly runs a binary, a quoted filename will be treated as +# as a filename containing a quote character. But when it calls +# a shell, the quotes are handled by the shell as quotes. +# b. Under MSWin32, quotes are illegal filename characters, and tend +# to be handled correctly. +# c. But under cygwin, results are not so clear (there are many +# combinations: native v. cygwin perl, native v cygwin programs +# NT v. unix scripts, which shell is called. +# B. TeX doesn't always handle filenames with spaces gracefully. +# a. UNIX/LINUX: The version on gluon2 Mar 31, 2006 to Sep. 2007) +# doesn't handle them at all. (TeX treats space as separator.) +# b. At least some later versions actually do (Brad Miller e-mail, +# Sep. 2007). +# c. fptex [[e-TeXk, Version 3.141592-2.1 (Web2c 7.5.2)] does, on +# my MSWin at home. In \input the filename must be in quotes. +# d. Bibtex [BibTeX (Web2c 7.5.2) 0.99c on my MSWin system at home, +# Sep. 2007] does not allow names of bibfiles to have spaces. +# C. =====> Using the shell for command lines is not safe, since special +# characters can cause lots of mayhem. +# It will therefore be a good idea to sanitize filenames. +# +# I've sanitized all calls out: +# a. system and exec use a single argument, which forces +# use of shell, under all circumstances +# Thus I can safely use quotes on filenames: They will be handled by +# the shell under UNIX, and simply passed on to the program under MSWin32. +# b. I reorganized Run, Run_Detached to use single command line +# c. All calls to Run and Run_Detached have quoted filenames. +# d. So if a space-free filename with wildcards is given on latexmk's +# command line, and it globs to space-containing filename(s), that +# works (fptex on home computer, native NT tex) +# e. ====> But globbing fails: the glob function takes space as filename +# separator. ==================== + +#================= TO DO ================ +# +# 1. See ?? ESPECIALLY $MSWin_fudge_break +# 2. Check fudged conditions in looping and make_files +# 3. Should not completely abort after a run that ends in failure from latex +# Missing input files (including via custom dependency) should be checked for +# a change in status +# If sources for missing files from custom dependency +# are available, then do a rerun +# If sources of any kind become available rerun (esp. for pvc) +# rerun +# Must parse log_file after unsuccessful run of latex: it may give +# information about missing files. +# 4. Check file of bug reports and requests +# 5. Rationalize bibtex warnings and errors. Two almost identical routines. +# Should 1. Use single routine +# 2. Convert errors to failure only in calling routine +# 3. Save first warning/error. + +# ?? Use of generated_exts arrays and hashes needs rationalization + +# To do: +# Rationalize again handling of include files. +# Now I use kpsewhich to do searches, if file not found +# (How do I avoid getting slowed down too much?) +# Document the assumptions at each stage of processing algorithm. +# Option to restart previewer automatically, if it dies under -pvc +# Test for already running previewer gets wrong answer if another +# process has the viewed file in its command line + +$my_name = 'latexmk'; +$My_name = 'Latexmk'; +$version_num = '4.52c'; +$version_details = "$My_name, John Collins, 19 Jan. 2017"; + +use Config; +use File::Basename; +use File::Copy; +use File::Glob ':glob'; # Better glob. Does not use space as item separator. +use File::Path 2.08 qw( make_path ); +use FileHandle; +use File::Find; +use List::Util qw( max ); +use Cwd; # To be able to change cwd +use Cwd "chdir"; # Ensure $ENV{PWD} tracks cwd +use Digest::MD5; + +#use strict; + +# The following variables are assigned once and then used in symbolic +# references, so we need to avoid warnings 'name used only once': +use vars qw( $dvi_update_command $ps_update_command $pdf_update_command ); + +# Translation of signal names to numbers and vv: +%signo = (); +@signame = (); +if ( defined $Config{sig_name} ) { + $i = 0; + foreach $name (split('\s+', $Config{sig_name})) { + $signo{$name} = $i; + $signame[$i] = $name; + $i++; + } +} +else { + warn "Something wrong with the perl configuration: No signals?\n"; +} + +## Copyright John Collins 1998-2017 +## (username jcc8 at node psu.edu) +## (and thanks to David Coppit (username david at node coppit.org) +## for suggestions) +## Copyright Evan McLean +## (modifications up to version 2) +## Copyright 1992 by David J. Musliner and The University of Michigan. +## (original version) +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +## +## +## +## NEW FEATURES, since v. 2.0: +## 1. Correct algorithm for deciding how many times to run latex: +## based on whether source file(s) change between runs +## 2. Continuous preview works, and can be of ps file or dvi file +## 3. pdf creation by pdflatex possible +## 4. Defaults for commands are OS dependent. +## 5. Parsing of log file instead of source file is used to +## obtain dependencies, by default. +## +## Modification log from 9 Dec 2011 onwards in detail +## +## 12 Jan 2012 STILL NEED TO DOCUMENT some items below +## +## 19 Jan 2017 John Collins Make -jobname work with -pdfxe and -pdflua +## (v. 4.53c) +## 17 Jan 2017 John Collins Fix bbl file detection bug. +## Bbl files were previously only identified +## from occurrence as input files in log +## file rather than from fls as well. +## 16 Jan 2017 John Collins Clean up +## Add extra item to @file_not_found for +## xelatex's characteristic message. +## 14 Jan 2017 John Collins Fix some diagnostics. +## Detect graphics candidates in log file from +## <...> constructs. +## Don't look in log file for input files in the +## (...) and <...> constructs unless forced to +## by lack of up-to-date fls file. +## 13 Jan 2017 John Collins Kpsewhich diagnostics: also if not +## silent, or when $kpsewhich_show set. +## Optimize calls to kpsewhich to find files +## given by lines put in log file by +## graphics package. +## Work around LuaTeX line-wrapping bug. (LuaTeX 0.95.0) +## 12 Jan 2017 John Collins Improve error reporting on failed run. +## 11 Jan 2017 John Collins With -diagnositcs, include invocation +## and results for kpsewhich. +## 4, 10 Jan 2017 John Collins Finish fix for read-after-write files +## 29-31 Dec 2016 John Collins V. 4.51 +## For biber and bibtex rules, included .blg +## file as extra generated file. +## Similarly for makeindex rule +## 3 Nov 2016 John Collins Start to fix problem reported by jfbu +## that with deleted aux file, latexmk +## does too few runs. +## Problems: +## 1. latexmk doesn't create initial +## dummy aux or fdb when only one +## fails to exist, but only when +## both fail to exist. +## 2. latexmk detects the aux file as +## only read after write, and +## hence not a true dependent. +## That is the initial attempt to +## read, giving a No file message, +## is not recorded in the fls +## file. +## First fix: missing aux file => make +## dummy. +## Need better: if source file in fdb +## doesn't exist initially, then it +## should be counted as initially +## read, so not read after write. +## 18 Oct 2016 John Collins xelatex support via xdv file for speed. +## lualatex +## 5 Sep 2016 John Collins Add routines: rdb_list_source, rdb_set_source +## 17 Aug 2016 John Collins Add XDG Base Directory compatibility +## for per-user rc file +## 1 May 2016 John Collins Correct creation of output and aux directories +## to correctly handle relative paths when -cd +## is used. +## 22 Apr 2016 John Collins Fix problem of -C not always working correctly +## when compilation was with -pdf and clear was default. +## (Correctly default set of rules in rdb_make_rule_list.) +## Ver. 4.45 +## +## 1998-2010, John Collins. Many improvements and fixes. +## See CHANGE-log.txt for full list, and CHANGES for summary +## +## Modified by Evan McLean (no longer available for support) +## Original script (RCS version 2.3) called "go" written by David J. Musliner +## +##----------------------------------------------------------------------- + + +## Explicit exit codes: +## 10 = bad command line arguments +## 11 = file specified on command line not found +## or other file not found +## 12 = failure in some part of making files +## 13 = error in initialization file +## 20 = probable bug +## or retcode from called program. + + +# Line length in log file that indicates wrapping. +# This number EXCLUDES line-end characters, and is one-based. +# It is the parameter max_print_line in the TeX program. (tex.web) +$log_wrap = 79; + +######################################################################### +## Default parsing and file-handling settings + +## Array of reg-exps for patterns in log-file for file-not-found +## Each item is the string in a regexp, without the enclosing slashes. +## First parenthesized part is the filename. +## Note the need to quote slashes and single right quotes to make them +## appear in the regexp. +## Add items by push, e.g., +## push @file_not_found, '^No data file found `([^\\\']*)\\\''; +## will give match to line starting "No data file found `filename'" +@file_not_found = ( + '^No file\\s*(.*)\\.$', + '^\\! LaTeX Error: File `([^\\\']*)\\\' not found\\.', + '.*?:\\d*: LaTeX Error: File `([^\\\']*)\\\' not found\\.', + '^LaTeX Warning: File `([^\\\']*)\\\' not found', + '^Package .* [fF]ile `([^\\\']*)\\\' not found', + 'Error: pdflatex \(file ([^\)]*)\): cannot find image file', + ': File (.*) not found:\s*$', + '! Unable to load picture or PDF file \\\'([^\\\']+)\\\'.', +); + +## Hash mapping file extension (w/o period, e.g., 'eps') to a single regexp, +# whose matching by a line in a file with that extension indicates that the +# line is to be ignored in the calculation of the hash number (md5 checksum) +# for the file. Typically used for ignoring datestamps in testing whether +# a file has changed. +# Add items e.g., by +# $hash_calc_ignore_pattern{'eps'} = '^%%CreationDate: '; +# This makes the hash calculation for an eps file ignore lines starting with +# '%%CreationDate: ' +# ?? Note that a file will be considered changed if +# (a) its size changes +# or (b) its hash changes +# So it is useful to ignore lines in the hash calculation only if they +# are of a fixed size (as with a date/time stamp). +%hash_calc_ignore_pattern =(); + + +# Specification of templates for extra rules. +# See subroutine rdb_make_rule_list for examples of rule templates. +# See subroutine rdb_set_rules for how they get used to construct rules. +# (Documentation obviously needs to be improved!) +%extra_rule_spec = (); + + +# Hooks for customized extra processing on aux files. The following +# variable is an array of references to function. Each function is +# invoked in turn when a line of an aux file is processed (if none +# of the built-in actions have been done). On entry to the function, +# the following variables are set: +# $_ = current line of aux file +# $rule = name of rule during the invocation of which, the aux file +# was supposed to have been generated. +@aux_hooks = (); + +######################################################################### +## Default document processing programs, and related settings, +## These are mostly the same on all systems. +## Most of these variables represents the external command needed to +## perform a certain action. Some represent switches. + +## Commands to invoke latex, pdflatex, etc +$latex = 'latex %O %S'; +$pdflatex = 'pdflatex %O %S'; +$lualatex = 'lualatex %O %S'; +# xelatex is used to give xdv file, not pdf file +$xelatex = 'xelatex -no-pdf %O %S'; + +## Default switches: +$latex_default_switches = ''; +$pdflatex_default_switches = ''; +$lualatex_default_switches = ''; +$xelatex_default_switches = ''; + +## Switch(es) to make them silent: +$latex_silent_switch = '-interaction=batchmode'; +$pdflatex_silent_switch = '-interaction=batchmode'; +$lualatex_silent_switch = '-interaction=batchmode'; +$xelatex_silent_switch = '-interaction=batchmode'; + +# %input_extensions maps primary_rule_name to pointer to hash of file extensions +# used for extensionless files specified in the source file by constructs +# like \input{file} \includegraphics{file} +# Could write +#%input_extensions = ( 'latex' => { 'tex' => 1, 'eps' => 1 };, +# 'pdflatex' => { 'tex' => 1, 'pdf' => 1, 'jpg' => 1, 'png' => 1 }; ); +# Instead we'll exercise the user-friendly access routines: +add_input_ext( 'latex', 'tex', 'eps' ); +add_input_ext( 'pdflatex', 'tex', 'jpg', 'pdf', 'png' ); +add_input_ext( 'lualatex', 'tex', 'jpg', 'pdf', 'png' ); +add_input_ext( 'xelatex', 'tex', 'jpg', 'pdf', 'png' ); +#show_input_ext( 'latex' ); show_input_ext( 'pdflatex' ); + +# Information about options to latex and pdflatex that latexmk will simply +# pass through to (pdf)latex +# Option without arg. maps to itself. +# Option with arg. maps the option part to the full specification +# e.g., -kpathsea-debug => -kpathsea-debug=NUMBER +%allowed_latex_options = (); +%allowed_latex_options_with_arg = (); +foreach ( + ##### + # TeXLive options + "-draftmode switch on draft mode (generates no output PDF)", + "-enc enable encTeX extensions such as \\mubyte", + "-etex enable e-TeX extensions", + "-file-line-error enable file:line:error style messages", + "-no-file-line-error disable file:line:error style messages", + "-fmt=FMTNAME use FMTNAME instead of program name or a %& line", + "-halt-on-error stop processing at the first error", + "-interaction=STRING set interaction mode (STRING=batchmode/nonstopmode/\n". + " scrollmode/errorstopmode)", + "-ipc send DVI output to a socket as well as the usual\n". + " output file", + "-ipc-start as -ipc, and also start the server at the other end", + "-kpathsea-debug=NUMBER set path searching debugging flags according to\n". + " the bits of NUMBER", + "-mktex=FMT enable mktexFMT generation (FMT=tex/tfm/pk)", + "-no-mktex=FMT disable mktexFMT generation (FMT=tex/tfm/pk)", + "-mltex enable MLTeX extensions such as \charsubdef", + "-output-comment=STRING use STRING for DVI file comment instead of date\n". + " (no effect for PDF)", + "-output-format=FORMAT use FORMAT for job output; FORMAT is `dvi\" or `pdf\"", + "-parse-first-line enable parsing of first line of input file", + "-no-parse-first-line disable parsing of first line of input file", + "-progname=STRING set program (and fmt) name to STRING", + "-shell-escape enable \\write18{SHELL COMMAND}", + "-no-shell-escape disable \\write18{SHELL COMMAND}", + "-shell-restricted enable restricted \\write18", + "-src-specials insert source specials into the DVI file", + "-src-specials=WHERE insert source specials in certain places of\n". + " the DVI file. WHERE is a comma-separated value\n". + " list: cr display hbox math par parend vbox", + "-synctex=NUMBER generate SyncTeX data for previewers if nonzero", + "-translate-file=TCXNAME use the TCX file TCXNAME", + "-8bit make all characters printable by default", + + ##### + # MikTeX options not in TeXLive + "-alias=app pretend to be app", + "-buf-size=n maximum number of characters simultaneously present\n". + " in current lines", + "-c-style-errors C-style error messages", + "-disable-installer disable automatic installation of missing packages", + "-disable-pipes disable input (output) from (to) child processes", + "-disable-write18 disable the \\write18{command} construct", + "-dont-parse-first-line disable checking whether the first line of the main\n". + " input file starts with %&", + "-enable-enctex enable encTeX extensions such as \\mubyte", + "-enable-installer enable automatic installation of missing packages", + "-enable-mltex enable MLTeX extensions such as \charsubdef", + "-enable-pipes enable input (output) from (to) child processes", + "-enable-write18 fully enable the \\write18{command} construct", + "-error-line=n set the width of context lines on terminal error\n". + " messages", + "-extra-mem-bot=n set the extra size (in memory words) for large data\n". + " structures", + "-extra-mem-top=n set the extra size (in memory words) for chars,\n". + " tokens, et al", + "-font-max=n set the maximum internal font number", + "-font-mem-size=n set the size, in TeX memory words, of the font memory", + "-half-error-line=n set the width of first lines of contexts in terminal\n". + " error messages", + "-hash-extra=n set the extra space for the hash table of control\n". + " sequences", + "-job-time=file set the time-stamp of all output files equal to\n". + " file's time-stamp", + "-main-memory=n change the total size (in memory words) of the main\n". + " memory array", + "-max-in-open=n set the maximum number of input files and error\n". + " insertions that can be going on simultaneously", + "-max-print-line=n set the width of longest text lines output", + "-max-strings=n set the maximum number of strings", + "-nest-size=n set the maximum number of semantic levels\n". + " simultaneously active", + "-no-c-style-errors standard error messages", + "-param-size=n set the the maximum number of simultaneous macro\n". + " parameters", + "-pool-size=n set the maximum number of characters in strings", + "-record-package-usages=file record all package usages and write them into\n". + " file", + "-restrict-write18 partially enable the \\write18{command} construct", + "-save-size=n set the the amount of space for saving values\n". + " outside of current group", + "-stack-size=n set the maximum number of simultaneous input sources", + "-string-vacancies=n set the minimum number of characters that should be\n". + " available for the user's control sequences and font\n". + " names", + "-tcx=name process the TCX table name", + "-time-statistics show processing time statistics", + "-trace enable trace messages", + "-trace=tracestreams enable trace messages. The tracestreams argument is\n". + " a comma-separated list of trace stream names", + "-trie-size=n set the amount of space for hyphenation patterns", + "-undump=name use name as the name of the format to be used,\n". + " instead of the name by which the program was\n". + " called or a %& line.", + + ##### + # Options passed to (pdf)latex that have special processing by latexmk, + # so they are commented out here. + #-jobname=STRING set the job name to STRING + #-aux-directory=dir Set the directory dir to which auxiliary files are written + #-output-directory=DIR use existing DIR as the directory to write files in + #-quiet + #-recorder enable filename recorder + # + # Options with different processing by latexmk than (pdf)latex + #-help + #-version + # + # Options NOT used by latexmk + #-includedirectory=dir prefix dir to the search path + #-initialize become the INI variant of the compiler + #-ini be pdfinitex, for dumping formats; this is implicitly + # true if the program name is `pdfinitex' +) { + if ( /^([^\s=]+)=/ ) { + $allowed_latex_options_with_arg{$1} = $_; + } + elsif ( /^([^\s=]+)\s/ ) { + $allowed_latex_options{$1} = $_; + } + else { + $allowed_latex_options{$_} = $_; + } +} + +# Arrays of options that will be added to latex and pdflatex. +# These need to be stored until after the command line parsing is finished, +# in case the values of $latex and/or $pdflatex change after an option +# is added. +@extra_latex_options = (); +@extra_pdflatex_options = (); +@extra_lualatex_options = (); +@extra_xelatex_options = (); + + +## Command to invoke biber & bibtex +$biber = 'biber %O %B'; +$bibtex = 'bibtex %O %B'; +# Switch(es) to make biber & bibtex silent: +$biber_silent_switch = '--onlylog'; +$bibtex_silent_switch = '-terse'; +$bibtex_use = 1; # Whether to actually run bibtex to update bbl files + # 0: Never run bibtex + # 1: Run bibtex only if the bibfiles exists + # according to kpsewhich, and the bbl files + # appear to be out-of-date + # 2: Run bibtex when the bbl files are out-of-date + # In any event bibtex is only run if the log file + # indicates that the document uses bbl files. + +## Command to invoke makeindex +$makeindex = 'makeindex %O -o %D %S'; +# Switch(es) to make makeinex silent: +$makeindex_silent_switch = '-q'; + +## Command to convert dvi file to pdf file directly: +$dvipdf = 'dvipdf %O %S %D'; +# N.B. Standard dvipdf runs dvips and gs with their silent switch, so for +# standard dvipdf $dvipdf_silent_switch is unneeded, but innocuous. +# But dvipdfmx can be used instead, and it has a silent switch (-q). +# So implementing $dvipdf_silent_switch is useful. + +$dvipdf_silent_switch = '-q'; + +## Command to convert dvi file to ps file: +$dvips = 'dvips %O -o %D %S'; +## Command to convert dvi file to ps file in landscape format: +$dvips_landscape = 'dvips -tlandscape %O -o %D %S'; +# Switch(es) to get dvips to make ps file suitable for conversion to good pdf: +# (If this is not used, ps file and hence pdf file contains bitmap fonts +# (type 3), which look horrible under acroread. An appropriate switch +# ensures type 1 fonts are generated. You can put this switch in the +# dvips command if you prefer.) +$dvips_pdf_switch = '-P pdf'; +# Switch(es) to make dvips silent: +$dvips_silent_switch = '-q'; + +## Command to convert ps file to pdf file: +$ps2pdf = 'ps2pdf %O %S %D'; + +## Command to convert xdv file to pdf file +$xdvipdfmx = 'xdvipdfmx -o %D %O %S'; +$xdvipdfmx_silent_switch = '-q'; + + +## Command to search for tex-related files +$kpsewhich = 'kpsewhich %S'; + +## Command to run make: +$make = 'make'; + +##Printing: +$print_type = 'auto'; # When printing, print the postscript file. + # Possible values: 'dvi', 'ps', 'pdf', 'auto', 'none' + # 'auto' ==> set print type according to the printable + # file(s) being made: priority 'ps', 'pdf', 'dvi' + +## Which treatment of default extensions and filenames with +## multiple extensions is used, for given filename on +## tex/latex's command line? See sub find_basename for the +## possibilities. +## Current tex's treat extensions like UNIX teTeX: +$extension_treatment = 'unix'; + +## Substitute backslashes in file and directory names for +## MSWin command line +$MSWin_back_slash = 1; + +$dvi_update_signal = undef; +$ps_update_signal = undef; +$pdf_update_signal = undef; + +$dvi_update_command = undef; +$ps_update_command = undef; +$pdf_update_command = undef; + +$allow_subdir_creation = 1; + +$new_viewer_always = 0; # If 1, always open a new viewer in pvc mode. + # If 0, only open a new viewer if no previous + # viewer for the same file is detected. + +$quote_filenames = 1; # Quote filenames in external commands + +$del_dir = ''; # Directory into which cleaned up files are to be put. + # If $del_dir is '', just delete the files + +@rc_system_files = (); + +######################################################################### + +################################################################ +## Special variables for system-dependent fudges, etc. +$log_file_binary = 0; # Whether to treat log file as binary + # Normally not, since the log file SHOULD be pure text. + # But Miktex 2.7 sometimes puts binary characters + # in it. (Typically in construct \OML ... after + # overfull box with mathmode.) + # Sometimes there is ctrl/Z, which is not only non-text, + # but is end-of-file marker for MS-Win in text mode. + +$MSWin_fudge_break = 1; # Give special treatment to ctrl/C and ctrl/break + # in -pvc mode under MSWin + # Under MSWin32 (at least with perl 5.8 and WinXP) + # when latexmk is running another program, and the + # user gives ctrl/C or ctrl/break, to stop the + # daughter program, not only does it reach + # the daughter, but also latexmk/perl, so + # latexmk is stopped also. In -pvc mode, + # this is not normally desired. So when the + # $MSWin_fudge_break variable is set, + # latexmk arranges to ignore ctrl/C and + # ctrl/break during processing of files; + # only the daughter programs receive them. + # This fudge is not applied in other + # situations, since then having latexmk also + # stopping because of the ctrl/C or + # ctrl/break signal is desirable. + # The fudge is not needed under UNIX (at least + # with Perl 5.005 on Solaris 8). Only the + # daughter programs receive the signal. In + # fact the inverse would be useful: In + # normal processing, as opposed to -pvc, if + # force mode (-f) is set, a ctrl/C is + # received by a daughter program does not + # also stop latexmk. Under tcsh, we get + # back to a command prompt, while latexmk + # keeps running in the background! + + +################################################################ + + +# System-dependent overrides: +# Currently, the cases I have tests for are: MSWin32, cygwin, linux and +# darwin, with the main complications being for MSWin32 and cygwin. +# Special treatment may also be useful for MSYS (for which $^O reports +# "msys"). This is another *nix-emulation/system for MSWindows. At +# present it is treated as unix-like, but the environment variables +# are those of Windows. (The test for USERNAME as well as USER was +# to make latexmk work under MSYS's perl.) +# +if ( $^O eq "MSWin32" ) { +# Pure MSWindows configuration + ## Configuration parameters: + + ## Use first existing case for $tmpdir: + $tmpdir = $ENV{TMPDIR} || $ENV{TEMP} || '.'; + $log_file_binary = 1; # Protect against ctrl/Z in log file from + # Miktex 2.7. + + ## List of possibilities for the system-wide initialization file. + ## The first one found (if any) is used. + @rc_system_files = ( "C:/latexmk/LatexMk", "C:/latexmk/latexmkrc" ); + + $search_path_separator = ';'; # Separator of elements in search_path + + # For a pdf-file, "start x.pdf" starts the pdf viewer associated with + # pdf files, so no program name is needed: + $pdf_previewer = 'start %O %S'; + $ps_previewer = 'start %O %S'; + $ps_previewer_landscape = $ps_previewer; + $dvi_previewer = 'start %O %S'; + $dvi_previewer_landscape = "$dvi_previewer"; + # Viewer update methods: + # 0 => auto update: viewer watches file (e.g., gv) + # 1 => manual update: user must do something: e.g., click on window. + # (e.g., ghostview, MSWIN previewers, acroread under UNIX) + # 2 => send signal. Number of signal in $dvi_update_signal, + # $ps_update_signal, $pdf_update_signal + # 3 => viewer can't update, because it locks the file and the file + # cannot be updated. (acroread under MSWIN) + # 4 => run a command to force the update. The commands are + # specified by the variables $dvi_update_command, + # $ps_update_command, $pdf_update_command + $dvi_update_method = 1; + $ps_update_method = 1; + $pdf_update_method = 3; # acroread locks the pdf file + # Use NONE as flag that I am not implementing some commands: + $lpr = + 'NONE $lpr variable is not configured to allow printing of ps files'; + $lpr_dvi = + 'NONE $lpr_dvi variable is not configured to allow printing of dvi files'; + $lpr_pdf = + 'NONE $lpr_pdf variable is not configured to allow printing of pdf files'; + # The $pscmd below holds a command to list running processes. It + # is used to find the process ID of the viewer looking at the + # current output file. The output of the command must include the + # process number and the command line of the processes, since the + # relevant process is identified by the name of file to be viewed. + # Its use is not essential. + $pscmd = + 'NONE $pscmd variable is not configured to detect running processes'; + $pid_position = -1; # offset of PID in output of pscmd. + # Negative means I cannot use ps +} +elsif ( $^O eq "cygwin" ) { + # The problem is a mixed MSWin32 and UNIX environment. + # Perl decides the OS is cygwin in two situations: + # 1. When latexmk is run from a cygwin shell under a cygwin + # environment. Perl behaves in a UNIX way. This is OK, since + # the user is presumably expecting UNIXy behavior. + # 2. When CYGWIN exectuables are in the path, but latexmk is run + # from a native NT shell. Presumably the user is expecting NT + # behavior. But perl behaves more UNIXy. This causes some + # clashes. + # The issues to handle are: + # 1. Perl sees both MSWin32 and cygwin filenames. This is + # normally only an advantage. + # 2. Perl uses a UNIX shell in the system command + # This is a nasty problem: under native NT, there is a + # start command that knows about NT file associations, so that + # we can do, e.g., (under native NT) system("start file.pdf"); + # But this won't work when perl has decided the OS is cygwin, + # even if it is invoked from a native NT command line. An + # NT command processor must be used to deal with this. + # 3. External executables can be native NT (which only know + # NT-style file names) or cygwin executables (which normally + # know both cygwin UNIX-style file names and NT file names, + # but not always; some do not know about drive names, for + # example). + # Cygwin executables for tex and latex may only know cygwin + # filenames. + # 4. The BIBINPUTS environment variables may be + # UNIX-style or MSWin-style depending on whether native NT or + # cygwin executables are used. They are therefore parsed + # differently. Here is the clash: + # a. If a user is running under an NT shell, is using a + # native NT installation of tex (e.g., fptex or miktex), + # but has the cygwin executables in the path, then perl + # detects the OS as cygwin, but the user needs NT + # behavior from latexmk. + # b. If a user is running under an UNIX shell in a cygwin + # environment, and is using the cygwin installation of + # tex, then perl detects the OS as cygwin, and the user + # needs UNIX behavior from latexmk. + # Latexmk has no way of detecting the difference. The two + # situations may even arise for the same user on the same + # computer simply by changing the order of directories in the + # path environment variable + + + ## Configuration parameters: We'll assume native NT executables. + ## The user should override if they are not. + + # This may fail: perl converts MSWin temp directory name to cygwin + # format. Names containing this string cannot be handled by native + # NT executables. + $tmpdir = $ENV{TMPDIR} || $ENV{TEMP} || '.'; + + ## List of possibilities for the system-wide initialization file. + ## The first one found (if any) is used. + ## We could stay with MSWin files here, since cygwin perl understands them + ## @rc_system_files = ( 'C:/latexmk/LatexMk', 'C:/latexmk/latexmkrc' ); + ## But they are deprecated in v. 1.7. So use the UNIX version, prefixed + ## with a cygwin equivalent of the MSWin location + ## In addition, we need to add the same set of possible locations as with + ## unix, so that the user use a unix-style setup. + @rc_system_files = (); + foreach ( 'LatexMk', 'latexmkrc' ) { + push @rc_system_files, + ( "/cygdrive/c/latexmk/$_", + "/opt/local/share/latexmk/$_", + "/usr/local/share/latexmk/$_", + "/usr/local/lib/latexmk/$_" ); + } + $search_path_separator = ';'; # Separator of elements in search_path + # This is tricky. The search_path_separator depends on the kind + # of executable: native NT v. cygwin. + # So the user will have to override this. + + # We will assume that files can be viewed by native NT programs. + # Then we must fix the start command/directive, so that the + # NT-native start command of a cmd.exe is used. + # For a pdf-file, "start x.pdf" starts the pdf viewer associated with + # pdf files, so no program name is needed: + $start_NT = "cmd /c start \"\""; + $pdf_previewer = "$start_NT %O %S"; + $ps_previewer = "$start_NT %O %S"; + $ps_previewer_landscape = $ps_previewer; + $dvi_previewer = "$start_NT %O %S"; + $dvi_previewer_landscape = $dvi_previewer; + # Viewer update methods: + # 0 => auto update: viewer watches file (e.g., gv) + # 1 => manual update: user must do something: e.g., click on window. + # (e.g., ghostview, MSWIN previewers, acroread under UNIX) + # 2 => send signal. Number of signal in $dvi_update_signal, + # $ps_update_signal, $pdf_update_signal + # 3 => viewer can't update, because it locks the file and the file + # cannot be updated. (acroread under MSWIN) + $dvi_update_method = 1; + $ps_update_method = 1; + $pdf_update_method = 3; # acroread locks the pdf file + # Use NONE as flag that I am not implementing some commands: + $lpr = + 'NONE $lpr variable is not configured to allow printing of ps files'; + $lpr_dvi = + 'NONE $lpr_dvi variable is not configured to allow printing of dvi files'; + $lpr_pdf = + 'NONE $lpr_pdf variable is not configured to allow printing of pdf files'; + # The $pscmd below holds a command to list running processes. It + # is used to find the process ID of the viewer looking at the + # current output file. The output of the command must include the + # process number and the command line of the processes, since the + # relevant process is identified by the name of file to be viewed. + # Its use is not essential. + # When the OS is detected as cygwin, there are two possibilities: + # a. Latexmk was run from an NT prompt, but cygwin is in the + # path. Then the cygwin ps command will not see commands + # started from latexmk. So we cannot use it. + # b. Latexmk was started within a cygwin environment. Then + # the ps command works as we need. + # Only the user, not latemk knows which, so we default to not + # using the ps command. The user can override this in a + # configuration file. + $pscmd = + 'NONE $pscmd variable is not configured to detect running processes'; + $pid_position = -1; # offset of PID in output of pscmd. + # Negative means I cannot use ps +} +else { + # Assume anything else is UNIX or clone + + ## Configuration parameters: + + + ## Use first existing case for $tmpdir: + $tmpdir = $ENV{TMPDIR} || '/tmp'; + + ## List of possibilities for the system-wide initialization file. + ## The first one found (if any) is used. + ## Normally on a UNIX it will be in a subdirectory of /opt/local/share or + ## /usr/local/share, depending on the local conventions. + ## But /usr/local/lib/latexmk is put in the list for + ## compatibility with older versions of latexmk. + @rc_system_files = (); + foreach ( 'LatexMk', 'latexmkrc' ) { + push @rc_system_files, + ( "/opt/local/share/latexmk/$_", + "/usr/local/share/latexmk/$_", + "/usr/local/lib/latexmk/$_" ); + } + $search_path_separator = ':'; # Separator of elements in search_path + + $dvi_update_signal = $signo{USR1} + if ( defined $signo{USR1} ); # Suitable for xdvi + $ps_update_signal = $signo{HUP} + if ( defined $signo{HUP} ); # Suitable for gv + $pdf_update_signal = $signo{HUP} + if ( defined $signo{HUP} ); # Suitable for gv + ## default document processing programs. + # Viewer update methods: + # 0 => auto update: viewer watches file (e.g., gv) + # 1 => manual update: user must do something: e.g., click on window. + # (e.g., ghostview, MSWIN previewers, acroread under UNIX) + # 2 => send signal. Number of signal in $dvi_update_signal, + # $ps_update_signal, $pdf_update_signal + # 3 => viewer can't update, because it locks the file and the file + # cannot be updated. (acroread under MSWIN) + # 4 => Run command to update. Command in $dvi_update_command, + # $ps_update_command, $pdf_update_command. + $dvi_previewer = 'start xdvi %O %S'; + $dvi_previewer_landscape = 'start xdvi -paper usr %O %S'; + if ( defined $dvi_update_signal ) { + $dvi_update_method = 2; # xdvi responds to signal to update + } else { + $dvi_update_method = 1; + } +# if ( defined $ps_update_signal ) { +# $ps_update_method = 2; # gv responds to signal to update +# $ps_previewer = 'start gv -nowatch'; +# $ps_previewer_landscape = 'start gv -swap -nowatch'; +# } else { +# $ps_update_method = 0; # gv -watch watches the ps file +# $ps_previewer = 'start gv -watch'; +# $ps_previewer_landscape = 'start gv -swap -watch'; +# } + # Turn off the fancy options for gv. Regular gv likes -watch etc + # GNU gv likes --watch etc. User must configure + $ps_update_method = 0; # gv -watch watches the ps file + $ps_previewer = 'start gv %O %S'; + $ps_previewer_landscape = 'start gv -swap %O %S'; + $pdf_previewer = 'start acroread %O %S'; + $pdf_update_method = 1; # acroread under unix needs manual update + $lpr = 'lpr %O %S'; # Assume lpr command prints postscript files correctly + $lpr_dvi = + 'NONE $lpr_dvi variable is not configured to allow printing of dvi files'; + $lpr_pdf = + 'NONE $lpr_pdf variable is not configured to allow printing of pdf files'; + # The $pscmd below holds a command to list running processes. It + # is used to find the process ID of the viewer looking at the + # current output file. The output of the command must include the + # process number and the command line of the processes, since the + # relevant process is identified by the name of file to be viewed. + # Uses: + # 1. In preview_continuous mode, to save running a previewer + # when one is already running on the relevant file. + # 2. With xdvi in preview_continuous mode, xdvi must be + # signalled to make it read a new dvi file. + # + # The following works on Solaris, LINUX, HP-UX, IRIX + # Use -f to get full listing, including command line arguments. + # Use -u $ENV{USER} to get all processes started by current user (not just + # those associated with current terminal), but none of other users' + # processes. + # However, the USER environment variable may not exist. Windows uses + # USERNAME instead. (And this propagates to a situation of + # unix-emulation software running under Windows.) + if ( exists $ENV{USER} ) { + $pscmd = "ps -f -u $ENV{USER}"; + } + elsif ( exists $ENV{USERNAME} ) { + $pscmd = "ps -f -u $ENV{USERNAME}"; + } + else { + $pscmd = "ps -f"; + } + $pid_position = 1; # offset of PID in output of pscmd; first item is 0. + if ( $^O eq "linux" ) { + # Ps on Redhat (at least v. 7.2) appears to truncate its output + # at 80 cols, so that a long command string is truncated. + # Fix this with the --width option. This option works under + # other versions of linux even if not necessary (at least + # for SUSE 7.2). + # However the option is not available under other UNIX-type + # systems, e.g., Solaris 8. + # But (19 Aug 2010), the truncation doesn't happen on RHEL4 and 5, + # unless the output is written to a terminal. So the --width + # option is now unnecessary + # $pscmd = "ps --width 200 -f -u $ENV{USER}"; + } + elsif ( $^O eq "darwin" ) { + # OS-X on Macintosh + # open starts command associated with a file. + # For pdf, this is set by default to OS-X's preview, which is suitable. + # Manual update is simply by clicking on window etc, which is OK. + # For ps, this is set also to preview. This works, but since it + # converts the file to pdf and views the pdf file, it doesn't + # see updates, and a refresh cannot be done. This is far from + # optimal. + # For a full installation of MacTeX, which is probably the most common + # on OS-X, an association is created between dvi files and TeXShop. + # This also converts the file to pdf, so again while it works, it + # does not deal with changed dvi files, as far as I can see. + $pdf_previewer = 'open %S'; + $pdf_update_method = 1; # manual + $dvi_previewer = $dvi_previewer_landscape = 'NONE'; + $ps_previewer = $ps_previewer_landscape = 'NONE'; + # Others + $lpr_pdf = 'lpr %O %S'; + $pscmd = "ps -ww -u $ENV{USER}"; + } +} + +## default parameters +$auto_rc_use = 1; # Whether to read rc files automatically +$max_repeat = 5; # Maximum times I repeat latex. Normally + # 3 would be sufficient: 1st run generates aux file, + # 2nd run picks up aux file, and maybe toc, lof which + # contain out-of-date information, e.g., wrong page + # references in toc, lof and index, and unresolved + # references in the middle of lines. But the + # formatting is more-or-less correct. On the 3rd + # run, the page refs etc in toc, lof, etc are about + # correct, but some slight formatting changes may + # occur, which mess up page numbers in the toc and lof, + # Hence a 4th run is conceivably necessary. + # At least one document class (JHEP.cls) works + # in such a way that a 4th run is needed. + # We allow an extra run for safety for a + # maximum of 5. Needing further runs is + # usually an indication of a problem; further + # runs may not resolve the problem, and + # instead could cause an infinite loop. +$clean_ext = ""; # space separated extensions of files that are + # to be deleted when doing cleanup, beyond + # standard set +$clean_full_ext = ""; # space separated extensions of files that are + # to be deleted when doing cleanup_full, beyond + # standard set and those in $clean_ext +@cus_dep_list = (); # Custom dependency list +@default_files = ( '*.tex' ); # Array of LaTeX files to process when + # no files are specified on the command line. + # Wildcards allowed + # Best used for project specific files. +@default_excluded_files = ( ); + # Array of LaTeX files to exclude when using + # @default_files, i.e., when no files are specified + # on the command line. + # Wildcards allowed + # Best used for project specific files. +$texfile_search = ""; # Specification for extra files to search for + # when no files are specified on the command line + # and the @default_files variable is empty. + # Space separated, and wildcards allowed. + # These files are IN ADDITION to *.tex in current + # directory. + # This variable is obsolete, and only in here for + # backward compatibility. + +$fdb_ext = 'fdb_latexmk'; # Extension for the file for latexmk's + # file-database + # Make it long to avoid possible collisions. +$fdb_ver = 3; # Version number for kind of fdb_file. + +$jobname = ''; # Jobname: as with current tex, etc indicates + # basename of generated files. + # Defined so that --jobname=STRING on latexmk's + # command line has same effect as with current + # tex, etc. (If $jobname is non-empty, then + # the --jobname=... option is used on tex.) +$out_dir = ''; # Directory for output files. + # Cf. --output-directory of current (pdf)latex +$aux_dir = ''; # Directory for aux files (log, aux, etc). + # Cf. --aux-directory of current (pdf)latex in MiKTeX. + + +## default flag settings. +$recorder = 1; # Whether to use recorder option on latex/pdflatex +$silent = 0; # Silence latex's messages? +$silence_logfile_warnings = 0; # Do list warnings in log file +$kpsewhich_show = 0; # Show calls to and results from kpsewhich +$landscape_mode = 0; # default to portrait mode +$analyze_input_log_always = 0; # Always analyze .log for input files in the + # <...> and (...) constructions. Otherwise, only + # do the analysis when fls file doesn't exist or is + # out of date. + +# The following two arrays contain lists of extensions (without +# period) for files that are read in during a (pdf)LaTeX run but that +# are generated automatically from the previous run, as opposed to +# being user generated files (directly or indirectly from a custom +# dependency). These files get two kinds of special treatment: +# 1. In clean up, where depending on the kind of clean up, some +# or all of these generated files are deleted. +# (Note that special treatment is given to aux files.) +# 2. In analyzing the results of a run of (pdf)LaTeX, to +# determine if another run is needed. With an error free run, +# a rerun should be provoked by a change in any source file, +# whether a user file or a generated file. But with a run +# that ends in an error, only a change in a user file during +# the run (which might correct the error) should provoke a +# rerun, but a change in a generated file should not. +# These arrays can be user-configured. + +@generated_exts = ( 'aux', 'bcf', 'fls', 'idx', 'ind', 'lof', 'lot', + 'out', 'toc' ); + # N.B. 'out' is generated by hyperref package + +# Which kinds of file do I have requests to make? +# If no requests at all are made, then I will make dvi file +# If particular requests are made then other files may also have to be +# made. E.g., ps file requires a dvi file +$dvi_mode = 0; # No dvi file requested +$postscript_mode = 0; # No postscript file requested +$pdf_mode = 0; # No pdf file requested to be made by pdflatex + # Possible values: + # 0 don't create pdf file + # 1 to create pdf file by pdflatex + # 2 to create pdf file by ps2pdf + # 3 to create pdf file by dvipdf + # 4 to create pdf file by lualatex + # 5 to create pdf file by xelatex + xdvipdfmx +$view = 'default'; # Default preview is of highest of dvi, ps, pdf +$sleep_time = 2; # time to sleep b/w checks for file changes in -pvc mode +$banner = 0; # Non-zero if we have a banner to insert +$banner_scale = 220; # Original default scale +$banner_intensity = 0.95; # Darkness of the banner message +$banner_message = 'DRAFT'; # Original default message +$do_cd = 0; # Do not do cd to directory of source file. + # Thus behave like latex. +$dependents_list = 0; # Whether to display list(s) of dependencies +$dependents_phony = 0; # Whether list(s) of dependencies includes phony targets + # (as with 'gcc -MP'). +$deps_file = '-'; # File for dependency list output. Default stdout. +$rules_list = 0; # Whether to display list(s) of dependencies +@dir_stack = (); # Stack of pushed directories, each of form of + # pointer to array [ cwd, good_cwd ], where + # good_cwd differs from cwd by being converted + # to native MSWin path when cygwin is used. +$cleanup_mode = 0; # No cleanup of nonessential LaTex-related files. + # $cleanup_mode = 0: no cleanup + # $cleanup_mode = 1: full cleanup + # $cleanup_mode = 2: cleanup except for dvi, + # dviF, pdf, ps, psF & xdv +$cleanup_fdb = 0; # No removal of file for latexmk's file-database +$cleanup_only = 0; # When doing cleanup, do not go on to making files +$cleanup_includes_generated = 0; + # Determines whether cleanup deletes files generated by + # custom dependencies +$cleanup_includes_cusdep_generated = 0; + # Determines whether cleanup deletes files generated by + # (pdf)latex (found from \openout lines in log file). +$diagnostics = 0; +$dvi_filter = ''; # DVI filter command +$ps_filter = ''; # Postscript filter command + +$force_mode = 0; # =1 to force processing past errors +$go_mode = 0; # =1 to force processing regardless of time-stamps + # =2 full clean-up first +$preview_mode = 0; +$preview_continuous_mode = 0; +$printout_mode = 0; # Don't print the file + +$show_time = 0; +@timings = (); +$processing_time1 = processing_time(); + +$use_make_for_missing_files = 0; # Whether to use make to try to make missing files. + +# Do we make view file in temporary then move to final destination? +# (To avoid premature updating by viewer). +$always_view_file_via_temporary = 0; # Set to 1 if viewed file is always + # made through a temporary. +$pvc_view_file_via_temporary = 1; # Set to 1 if only in -pvc mode is viewed + # file made through a temporary. + +# State variables initialized here: + +$updated = 0; # Flags when something has been remade + # Used to allow convenient user message in -pvc mode +$waiting = 0; # Flags whether we are in loop waiting for an event + # Used to avoid unnecessary repeated o/p in wait loop + +# Used for some results of parsing log file: +$reference_changed = 0; +$mult_defined = 0; +$bad_reference = 0; +$bad_citation = 0; + +# Cache of expensive-to-compute state variables, e.g., cwd in form +# fixed to deal with cygwin issues. +%cache = (); +&cache_good_cwd; + +# Set search paths for includes. +# Set them early so that they can be overridden +$BIBINPUTS = $ENV{'BIBINPUTS'}; +if (!$BIBINPUTS) { $BIBINPUTS = '.'; } + +# Convert search paths to arrays: +# If any of the paths end in '//' then recursively search the +# directory. After these operations, @BIBINPUTS should +# have all the directories that need to be searched + +@BIBINPUTS = find_dirs1( $BIBINPUTS ); + + +###################################################################### +###################################################################### +# +# ??? UPDATE THE FOLLOWING!! +# +# We will need to determine whether source files for runs of various +# programs are out of date. In a normal situation, this is done by +# asking whether the times of the source files are later than the +# destination files. But this won't work for us, since a common +# situation is that a file is written on one run of latex, for +# example, and read back in on the next run (e.g., an .aux file). +# Some situations of this kind are standard in latex generally; others +# occur with particular macro packages or with particular +# postprocessors. +# +# The correct criterion for whether a source is out-of-date is +# therefore NOT that its modification time is later than the +# destination file, but whether the contents of the source file have +# changed since the last successful run. This also handles the case +# that the user undoes some changes to a source file by replacing the +# source file by reverting to an earlier version, which may well have +# an older time stamp. Since a direct comparison of old and new files +# would involve storage and access of a large number of backup files, +# we instead use the md5 signature of the files. (Previous versions +# of latexmk used the backup file method, but restricted to the case +# of .aux and .idx files, sufficient for most, but not all, +# situations.) +# +# We will have a database of (time, size, md5) for the relevant +# files. If the time and size of a file haven't changed, then the file +# is assumed not to have changed; this saves us from having to +# determine its md5 signature, which would involve reading the whole +# file, which is naturally time-consuming, especially if network file +# access to a server is needed, and many files are involved, when most +# of them don't change. It is of course possible to change a file +# without changing its size, but then to adjust its timestamp +# to what it was previously; this requires a certain amount of +# perversity. We can safely assume that if the user edits a file or +# changes its contents, then the file's timestamp changes. The +# interesting case is that the timestamp does change, because the file +# has actually been written to, but that the contents do not change; +# it is for this that we use the md5 signature. However, since +# computing the md5 signature involves reading the whole file, which +# may be large, we should avoid computing it more than necessary. +# +# So we get the following structure: +# +# 1. For each relevant run (latex, pdflatex, each instance of a +# custom dependency) we have a database of the state of the +# source files that were last used by the run. +# 2. On an initial startup, the database for a primary tex file +# is read that was created by a previous run of latex or +# pdflatex, if this exists. +# 3. If the file doesn't exist, then the criterion for +# out-of-dateness for an initial run is that it goes by file +# timestamps, as in previous versions of latexmk, with due +# (dis)regard to those files that are known to be generated by +# latex and re-read on the next run. +# 4. Immediately before a run, the database is updated to +# represent the current conditions of the run's source files. +# 5. After the run, it is determined whether any of the source +# files have changed. This covers both files written by the +# run, which are therefore in a dependency loop, and files that +# the user may have updated during the run. (The last often +# happens when latex takes a long time, for a big document, +# and the user makes edits before latex has finished. This is +# particularly prevalent when latexmk is used with +# preview-continuous mode.) +# 6. In the case of latex or pdflatex, the custom dependencies +# must also be checked and redone if out-of-date. +# 7. If any source files have changed, the run is redone, +# starting at step 1. +# 8. There is naturally a limit on the number of reruns, to avoid +# infinite loops from bugs and from pathological or unforeseen +# conditions. +# 9. After the run is done, the run's file database is updated. +# (By hypothesis, the sizes and md5s are correct, if the run +# is successful.) +# 10. To allow reuse of data from previous runs, the file database +# is written to a file after every complete set of passes +# through latex or pdflatex. (Note that there is separate +# information for latex and pdflatex; the necessary +# information won't coincide: Out-of-dateness for the files +# for each program concerns the properties of the files when +# the other program was run, and the set of source files could +# be different, e.g., for graphics files.) +# +# We therefore maintain the following data structures.: +# +# a. For each run (latex, pdflatex, each custom dependency) a +# database is maintained. This is a hash from filenames to a +# reference to an array: [time, size, md5]. The semantics of +# the database is that it represents the state of the source +# files used in the run. During a run it represents the state +# immediately before the run; after a run, with all reruns, it +# represents the state of the files used, modified by having +# the latest timestamps for generated files. +# b. There is a global database for all files, which represents +# the current state. This saves having to recompute the md5 +# signatures of a changed file used in more than one run +# (e.g., latex and pdflatex). +# c. Each of latex and pdflatex has a list of the relevant custom +# dependencies. +# +# In all the following a fdb-hash is a hash of the form: +# filename -> [time, size, md5] +# If a file is found to disappear, its entry is removed from the hash. +# In returns from fdb access routines, a size entry of -1 indicates a +# non-existent file. + + +# List of known rules. Rule types: primary, +# external (calls program), internal (calls routine), cusdep. + +%possible_primaries = ( 'latex' => 'primary', 'pdflatex' => 'primary', + 'lualatex' => 'primary', 'xelatex' => 'primary' ); +%primaries = (); # Hash of rules for primary part of make. Keys are + # currently 'latex', 'pdflatex' or both; also 'lualatex' + # and 'xelatex'. Value is currently irrelevant. + # Use hash for ease of lookup + # Make remove this later, if use rdb_makeB + +# Hashes, whose keys give names of particular kinds of rule. We use +# hashes for ease of lookup. +%possible_one_time = ( 'view' => 1, 'print' => 1, 'update_view' => 1, ); +%requested_filerules = (); # Hash for rules corresponding to requested files. + # The keys are the rulenames and the value is + # currently irrelevant. +%one_time = (); # Hash for requested one-time-only rules, currently + # possible values 'print' and 'view'. + + +%rule_db = (); # Database of all rules: + # Hash: rulename -> [array of rule data] + # Rule data: + # 0: [ cmd_type, ext_cmd, int_cmd, test_kind, + # source, dest, base, + # out_of_date, out_of_date_user, + # time_of_last_run, time_of_last_file_check, + # changed + # last_result, last_message, + # default_extra_generated + # ] + # where + # cmd_type is 'primary', 'external', or 'cusdep' + # ext_cmd is string for associated external command + # with substitutions (%D for destination, %S + # for source, %B for base of current rule, + # %R for base of primary tex file, %T for + # texfile name, %O for options, + # %Y for $aux_dir1, and %Z for $out_dir1 + # int_cmd specifies any internal command to be + # used to implement the application of the + # rule. If this is present, it overrides + # the external command, and it is the + # responsibility of the perl subroutine + # specified in intcmd to execute the + # external command if this is appropriate. + # This variable intcmd is a reference to an array, + # $$intcmd[0] = internal routine + # $$intcmd[1...] = its arguments (if any) + # test_kind specifies method of determining + # whether a file is out-of-date: + # 0 for never + # 1 for usual: whether there is a source + # file change + # 2 for dest earlier than source + # 3 for method 2 at first run, 1 thereafter + # (used when don't have file data from + # previous run). + # source = name of primary source file, if any + # dest = name of primary destination file, + # if any + # base = base name, if any, of files for + # this rule + # out_of_date = 1 if it has been detected that + # this rule needs to be run + # (typically because a source + # file has changed). + # 0 otherwise + # out_of_date_user is like out_of_date, except + # that the detection of out-of-dateness + # has been made from a change of a + # putative user file, i.e., one that is + # not a generated file (e.g., aux). This + # kind of out-of-dateness should provoke a + # rerun whether or not there was an error + # during a run of (pdf)LaTeX. Normally, + # if there is an error, one should wait + # for the user to correct the error. But + # it is possible the error condition is + # already corrected during the run, e.g., + # by the user changing a source file in + # response to an error message. + # time_of_last_run = time that this rule was + # last applied. (In standard units + # from perl, to be directly compared + # with file modification times.) + # time_of_last_file_check = last time that a check + # was made for changes in source files. + # changed flags whether special changes have been made + # that require file-existence status to be ignored + # last_result is + # -1 if no run has been made, + # 0 if the last run was successful + # 1 if last run was successful, but + # failed to create an output file + # 2 if last run failed + # 200 if last run gave a warning that is + # important enough to be reported with + # the error summary. The warning + # message is stored in last_message. + # last_message is error message for last run + # default_extra_generated is a reference to an array + # of specifications of extra generated files (beyond + # the main dest file. Standard place holders are used. + # Example ['%Y%R.log'] for (pdf)latex, and ['%R.blg'] + # for bibtex. (There's no need for '%R.aux', here, + # since such generated files are detected dynamically.) + # 1: {Hash sourcefile -> [source-file data] } + # Source-file data array: + # 0: time + # 1: size + # 2: md5 + # 3: name of rule to make this file + # 4: whether the file is of the kind made by epstopdf.sty + # during a primary run. It will have been read during + # the run, so that even though the file changes during + # a primary run, there is no need to trigger another + # run because of this. + # Size and md5 correspond to the values at the last run. + # But time may be updated to correspond to the time + # for the file, if the file is otherwise unchanged. + # This saves excessive md5 calculations, which would + # otherwise be done everytime the file is checked, + # in the following situation: + # When the file has been rewritten after a run + # has started (commonly aux, bbl files etc), + # but the actual file contents haven't + # changed. Then because the filetime has + # changed, on every file-change check latexmk + # would normally redo the md5 calculation to + # test for actual changes. Once one such + # check is done, and the contents are + # unchanged, later checks are superfluous, and + # can be avoided by changing the file's time + # in the source-file list. + # 2: {Hash generated_file -> 1 } + # This lists all generated files; the values + # are currently unused, only the keys + +%fdb_current = (); # Fdb-hash for all files used. + + +# User's home directory +$HOME = ''; +if (exists $ENV{'HOME'} ) { + $HOME = $ENV{'HOME'}; +} +elsif (exists $ENV{'USERPROFILE'} ) { + $HOME = $ENV{'USERPROFILE'}; +} +# XDG configuration home +$XDG_CONFIG_HOME = ''; +if (exists $ENV{'XDG_CONFIG_HOME'} ) { + $XDG_CONFIG_HOME = $ENV{'XDG_CONFIG_HOME'}; +} +elsif ($HOME ne '') { + if ( -d "$HOME/.config") { + $XDG_CONFIG_HOME = "$HOME/.config"; + } +} + + +#================================================== + +# Options that are to be obeyed before rc files are read: + +foreach $_ ( @ARGV ) +{ + if (/^-{1,2}norc$/ ) { + $auto_rc_use = 0; + } +} + +#================================================== +## Read rc files with this subroutine + +sub read_first_rc_file_in_list { + foreach my $rc_file ( @_ ) { + #print "===Testing for rc file \"$rc_file\" ...\n"; + if ( -d $rc_file ) { + warn "$My_name: I have found a DIRECTORY named \"$rc_file\".\n", + " Have you perhaps misunderstood latexmk's documentation?\n", + " This name is normally used for a latexmk configuration (rc) file,\n", + " and in that case it should be a regular text file, not a directory.\n"; + } + elsif ( -e $rc_file ) { + #print "===Reading rc file \"$rc_file\" ...\n"; + process_rc_file( $rc_file ); + return; + } + } +} + +# Note that each rc file may unset $auto_rc_use to +# prevent lower-level rc files from being read. +# So test on $auto_rc_use in each case. +if ( $auto_rc_use ) { + # System rc file: + read_first_rc_file_in_list( @rc_system_files ); +} +if ( $auto_rc_use && ($HOME ne "" ) ) { + # User rc file: + @user_rc = (); + if ( $XDG_CONFIG_HOME ) { + push @user_rc, "$XDG_CONFIG_HOME/latexmk/latexmkrc"; + } + # N.B. $HOME equals "" if latexmk couldn't determine a home directory. + # In that case, we shouldn't look for an rc file there. + if ( $HOME ) { + push @user_rc, "$HOME/.latexmkrc"; + } + read_first_rc_file_in_list( @user_rc ); +} +if ( $auto_rc_use ) { + # Rc file in current directory: + read_first_rc_file_in_list( "latexmkrc", ".latexmkrc" ); +} + +## Process command line args. +@command_line_file_list = (); +$bad_options = 0; + +while ($_ = $ARGV[0]) +{ + # Make -- and - equivalent at beginning of option, + # but save original for possible use in (pdf)latex command line + $original = $_; + s/^--/-/; + shift; + if ( /^-aux-directory=(.*)$/ || /^-auxdir=(.*)$/ ) { + $aux_dir = $1; + } + elsif (/^-bibtex$/) { $bibtex_use = 2; } + elsif (/^-bibtex-$/) { $bibtex_use = 0; } + elsif (/^-nobibtex$/) { $bibtex_use = 0; } + elsif (/^-bibtex-cond$/) { $bibtex_use = 1; } + elsif (/^-c$/) { $cleanup_mode = 2; $cleanup_fdb = 1; $cleanup_only = 1; } + elsif (/^-C$/ || /^-CA$/ ) { $cleanup_mode = 1; $cleanup_fdb = 1; $cleanup_only = 1; } + elsif (/^-CF$/) { $cleanup_fdb = 1; } + elsif (/^-cd$/) { $do_cd = 1; } + elsif (/^-cd-$/) { $do_cd = 0; } + elsif (/^-commands$/) { &print_commands; exit; } + elsif (/^-d$/) { $banner = 1; } + elsif (/^-dependents$/ || /^-deps$/ || /^-M$/ ) { $dependents_list = 1; } + elsif (/^-nodependents$/ || /^-dependents-$/ || /^-deps-$/) { $dependents_list = 0; } + elsif (/^-deps-out=(.*)$/) { + $deps_file = $1; + $dependents_list = 1; + } + elsif (/^-diagnostics/) { $diagnostics = 1; } + elsif (/^-dvi$/) { $dvi_mode = 1; } + elsif (/^-dvi-$/) { $dvi_mode = 0; } + elsif (/^-f$/) { $force_mode = 1; } + elsif (/^-f-$/) { $force_mode = 0; } + elsif (/^-g$/) { $go_mode = 1; } + elsif (/^-g-$/) { $go_mode = 0; } + elsif (/^-gg$/) { + $go_mode = 2; $cleanup_mode = 1; $cleanup_fdb = 1; $cleanup_only = 0; + } + elsif ( /^-h$/ || /^-help$/ ) { &print_help; exit;} + elsif (/^-jobname=(.*)$/) { + $jobname = $1; + } + elsif (/^-l$/) { $landscape_mode = 1; } + elsif (/^-l-$/) { $landscape_mode = 0; } + elsif (/^-latex=(.*)$/) { + $latex = $1; + } + elsif (/^-latexoption=(.*)$/) { + push @extra_latex_options, $1; + push @extra_pdflatex_options, $1; + push @extra_lualatex_options, $1; + push @extra_xelatex_options, $1; + } + elsif ( /^-logfilewarninglist$/ || /^-logfilewarnings$/ ) + { $silence_logfile_warnings = 0; } + elsif ( /^-logfilewarninglist-$/ || /^-logfilewarnings-$/ ) + { $silence_logfile_warnings = 1; } +# See above for -M + elsif (/^-MF$/) { + if ( $ARGV[0] eq '' ) { + &exit_help( "No file name specified after -MF switch"); + } + $deps_file = $ARGV[0]; + shift; + } + elsif ( /^-MP$/ ) { $dependents_phony = 1; } + elsif (/^-new-viewer$/) { + $new_viewer_always = 1; + } + elsif (/^-new-viewer-$/) { + $new_viewer_always = 0; + } + elsif (/^-norc$/ ) { + $auto_rc_use = 0; + # N.B. This has already been obeyed. + } + elsif ( /^-output-directory=(.*)$/ ||/^-outdir=(.*)$/ ) { + $out_dir = $1; + } + elsif (/^-p$/) { $printout_mode = 1; + $preview_continuous_mode = 0; # to avoid conflicts + $preview_mode = 0; + } + elsif (/^-p-$/) { $printout_mode = 0; } + elsif (/^-pdf$/) { $pdf_mode = 1; } + elsif (/^-pdf-$/) { $pdf_mode = 0; } + elsif (/^-pdfdvi$/){ $pdf_mode = 3; } + elsif (/^-pdflua$/){ $pdf_mode = 4; } + elsif (/^-pdfxe$/) { $pdf_mode = 5; } +# elsif (/^-pdflatex$/) { +# $pdflatex = "pdflatex %O %S"; +# $pdf_mode = 1; +# $dvi_mode = $postscript_mode = 0; +# } + elsif (/^-pdflatex=(.*)$/) { + $pdflatex = $1; + } + elsif (/^-pdfps$/) { $pdf_mode = 2; } + elsif (/^-print=(.*)$/) { + $value = $1; + if ( $value =~ /^dvi$|^ps$|^pdf$|^auto$/ ) { + $print_type = $value; + $printout_mode = 1; + } + else { + &exit_help("$My_name: unknown print type '$value' in option '$_'"); + } + } + elsif (/^-ps$/) { $postscript_mode = 1; } + elsif (/^-ps-$/) { $postscript_mode = 0; } + elsif (/^-pv$/) { $preview_mode = 1; + $preview_continuous_mode = 0; # to avoid conflicts + $printout_mode = 0; + } + elsif (/^-pv-$/) { $preview_mode = 0; } + elsif (/^-pvc$/) { $preview_continuous_mode = 1; + $force_mode = 0; # So that errors do not cause loops + $preview_mode = 0; # to avoid conflicts + $printout_mode = 0; + } + elsif (/^-pvc-$/) { $preview_continuous_mode = 0; } + elsif (/^-recorder$/ ){ $recorder = 1; } + elsif (/^-recorder-$/ ){ $recorder = 0; } + elsif (/^-rules$/ ) { $rules_list = 1; } + elsif (/^-norules$/ || /^-rules-$/ ) { $rules_list = 0; } + elsif (/^-showextraoptions$/) { + print "List of extra latex and pdflatex options recognized by $my_name.\n", + "These are passed as is to (pdf)latex. They may not be recognized by\n", + "particular versions of (pdf)latex. This list is a combination of those\n", + "for TeXLive and MikTeX.\n", + "\n", + "Note that in addition to the options in this list, there are several\n", + "options known to the (pdf)latex programs that are also recognized by\n", + "latexmk and trigger special behavior by latexmk. Since these options\n", + "appear in the main list given by running 'latexmk --help', they do not\n", + "appear in the following list\n", + "NOTE ALSO: Not all of these options are supported by all versions of (pdf)latex.\n", + "\n"; + foreach $option ( sort( keys %allowed_latex_options, keys %allowed_latex_options_with_arg ) ) { + if (exists $allowed_latex_options{$option} ) { print " $allowed_latex_options{$option}\n"; } + if (exists $allowed_latex_options_with_arg{$option} ) { print " $allowed_latex_options_with_arg{$option}\n"; } + } + exit; + } + elsif (/^-silent$/ || /^-quiet$/ ){ $silent = 1; } + elsif (/^-time$/) { $show_time = 1;} + elsif (/^-time-$/) { $show_time = 0;} + elsif (/^-use-make$/) { $use_make_for_missing_files = 1; } + elsif (/^-use-make-$/) { $use_make_for_missing_files = 0; } + elsif (/^-v$/ || /^-version$/) { + print "\n$version_details. Version $version_num\n"; + exit; + } + elsif (/^-verbose$/) { $silent = 0; } + elsif (/^-view=default$/) { $view = "default";} + elsif (/^-view=dvi$/) { $view = "dvi";} + elsif (/^-view=none$/) { $view = "none";} + elsif (/^-view=ps$/) { $view = "ps";} + elsif (/^-view=pdf$/) { $view = "pdf"; } + elsif (/^-lualatex$/) { + $pdf_mode = 4; + $dvi_mode = $postscript_mode = 0; + } + elsif (/^-xelatex$/) { + $pdf_mode = 5; + $dvi_mode = $postscript_mode = 0; + } + elsif (/^-e$/) { + if ( $#ARGV < 0 ) { + &exit_help( "No code to execute specified after -e switch"); + } + execute_code_string( $ARGV[0] ); + shift; + } + elsif (/^-r$/) { + if ( $ARGV[0] eq '' ) { + &exit_help( "No RC file specified after -r switch"); + } + if ( -e $ARGV[0] ) { + process_rc_file( $ARGV[0] ); + } + else { + die "$My_name: RC file [$ARGV[0]] does not exist\n"; + } + shift; + } + elsif (/^-bm$/) { + if ( $ARGV[0] eq '' ) { + &exit_help( "No message specified after -bm switch"); + } + $banner = 1; $banner_message = $ARGV[0]; + shift; + } + elsif (/^-bi$/) { + if ( $ARGV[0] eq '' ) { + &exit_help( "No intensity specified after -bi switch"); + } + $banner_intensity = $ARGV[0]; + shift; + } + elsif (/^-bs$/) { + if ( $ARGV[0] eq '' ) { + &exit_help( "No scale specified after -bs switch"); + } + $banner_scale = $ARGV[0]; + shift; + } + elsif (/^-dF$/) { + if ( $ARGV[0] eq '' ) { + &exit_help( "No dvi filter specified after -dF switch"); + } + $dvi_filter = $ARGV[0]; + shift; + } + elsif (/^-pF$/) { + if ( $ARGV[0] eq '' ) { + &exit_help( "No ps filter specified after -pF switch"); + } + $ps_filter = $ARGV[0]; + shift; + } + elsif ( ( exists( $allowed_latex_options{$_} ) ) + || ( /^(-.+)=/ && exists( $allowed_latex_options_with_arg{$1} ) ) + ) + { + push @extra_latex_options, $original; + push @extra_pdflatex_options, $original; + push @extra_lualatex_options, $original; + push @extra_xelatex_options, $original; + } + elsif (/^-/) { + warn "$My_name: $_ bad option\n"; + $bad_options++; + } + else { + push @command_line_file_list, $_ ; + } +} + +if ( $bad_options > 0 ) { + &exit_help( "Bad options specified" ); +} + +warn "$My_name: This is $version_details, version: $version_num.\n", + unless $silent; + +if ( ($out_dir ne '') && ($aux_dir eq '') ){ + $aux_dir = $out_dir; +} + +# Versions terminating in directory/path separator +$out_dir1 = $out_dir; +$aux_dir1 = $aux_dir; +foreach ( $aux_dir1, $out_dir1 ) { + if ( ($_ ne '') && ! m([\\/\:]$) ) { + $_ .= '/'; + } +} + +# At least one widely package (revtex4-1) generates a bib file +# (which is used in revtex4-1 for putting footnotes in the reference +# list), and bibtex must be run to use it. But latexmk needs to +# determine the existence of the bib file by use of kpsewhich, otherwise +# there is an error. So cope with this situation (and any analogous +# cases by adding the aux_dir to the relevant path search environment +# variables. BIBINPUTS seems to be the only one currently affected. +foreach ( 'BIBINPUTS' ) { + if ( exists $ENV{$_} ) { + $ENV{$_} = $aux_dir.$search_path_separator.$ENV{$_}; + } + else { + $ENV{$_} = $aux_dir.$search_path_separator; + } +} + + +if ($bibtex_use > 1) { + push @generated_exts, 'bbl'; +} + +# For backward compatibility, convert $texfile_search to @default_files +# Since $texfile_search is initialized to "", a nonzero value indicates +# that an initialization file has set it. +if ( $texfile_search ne "" ) { + @default_files = split /\s+/, "*.tex $texfile_search"; +} + +#Glob the filenames command line if the script was not invoked under a +# UNIX-like environment. +# Cases: (1) MS/MSwin native Glob +# (OS detected as MSWin32) +# (2) MS/MSwin cygwin Glob [because we do not know whether +# the cmd interpreter is UNIXy (and does glob) or is +# native MS-Win (and does not glob).] +# (OS detected as cygwin) +# (3) UNIX Don't glob (cmd interpreter does it) +# (Currently, I assume this is everything else) +if ( ($^O eq "MSWin32") || ($^O eq "cygwin") ) { + # Preserve ordering of files + @file_list = glob_list1(@command_line_file_list); +#print "A1:File list:\n"; +#for ($i = 0; $i <= $#file_list; $i++ ) { print "$i: '$file_list[$i]'\n"; } +} +else { + @file_list = @command_line_file_list; +} +@file_list = uniq1( @file_list ); + + +# Check we haven't selected mutually exclusive modes. +# Note that -c overrides all other options, but doesn't cause +# an error if they are selected. +if (($printout_mode && ( $preview_mode || $preview_continuous_mode )) + || ( $preview_mode && $preview_continuous_mode )) +{ + # Each of the options -p, -pv, -pvc turns the other off. + # So the only reason to arrive here is an incorrect inititalization + # file, or a bug. + &exit_help( "Conflicting options (print, preview, preview_continuous) selected"); +} + +if ( @command_line_file_list ) { + # At least one file specified on command line (before possible globbing). + if ( !@file_list ) { + &exit_help( "Wildcards in file names didn't match any files"); + } +} +else { + # No files specified on command line, try and find some + # Evaluate in order specified. The user may have some special + # for wanting processing in a particular order, especially + # if there are no wild cards. + # Preserve ordering of files + my @file_list1 = uniq1( glob_list1(@default_files) ); + my @excluded_file_list = uniq1( glob_list1(@default_excluded_files) ); + # Make hash of excluded files, for easy checking: + my %excl = (); + foreach my $file (@excluded_file_list) { + $excl{$file} = ''; + } + foreach my $file (@file_list1) { + push( @file_list, $file) unless ( exists $excl{$file} ); + } + if ( !@file_list ) { + &exit_help( "No file name specified, and I couldn't find any"); + } +} + +$num_files = $#file_list + 1; +$num_specified = $#command_line_file_list + 1; + +#print "Command line file list:\n"; +#for ($i = 0; $i <= $#command_line_file_list; $i++ ) { print "$i: '$command_line_file_list[$i]'\n"; } +#print "File list:\n"; +#for ($i = 0; $i <= $#file_list; $i++ ) { print "$i: '$file_list[$i]'\n"; } + + +# If selected a preview-continuous mode, make sure exactly one filename was specified +if ($preview_continuous_mode && ($num_files != 1) ) { + if ($num_specified > 1) { + &exit_help( + "Need to specify exactly one filename for ". + "preview-continuous mode\n". + " but $num_specified were specified" + ); + } + elsif ($num_specified == 1) { + &exit_help( + "Need to specify exactly one filename for ". + "preview-continuous mode\n". + " but wildcarding produced $num_files files" + ); + } + else { + &exit_help( + "Need to specify exactly one filename for ". + "preview-continuous mode.\n". + " Since none were specified on the command line, I looked for \n". + " files in '@default_files'.\n". + " But I found $num_files files, not 1." + ); + } +} + +# If selected jobname, can only apply that to one file: +if ( ($jobname ne '') && ($num_files > 1) ) { + &exit_help( + "Need to specify at most one filename if ". + "jobname specified, \n". + " but $num_files were found (after defaults and wildcarding)." + ); +} + + +# Normalize the commands, to have place-holders for source, dest etc: +&fix_cmds; + +# Add common options +add_option( $latex_default_switches, \$latex ); +add_option( $pdflatex_default_switches, \$pdflatex ); +add_option( $lualatex_default_switches, \$lualatex ); +add_option( $xelatex_default_switches, \$xelatex ); + +foreach (@extra_latex_options) { add_option( $_, \$latex ); } +foreach (@extra_pdflatex_options) { add_option( $_, \$pdflatex ); } +foreach (@extra_lualatex_options) { add_option( $_, \$lualatex ); } +foreach (@extra_xelatex_options) { add_option( $_, \$xelatex ); } + + +# If landscape mode, change dvips processor, and the previewers: +if ( $landscape_mode ) +{ + $dvips = $dvips_landscape; + $dvi_previewer = $dvi_previewer_landscape; + $ps_previewer = $ps_previewer_landscape; +} + +if ( $silent ) { + add_option( "$latex_silent_switch", \$latex ); + add_option( "$pdflatex_silent_switch", \$pdflatex ); + add_option( "$lualatex_silent_switch", \$lualatex ); + add_option( "$xelatex_silent_switch", \$xelatex ); + add_option( "$biber_silent_switch", \$biber ); + add_option( "$bibtex_silent_switch", \$bibtex ); + add_option( "$makeindex_silent_switch", \$makeindex ); + add_option( "$dvipdf_silent_switch", \$dvipdf ); + add_option( "$dvips_silent_switch", \$dvips ); + add_option( "$xdvipdfmx_silent_switch", \$xdvipdfmx ); +} + +if ( $recorder ) { + add_option( "-recorder", \$latex, \$pdflatex, \$lualatex, \$xelatex ); +} + +# If the output and/or aux directories are specified, fix the (pdf)latex +# commands to use them. +# N.B. We'll ensure that the directories actually exist only after a +# possible cd to the document directory, since the directories can be +# relative to the document. + +if ( $out_dir ) { + add_option( "-output-directory=\"$out_dir\"", + \$latex, \$pdflatex, \$lualatex, \$xelatex ); +} +if ( $aux_dir && ($aux_dir ne $out_dir) ) { + # N.B. If $aux_dir and $out_dir are the same, then the -output-directory + # option is sufficient, especially because the -aux-directory exists + # only in MiKTeX, not in TeXLive. + add_option( "-aux-directory=\"$aux_dir\"", + \$latex, \$pdflatex, \$lualatex, \$xelatex ); +} + +if ( $jobname ne '' ) { + $jobstring = "--jobname=\"$jobname\""; + add_option( "$jobstring", \$latex, \$lualatex, \$pdflatex, \$xelatex ); +} + +# Which kind of file do we preview? +if ( $view eq "default" ) { + # If default viewer requested, use "highest" of dvi, ps and pdf + # that was requested by user. + # No explicit request means view dvi. + $view = "dvi"; + if ( $postscript_mode ) { $view = "ps"; } + if ( $pdf_mode ) { $view = "pdf"; } +} + +# Make sure we make the kind of file we want to view: +if ($view eq 'dvi') { $dvi_mode = 1; } +if ($view eq 'ps') { $postscript_mode = 1; } +if ( ($view eq 'pdf') && ($pdf_mode == 0) ) { + $pdf_mode = 1; +} + +# Make sure that we make something if all requests are turned off +if ( ! ( $dvi_mode || $pdf_mode || $postscript_mode || $printout_mode) ) { + print "No specific requests made, so default to dvi by latex\n"; + $dvi_mode = 1; +} + +# Set new-style requested rules: +if ( $dvi_mode ) { $requested_filerules{'latex'} = 1; } +if ( $pdf_mode == 1 ) { $requested_filerules{'pdflatex'} = 1; } +elsif ( $pdf_mode == 2 ) { + $requested_filerules{'latex'} = 1; + $requested_filerules{'dvips'} = 1; + $requested_filerules{'ps2pdf'} = 1; +} +elsif ( $pdf_mode == 3 ) { + $requested_filerules{'latex'} = 1; + $requested_filerules{'dvipdf'} = 1; +} +elsif ( $pdf_mode == 4 ) { + $requested_filerules{'lualatex'} = 1; +} +elsif ( $pdf_mode == 5 ) { + $requested_filerules{'xelatex'} = 1; + $requested_filerules{'xdvipdfmx'} = 1; +} +if ( $postscript_mode ) { + $requested_filerules{'latex'} = 1; + $requested_filerules{'dvips'} = 1; +} +if ($print_type eq 'auto') { + if ( $postscript_mode ) { $print_type = 'ps'; } + elsif ( $pdf_mode ) { $print_type = 'pdf'; } + elsif ( $dvi_mode ) { $print_type = 'dvi'; } + else { $print_type = 'none'; } +} +if ( $printout_mode ) { + $one_time{'print'} = 1; + if ($print_type eq 'none'){ + warn "$My_name: You have requested printout, but \$print_type is set to 'none'\n"; + } +} +if ( $preview_continuous_mode || $preview_mode ) { $one_time{'view'} = 1; } +if ( length($dvi_filter) != 0 ) { $requested_filerules{'dvi_filter'} = 1; } +if ( length($ps_filter) != 0 ) { $requested_filerules{'ps_filter'} = 1; } +if ( $banner ) { $requested_filerules{'dvips'} = 1; } + + +if ( $pdf_mode == 2 ) { + # We generate pdf from ps. Make sure we have the correct kind of ps. + add_option( "$dvips_pdf_switch", \$dvips ); +} + +# Note sleep has granularity of 1 second. +# Sleep periods 0 < $sleep_time < 1 give zero delay, +# which is probably not what the user intended. +# Sleep periods less than zero give infinite delay +if ( $sleep_time < 0 ) { + warn "$My_name: Correcting negative sleep_time to 1 sec.\n"; + $sleep_time = 1; +} +elsif ( ($sleep_time < 1) && ( $sleep_time != 0 ) ) { + warn "$My_name: Correcting nonzero sleep_time of less than 1 sec to 1 sec.\n"; + $sleep_time = 1; +} +elsif ( $sleep_time == 0 ) { + warn "$My_name: sleep_time was configured to zero.\n", + " Do you really want to do this? It will give 100% CPU usage.\n"; +} + +# Make convenient forms for lookup. +# Extensions always have period. + +# Convert @generated_exts to a hash for ease of look up and deletion +# Keep extension without period! +%generated_exts_all = (); +foreach (@generated_exts ) { + $generated_exts_all{$_} = 1; +} + +if ($aux_dir) { + # Ensure $aux_dir is in TEXINPUTS search path. + # This is used by dvips for files generated by mpost. + if ( ! exists $ENV{TEXINPUTS} ) { + # Note the trailing ":" which ensures that the last item + # in the list of paths is the empty path, which actually + # means the default path, i.e., the following means that + # the TEXINPUTS search path is $aux_dir and the standard + # value. + $ENV{TEXINPUTS} = $aux_dir.$search_path_separator; + } + elsif ( $ENV{TEXINPUTS} !~ /$aux_dir$search_path_separator/ ) { + $ENV{TEXINPUTS} = $aux_dir.$search_path_separator.$ENV{TEXINPUTS}; + } +} + +$quell_uptodate_msgs = $silent; + # Whether to quell informational messages when files are uptodate + # Will turn off in -pvc mode + +$failure_count = 0; +@failed_primaries = (); + +if ($deps_file eq '' ) { + # Standardize name used for stdout + $deps_file = '-'; +} + +# In non-pvc mode, the dependency list is global to all processed TeX files, +# so we open a single file here, and add items to it after processing each file +# But in -pvc mode, the dependency list should be written after round of +# processing the single TeX file (as if each round were a separate run of +# latexmk). There's undoubtedly some non-optimal structuring here! +if ( $dependents_list && ! $preview_continuous_mode ) { + $deps_handle = new FileHandle "> $deps_file"; + if (! defined $deps_handle ) { + die "Cannot open '$deps_file' for output of dependency information\n"; + } +} + +# Remove leading and trailing space in the following space-separated lists, +# and collapse multiple spaces to one, +# to avoid getting incorrect blank items when they are split. +foreach ($clean_ext, $clean_full_ext) { s/^\s+//; s/\s+$//; s/\s+/ /g; } + + +FILE: +foreach $filename ( @file_list ) +{ + # Global variables for making of current file: + $updated = 0; + $failure = 0; # Set nonzero to indicate failure at some point of + # a make. Use value as exit code if I exit. + $failure_msg = ''; # Indicate reason for failure + + if ( $do_cd ) { + ($filename, $path) = fileparse( $filename ); + warn "$My_name: Changing directory to '$path'\n"; + pushd( $path ); + } + else { + $path = ''; + } + + # Ensure the output/auxiliary directories exist, if need be + if ( $out_dir ) { + if ( ! -e $out_dir ) { + warn "$My_name: making output directory '$out_dir'\n" + if ! $silent; + make_path $out_dir; + } + elsif ( ! -d $out_dir ) { + warn "$My_name: you requested output directory '$out_dir',\n", + " but an ordinary file of the same name exists, which will\n", + " probably give an error later\n"; + } + } + + if ( $aux_dir && ($aux_dir ne $out_dir) ) { + # N.B. If $aux_dir and $out_dir are the same, then the -output-directory + # option is sufficient, especially because the -aux-directory exists + # only in MiKTeX, not in TeXLive. + if ( ! -e $aux_dir ) { + warn "$My_name: making auxiliary directory '$aux_dir'\n" + if ! $silent; + make_path $aux_dir; + } + elsif ( ! -d $aux_dir ) { + warn "$My_name: you requested aux directory '$aux_dir',\n", + " but an ordinary file of the same name exists, which will\n", + " probably give an error later\n"; + } + } + + ## remove extension from filename if was given. + if ( find_basename($filename, $root_filename, $texfile_name) ) + { + if ( $force_mode ) { + warn "$My_name: Could not find file [$texfile_name]\n"; + } + else { + &ifcd_popd; + &exit_msg1( "Could not find file [$texfile_name]", + 11); + } + } + if ($jobname ne '' ) { + $root_filename = $jobname; + } + + $aux_main = "$aux_dir1$root_filename.aux"; + $log_name = "$aux_dir1$root_filename.log"; + $fdb_name = "$aux_dir1$root_filename.$fdb_ext"; + + # Initialize basic dependency information: + + # For use under error conditions: + @default_includes = ($texfile_name, $aux_main); + + # Initialize rule database. + # ?? Should I also initialize file database? + %rule_list = (); + &rdb_make_rule_list; + &rdb_set_rules( \%rule_list, \%extra_rule_spec ); + + if ( $cleanup_mode > 0 ) { +# ?? MAY NEED TO FIX THE FOLLOWING IF $aux_dir or $out_dir IS SET. + my %other_generated = (); + my @index_bibtex_generated = (); + my @aux_files = (); + $have_fdb = 0; + if ( -e $fdb_name ) { + print "$My_name: Examining fdb file '$fdb_name' for rules ...\n" + if $diagnostics; + $have_fdb = ( 0 == rdb_read( $fdb_name ) ); + } + if ( $have_fdb ) { + rdb_for_all( + sub { # Find generated files at rule level + my ($base, $path, $ext) = fileparseA( $$Psource ); + $base = $path.$base; + if ( $rule =~ /^makeindex/ ) { + push @index_bibtex_generated, $$Psource, $$Pdest, "$base.ilg"; + } + elsif ( $rule =~ /^(bibtex|biber)/ ) { + push @index_bibtex_generated, $$Pdest, "$base.blg"; + push @aux_files, $$Psource; + } + elsif ( exists $other_generated{$$Psource} ) { + $other_generated{$$Pdest}; + } + }, + sub { # Find generated files at source file level + if ( $file =~ /\.aux$/ ) { push @aux_files, $file; } + } + ); + } + elsif ( -e $log_name ) { + # No fdb file, but log file exists, so do inferior job by parse_log + print "$My_name: Examining log file '$log_name' for generated files...\n" + if $diagnostics; + # Variables set by parse_log. Can I remove them? + local %generated_log = (); + local %dependents = (); # Maps files to status. Not used here. + local @bbl_files = (); # Not used here. + local %idx_files = (); # Maps idx_file to (ind_file, base). Not used here. + local %conversions = (); # (pdf)latex-performed conversions. Not used here. + # Maps output file created and read by (pdf)latex + # to source file of conversion. + local $primary_out = ''; # Actual output file (dvi or pdf). Not used here. + local $fls_file_analyzed = 0; + &parse_log; + %other_generated = %generated_log; + } + else { + print "$My_name: No fdb or log file, so clean up default set of files ...\n" + if $diagnostics; + } + + if ( ($go_mode == 2) && !$silent ) { + warn "$My_name: Removing all generated files\n" unless $silent; + } + if ($bibtex_use < 2) { + delete $generated_exts_all{'bbl'}; + } + # Convert two arrays to hashes: + my %index_bibtex_generated = (); + my %aux_files = (); + foreach (@index_bibtex_generated) { + $index_bibtex_generated{$_} = 1 + unless ( /\.bbl$/ && ($bibtex_use < 2) ); + delete( $other_generated{$_} ); + } + foreach (@aux_files) { + $aux_files{$_} = 1; + delete( $other_generated{$_} ); + } + if ($diagnostics) { + show_array( "For deletion, the following were determined from fdb file or log file:\n" + ." Generated (from makeindex and bibtex):", + keys %index_bibtex_generated ); + show_array( " Aux files:", keys %aux_files ); + show_array( " Other generated files:\n" + ." (only deleted if \$cleanup_includes_generated is set): ", + keys %other_generated ); + show_array( " Yet other generated files:\n", + keys %generated_exts_all ); + } + &cleanup1( $aux_dir1, $fdb_ext, 'blg', 'ilg', 'log', 'aux.bak', 'idx.bak', + split('\s+',$clean_ext), + keys %generated_exts_all + ); + unlink_or_move( 'texput.log', "texput.aux", "missfont.log", + keys %index_bibtex_generated, + keys %aux_files ); + if ( $dependents_list && ( $deps_file ne '-' ) ) { + unlink_or_move( $deps_file ); + } + if ($cleanup_includes_generated) { + unlink_or_move( keys %other_generated ); + } + if ( $cleanup_includes_cusdep_generated) { + &cleanup_cusdep_generated; + } + if ( $cleanup_mode == 1 ) { + &cleanup1( $out_dir1, 'dvi', 'dviF', 'ps', 'psF', 'pdf', + 'synctex.gz', 'xdv', + split('\s+', $clean_full_ext) + ); + } + } + if ($cleanup_fdb) { + unlink_or_move( $fdb_name ); + # If the fdb file exists, it will have been read, and therefore changed + # rule database. But deleting the fdb file implies we also want + # a virgin rule database, so we must reset it: + rdb_set_rules( \%rule_list ); + } + if ($cleanup_only) { next FILE; } + + +#??? The following are not needed if use rdb_make. +# ?? They may be set too early? +# Arrays and hashes for picking out accessible rules. +# Distinguish rules for making files and others + @accessible_all = sort ( &rdb_accessible( keys %requested_filerules, keys %one_time )); + %accessible_filerules = (); + foreach (@accessible_all) { + unless ( /view/ || /print/ ) { $accessible_filerules{$_} = 1; } + } + @accessible_filerules = sort keys %accessible_filerules; + +# show_array ( "=======All rules used", @accessible_all ); +# show_array ( "=======Requested file rules", sort keys %requested_filerules ); +# show_array ( "=======Rules for files", @accessible_filerules ); + + if ( $diagnostics ) { + print "$My_name: Rules after start up for '$texfile_name'\n"; + rdb_show(); + } + + %primaries = (); + foreach (@accessible_all) { + if ( ($_ eq 'latex') || ($_ eq 'pdflatex') || ($_ eq 'lualatex') + || ($_ eq 'xelatex') ) + { $primaries{$_} = 1; } + } + + $have_fdb = 0; + if (! -e $aux_main ) { + # No aux file => set up trivial aux file + # and corresponding fdb_file. Arrange them to provoke one run + # as minimum, but no more if actual aux file is trivial. + # (Useful on big files without cross references.) + # If aux file doesn't exist, then any fdb file is surely + # wrong. + # Previously, I had condition for this as being both aux and + # fdb files failing to exist. But it's not obvious what to + # do if aux exists and fdb doesn't. So I won't do anything. + &set_trivial_aux_fdb; + } + + if ( -e $fdb_name ) { + $rdb_errors = rdb_read( $fdb_name ); + $have_fdb = ($rdb_errors == 0); + } + if (!$have_fdb) { + # We didn't get a valid set of data on files used in + # previous run. So use filetime criterion for make + # instead of change from previous run, until we have + # done our own make. + rdb_recurse( [keys %possible_primaries], + sub{ if ( $$Ptest_kind == 1 ) { $$Ptest_kind = 3;} } + ); + if ( -e $log_name ) { + rdb_for_some( [keys %possible_primaries], \&rdb_set_latex_deps ); + } + } + foreach $rule ( rdb_accessible( uniq1( keys %requested_filerules ) ) ){ + # For all source files of all accessible rules, + # if the file data are not already set (e.g., from fdb_latexmk + # file, set them from disk. + rdb_one_rule ($rule, undef, + sub{ if ( $$Ptime == 0) { &rdb_update1; } } + ); + } + + if ($go_mode) { + # Force everything to be remade. + rdb_recurse( [keys %requested_filerules], sub{$$Pout_of_date=1;} ); + } + + + if ( $diagnostics ) { + print "$My_name: Rules after initialization\n"; + rdb_show(); + } + + #************************************************************ + + if ( $preview_continuous_mode ) { + &make_preview_continuous; + next FILE; + } + + +## Handling of failures: +## Variable $failure is set to indicate a failure, with information +## put in $failure_msg. +## These variables should be set to 0 and '' at any point at which it +## should be assumed that no failures have occurred. +## When after a routine is called it is found that $failure is set, then +## processing should normally be aborted, e.g., by return. +## Then there is a cascade of returns back to the outermost level whose +## responsibility is to handle the error. +## Exception: An outer level routine may reset $failure and $failure_msg +## after initial processing, when the error condition may get +## ameliorated later. + #Initialize failure flags now. + $failure = 0; + $failure_msg = ''; + $failure = rdb_make( keys %requested_filerules ); + if ( ( $failure <= 0 ) || $force_mode ) { + rdb_for_some( [keys %one_time], \&rdb_run1 ); + } + if ($failure > 0) { next FILE; } +} # end FILE +continue { + if ($deps_handle) { deps_list($deps_handle); } + # If requested, print the list of rules. But don't do this in -pvc + # mode, since the rules list has already been printed. + if ($rules_list && ! $preview_continuous_mode) { rdb_list(); } + # Handle any errors + $error_message_count = rdb_show_rule_errors(); + if ( ($error_message_count == 0) || ($failure > 0) ) { + if ( $failure_msg ) { + #Remove trailing space + $failure_msg =~ s/\s*$//; + warn "$My_name: Did not finish processing file '$filename':\n", + " $failure_msg\n"; + $failure = 1; + } + } + if ( ($failure > 0) || ($error_message_count > 0) ) { + $failure_count ++; + push @failed_primaries, $filename; + } + &ifcd_popd; +} +close($deps_handle) if ( $deps_handle ); + +if ($show_time) { show_timing();} + +sub show_timing { + my $processing_time = processing_time() - $processing_time1; + print @timings, "Accumulated processing time = $processing_time\n"; + @timings = (); + $processing_time1 = processing_time(); +} + +# If we get here without going through the continue section: +if ( $do_cd && ($#dir_stack > -1) ) { + # Just in case we did an abnormal exit from the loop + warn "$My_name: Potential bug: dir_stack not yet unwound, undoing all directory changes now\n"; + &finish_dir_stack; +} + +if ($failure_count > 0) { + if ( $#file_list > 0 ) { + # Error occured, but multiple files were processed, so + # user may not have seen all the error messages + warn "\n------------\n"; + show_array( + "$My_name: Some operations failed, for the following tex file(s)", + @failed_primaries); + } + if ( !$force_mode ) { + warn "$My_name: Use the -f option to force complete processing,\n", + " unless error was exceeding maximum runs of latex/pdflatex.\n"; + } + exit 12; +} + + + +# end MAIN PROGRAM +############################################################# + +sub fix_cmds { + # If commands do not have placeholders for %S etc, put them in + foreach ($latex, $pdflatex, $lpr, $lpr_dvi, $lpr_pdf, + $pdf_previewer, $ps_previewer, $ps_previewer_landscape, + $dvi_previewer, $dvi_previewer_landscape, + $kpsewhich + ) { + # Source only + if ( $_ && ! /%/ ) { $_ .= " %O %S"; } + } + foreach ($pdf_previewer, $ps_previewer, $ps_previewer_landscape, + $dvi_previewer, $dvi_previewer_landscape, + ) { + # Run previewers detached + if ( $_ && ! /^(nostart|NONE|internal) / ) { + $_ = "start $_"; + } + } + foreach ($biber, $bibtex) { + # Base only + if ( $_ && ! /%/ ) { $_ .= " %O %B"; } + } + foreach ($dvipdf, $ps2pdf) { + # Source and dest without flag for destination + if ( $_ && ! /%/ ) { $_ .= " %O %S %D"; } + } + foreach ($dvips, $makeindex) { + # Source and dest with -o dest before source + if ( $_ && ! /%/ ) { $_ .= " %O -o %D %S"; } + } + foreach ($dvi_filter, $ps_filter) { + # Source and dest, but as filters + if ( $_ && ! /%/ ) { $_ .= " %O <%S >%D"; } + } +} #END fix_cmds + +############################################################# + +sub add_option { + # Call add_option( $opt, \$cmd ... ) + # Add option to one or more commands + my $option = shift; + while (@_) { + if ( ${$_[0]} !~ /%/ ) { &fix_cmds; } + ${$_[0]} =~ s/%O/$option %O/; + shift; + } +} #END add_option + +############################################################# + +sub rdb_make_rule_list { +# Set up specifications for standard rules, adjusted to current conditions +# Substitutions: %S = source, %D = dest, %B = this rule's base +# %T = texfile, %R = root = base for latex. +# %Y for $aux_dir1, %Z for $out_dir1 + + # Defaults for dvi, ps, and pdf files + # Use local, not my, so these variables can be referenced + local $dvi_final = "%Z%R.dvi"; + local $ps_final = "%Z%R.ps"; + local $pdf_final = "%Z%R.pdf"; + local $xdv_final = "%Z%R.xdv"; + if ( length($dvi_filter) > 0) { + $dvi_final = "%Z%R.dviF"; + } + if ( length($ps_filter) > 0) { + $ps_final = "%Z%R.psF"; + } + + my $print_file = ''; + my $print_cmd = 'NONE'; + if ( $print_type eq 'dvi' ) { + $print_file = $dvi_final; + $print_cmd = $lpr_dvi; + } + elsif ( $print_type eq 'pdf' ) { + $print_file = $pdf_final; + $print_cmd = $lpr_pdf; + } + elsif ( $print_type eq 'ps' ) { + $print_file = $ps_final; + $print_cmd = $lpr; + } + elsif ( $print_type eq 'none' ) { + $print_cmd = 'NONE echo NO PRINTING CONFIGURED'; + } + + my $view_file = ''; + my $viewer = ''; + my $viewer_update_method = 0; + my $viewer_update_signal = undef; + my $viewer_update_command = undef; + + if ( ($view eq 'dvi') || ($view eq 'pdf') || ($view eq 'ps') ) { + $view_file = ${$view.'_final'}; + $viewer = ${$view.'_previewer'}; + $viewer_update_method = ${$view.'_update_method'}; + $viewer_update_signal = ${$view.'_update_signal'}; + if (defined ${$view.'_update_command'}) { + $viewer_update_command = ${$view.'_update_command'}; + } + } + # Specification of internal command for viewer update: + my $PA_update = ['do_update_view', $viewer_update_method, $viewer_update_signal, 0, 1]; + +# For test_kind: Use file contents for latex and friends, but file time for the others. +# This is because, especially for dvi file, the contents of the file may contain +# a pointer to a file to be included, not the contents of the file! + %rule_list = ( + 'latex' => [ 'primary', "$latex", '', "%T", "%Z%B.dvi", "%R", 1, ["%Y%R.log"] ], + 'pdflatex' => [ 'primary', "$pdflatex", '', "%T", "%Z%B.pdf", "%R", 1, ["%Y%R.log"] ], + 'lualatex' => [ 'primary', "$lualatex", '', "%T", "%Z%B.pdf", "%R", 1, ["%Y%R.log"] ], + 'xelatex' => [ 'primary', "$xelatex", '', "%T", "%Z%B.xdv", "%R", 1, ["%Y%R.log"] ], + 'dvipdf' => [ 'external', "$dvipdf", 'do_viewfile', $dvi_final, "%B.pdf", "%Z%R", 2 ], + 'xdvipdfmx' => [ 'external', "$xdvipdfmx", 'do_viewfile', $xdv_final, "%B.pdf", "%Z%R", 2 ], + 'dvips' => [ 'external', "$dvips", 'do_viewfile', $dvi_final, "%B.ps", "%Z%R", 2 ], + 'dvifilter'=> [ 'external', $dvi_filter, 'do_viewfile', "%B.dvi", "%B.dviF", "%Z%R", 2 ], + 'ps2pdf' => [ 'external', "$ps2pdf", 'do_viewfile', $ps_final, "%B.pdf", "%Z%R", 2 ], + 'psfilter' => [ 'external', $ps_filter, 'do_viewfile', "%B.ps", "%B.psF", "%Z%R", 2 ], + 'print' => [ 'external', "$print_cmd", 'if_source', $print_file, "", "", 2 ], + 'update_view' => [ 'external', $viewer_update_command, $PA_update, + $view_file, "", "", 2 ], + 'view' => [ 'external', "$viewer", 'if_source', $view_file, "", "", 2 ], + ); + +# Ensure we only have one way to make pdf file, and that it is appropriate: + if ($pdf_mode == 2) { delete $rule_list{'dvipdf'}; delete $rule_list{'pdflatex'}; delete $rule_list{'lualatex'}; delete $rule_list{'xelatex'}; } + elsif ($pdf_mode == 3) { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'lualatex'}; delete $rule_list{'xelatex'}; } + elsif ($pdf_mode == 4) { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'dvipdf'}; delete $rule_list{'xelatex'}; } + elsif ($pdf_mode == 5) { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'dvipdf'}; delete $rule_list{'lualatex'}; } + else { # Default is to leave pdflatex + delete $rule_list{'dvipdf'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'lualatex'}; delete $rule_list{'xelatex'}; + } + +} # END rdb_make_rule_list + +#************************************************************ + +sub rdb_set_rules { + # Call rdb_set_rules( \%rule_list, ...) + # Set up rule database from definitions + + # Map of files to rules that MAKE them: + %rule_db = (); + + foreach my $Prule_list (@_) { + foreach my $rule ( keys %$Prule_list) { + my ( $cmd_type, $ext_cmd, $int_cmd, $source, $dest, $base, $test_kind, $PA_extra_gen ) = @{$$Prule_list{$rule}}; + if ( ! $PA_extra_gen ) { $PA_extra_gen = []; } + my $needs_making = 0; + # Substitute in the filename variables, since we will use + # those for determining filenames. But delay expanding $cmd + # until run time, in case of changes. + foreach ($base, $source, $dest, @$PA_extra_gen ) { + s/%R/$root_filename/; + s/%Y/$aux_dir1/; + s/%Z/$out_dir1/; + } + foreach ($source, $dest ) { + s/%B/$base/; + s/%T/$texfile_name/; + } + # print "$rule: $cmd_type, EC='$ext_cmd', IC='$int_cmd', $test_kind,\n", + # " S='$source', D='$dest', B='$base' $needs_making\n"; + rdb_create_rule( $rule, $cmd_type, $ext_cmd, $int_cmd, $test_kind, + $source, $dest, $base, + $needs_making, undef, undef, 1, $PA_extra_gen ); +# !! ?? Last line was +# $needs_making, undef, ($test_kind==1) ); + } + } # End arguments of subroutine + &rdb_make_links; +} # END rdb_set_rules + +#************************************************************ + +sub rdb_make_links { +# ?? Problem if there are multiple rules for getting a file. Notably pdf. +# Which one to choose? + # Create $from_rule if there's a suitable rule. + # Map files to rules: + local %from_rules = (); + rdb_for_all( sub{ if($$Pdest){$from_rules{$$Pdest} = $rule;} } ); +#?? foreach (sort keys %from_rules) {print "D='$_' F='$from_rules{$_}\n";} + rdb_for_all( + 0, + sub{ + # Set from_rule, but only if it isn't set or is invalid. + # Don't forget the biber v. bibtex issue + if ( exists $from_rules{$file} + && ( (!$$Pfrom_rule) || (! exists $rule_db{$$Pfrom_rule} ) ) + ) + { $$Pfrom_rule = $from_rules{$file}; + } + } + ); + rdb_for_all( + 0, + sub{ + if ( exists $from_rules{$file} ) { + $$Pfrom_rule = $from_rules{$file}; + } + if ( $$Pfrom_rule && (! rdb_rule_exists( $$Pfrom_rule ) ) ) { + $$Pfrom_rule = ''; + } +#?? print "$rule: $file, $$Pfrom_rule\n"; + } + ); +} # END rdb_make_links + +#************************************************************ + +sub set_trivial_aux_fdb { + # 1. Write aux file EXACTLY as would be written if the tex file + # had no cross references, etc. I.e., a minimal .aux file. + # 2. Write a corresponding fdb file + # 3. Provoke a run of (pdf)latex (actually of all primaries). + + local *aux_file; + open( aux_file, '>', $aux_main ) + or die "Cannot write file '$aux_main'\n"; + print aux_file "\\relax \n"; + close(aux_file); + + foreach my $rule (keys %primaries ) { + rdb_ensure_file( $rule, $texfile_name ); + rdb_ensure_file( $rule, $aux_main ); + rdb_one_rule( $rule, + sub{ $$Pout_of_date = 1; } + ); + } + &rdb_write( $fdb_name ); +} #END set_trivial_aux_fdb + +#************************************************************ +#### Particular actions +#************************************************************ +#************************************************************ + +sub do_cusdep { + # Unconditional application of custom-dependency + # except that rule is not applied if the source file source + # does not exist, and an error is returned if the dest is not made. + # + # Assumes rule context for the custom-dependency, and that my first + # argument is the name of the subroutine to apply + my $func_name = $_[0]; + my $return = 0; + if ( !-e $$Psource ) { + # Source does not exist. Users of this rule will need to turn + # it off when custom dependencies are reset + if ( !$silent ) { +## ??? Was commented out. 1 Sep. 2008 restored, for cusdep no-file-exists issue + warn "$My_name: In trying to apply custom-dependency rule\n", + " to make '$$Pdest' from '$$Psource'\n", + " the source file has disappeared since the last run\n"; + } + # Treat as successful + } + elsif ( !$func_name ) { + warn "$My_name: Possible misconfiguration or bug:\n", + " In trying to apply custom-dependency rule\n", + " to make '$$Pdest' from '$$Psource'\n", + " the function name is blank.\n"; + } + elsif ( ! defined &$func_name ) { + warn "$My_name: Misconfiguration or bug,", + " in trying to apply custom-dependency rule\n", + " to make '$$Pdest' from '$$Psource'\n", + " function name '$func_name' does not exists.\n"; + } + else { + my $cusdep_ret = &$func_name( $$Pbase ); + if ( defined $cusdep_ret && ($cusdep_ret != 0) ) { + $return = $cusdep_ret; + if ($return) { + warn "Rule '$rule', function '$func_name'\n", + " failed with return code = $return\n"; + } + } + elsif ( !-e $$Pdest ) { + # Destination non-existent, but routine failed to give an error + warn "$My_name: In running custom-dependency rule\n", + " to make '$$Pdest' from '$$Psource'\n", + " function '$func_name' did not make the destination.\n"; + $return = -1; + } + } + return $return; +} # END do_cusdep + +#************************************************************ + +sub do_viewfile { + # Unconditionally make file for viewing, going through temporary file if + # Assumes rule context + + my $return = 0; + my ($base, $path, $ext) = fileparseA( $$Pdest ); + if ( &view_file_via_temporary ) { + if ( $$Pext_cmd =~ /%D/ ) { + my $tmpfile = tempfile1( "${root_filename}_tmp", $ext ); + warn "$My_name: Making '$$Pdest' via temporary '$tmpfile'...\n"; + $return = &Run_subst( undef, undef, undef, undef, $tmpfile ); + move( $tmpfile, $$Pdest ); + } + else { + warn "$My_name is configured to make '$$Pdest' via a temporary file\n", + " but the command template '$$Pext_cmd' does not have a slot\n", + " to set the destination file, so I won't use a temporary file\n"; + $return = &Run_subst(); + } + } + else { + $return = &Run_subst(); + } + return $return; +} #END do_viewfile + +#************************************************************ + +sub do_update_view { + # Update viewer + # Assumes rule context + # Arguments: (method, signal, viewer_process) + + my $return = 0; + + # Although the process is passed as an argument, we'll need to update it. + # So (FUDGE??) bypass the standard interface for the process. + # We might as well do this for all the arguments. + my $viewer_update_method = ${$PAint_cmd}[1]; + my $viewer_update_signal = ${$PAint_cmd}[2]; + my $Pviewer_process = \${$PAint_cmd}[3]; + my $Pneed_to_get_viewer_process = \${$PAint_cmd}[4]; + + if ($viewer_update_method == 2) { + if ($$Pneed_to_get_viewer_process) { + $$Pviewer_process = &find_process_id( $$Psource ); + if ($$Pviewer_process != 0) { + $$Pneed_to_get_viewer_process = 0; + } + } + if ($$Pviewer_process == 0) { + print "$My_name: need to signal viewer for file '$$Psource', but didn't get \n", + " process ID for some reason, e.g., no viewer, bad configuration, bug\n" + if $diagnostics ; + } + elsif ( defined $viewer_update_signal) { + print "$My_name: signalling viewer, process ID $$Pviewer_process ", + "with signal $viewer_update_signal\n" + if $diagnostics ; + kill $viewer_update_signal, $$Pviewer_process; + } + else { + warn "$My_name: viewer is supposed to be sent a signal\n", + " but no signal is defined. Misconfiguration or bug?\n"; + $return = 1; + } + } + elsif ($viewer_update_method == 4) { + if (defined $$Pext_cmd) { + $return = &Run_subst(); + } + else { + warn "$My_name: viewer is supposed to be updated by running a command,\n", + " but no command is defined. Misconfiguration or bug?\n"; + } + } + return $return; +} #END do_update_view + +#************************************************************ + +sub if_source { + # Unconditionally apply rule if source file exists. + # Assumes rule context + if ( -e $$Psource ) { + return &Run_subst(); + } + else { + warn "Needed source file '$$Psource' does not exist.\n"; + return -1; + } +} #END if_source + +#************************************************************ +#### Subroutines +#************************************************************ +#************************************************************ + +sub find_basename { + # Finds the basename of the root file + # Arguments: + # 1 - Filename to breakdown + # 2 - Where to place base file + # 3 - Where to place tex file + # Returns non-zero if tex file does not exist + # + # The rules for determining this depend on the implementation of TeX. + # The variable $extension_treatment determines which rules are used. + + # !!!!!!!! I still need to implement use of kpsewhich to match behavior + # of (pdf)latex correctly. + + local($given_name, $base_name, $ext, $path, $tex_name); + $given_name = $_[0]; + if ( "$extension_treatment" eq "miktex_old" ) { + # Miktex v. 1.20d: + # 1. If the filename has an extension, then use it. + # 2. Else append ".tex". + # 3. The basename is obtained from the filename by + # removing the path component, and the extension, if it + # exists. If a filename has a multiple extension, then + # all parts of the extension are removed. + # 4. The names of generated files (log, aux) are obtained by + # appending .log, .aux, etc to the basename. Note that + # these are all in the CURRENT directory, and the drive/path + # part of the originally given filename is ignored. + # + # Thus when the given filename is "\tmp\a.b.c", the tex + # filename is the same, and the basename is "a". + + ($base_name, $path, $ext) = fileparse( $given_name, '\..*' ); + if ( "$ext" eq "") { $tex_name = "$given_name.tex"; } + else { $tex_name = $given_name; } + $_[1] = $base_name; + $_[2] = $tex_name; + } + elsif ( "$extension_treatment" eq "unix" ) { + # unix (at least TeXLive 2016) => + # A. Finding of tex file: + # 1. If filename.tex exists, use it, + # 2. else if kpsewhich finds filename.tex, use it + # 3. else if filename exists, use it, + # 4. else if kpsewhich finds filename, use it. + # (Probably can unify the above by + # 1'. If kpsewhich finds filename.tex, use result. + # 2'. else if kpsewhich finds filename, use result. + # 3'. else report file not found. + # B. The base filename is obtained by deleting the path + # component and, if an extension exists, the last + # component of the extension, even if the extension is + # null. (A name ending in "." has a null extension.) + # C. The names of generated files (log, aux) are obtained by + # appending .log, .aux, etc to the basename. Note that + # these are all in the CURRENT directory, and the drive/path + # part of the originally given filename is ignored. + # + # Thus when the given filename is "/tmp/a.b.c", there are two + # cases: + # a. /tmp/a.b.c.tex exists. Then this is the tex file, + # and the basename is "a.b.c". + # b. /tmp/a.b.c.tex does not exist. Then the tex file is + # "/tmp/a.b.c", and the basename is "a.b". + # But there are also modifications of this when a file can be + # found by kpsewhich. + + if ( -f "$given_name.tex" ) { + $tex_name = "$given_name.tex"; + } + else { + $tex_name = "$given_name"; + } + ($base_name, $path, $ext) = fileparse( $tex_name, '\.[^\.]*' ); + $_[1] = $base_name; + $_[2] = $tex_name; + } + else { + die "$My_name: Incorrect configuration gives \$extension_treatment=", + "'$extension_treatment'\n"; + } + if ($diagnostics) { + print "Given='$given_name', tex='$tex_name', base='$base_name'\n"; + } + return ! -e $tex_name; +} #END find_basename + +#************************************************************ + +sub make_preview_continuous { + local @changed = (); + local @disappeared = (); + local @no_dest = (); # Non-existent destination files + local @rules_never_run = (); + local @rules_to_apply = (); + + local $failure = 0; + local %rules_applied = (); + local $updated = 0; + + # What to make? + my @targets = keys %requested_filerules; + + $quell_uptodate_msgs = 1; + + local $view_file = ''; + rdb_one_rule( 'view', sub{ $view_file = $$Psource; } ); + + if ( ($view eq 'dvi') || ($view eq 'pdf') || ($view eq 'ps') ) { + warn "Viewing $view\n"; + } + elsif ( $view eq 'none' ) { + warn "Not using a previewer\n"; + $view_file = ''; + } + else { + warn "$My_name: BUG: Invalid preview method '$view'\n"; + exit 20; + } + + my $viewer_running = 0; # No viewer known to be running yet + # Get information from update_view rule + local $viewer_update_method = 0; + # Pointers so we can update the following: + local $Pviewer_process = undef; + local $Pneed_to_get_viewer_process = undef; + rdb_one_rule( 'update_view', + sub{ $viewer_update_method = $$PAint_cmd[1]; + $Pviewer_process = \$$PAint_cmd[3]; + $Pneed_to_get_viewer_process = \$$PAint_cmd[4]; + } + ); + # Note that we don't get the previewer process number from the program + # that starts it; that might only be a script to get things set up and the + # actual previewer could be (and sometimes IS) another process. + + if ( ($view_file ne '') && (-e $view_file) && !$new_viewer_always ) { + # Is a viewer already running? + # (We'll save starting up another viewer.) + $$Pviewer_process = &find_process_id( $view_file ); + if ( $$Pviewer_process ) { + warn "$My_name: Previewer is already running\n" + if !$silent; + $viewer_running = 1; + $$Pneed_to_get_viewer_process = 0; + } + } + + # Loop forever, rebuilding .dvi and .ps as necessary. + # Set $first_time to flag first run (to save unnecessary diagnostics) +CHANGE: + for (my $first_time = 1; 1; $first_time = 0 ) { + my %rules_to_watch = %requested_filerules; + $updated = 0; + $failure = 0; + $failure_msg = ''; + if ( $MSWin_fudge_break && ($^O eq "MSWin32") ) { + # Fudge under MSWin32 ONLY, to stop perl/latexmk from + # catching ctrl/C and ctrl/break, and let it only reach + # downstream programs. See comments at first definition of + # $MSWin_fudge_break. + $SIG{BREAK} = $SIG{INT} = 'IGNORE'; + } + if ($compiling_cmd) { + Run_subst( $compiling_cmd ); + } + $failure = rdb_make( @targets ); + +## warn "=========Viewer PID = $$Pviewer_process; updated=$updated\n"; + + if ( $MSWin_fudge_break && ($^O eq "MSWin32") ) { + $SIG{BREAK} = $SIG{INT} = 'DEFAULT'; + } + # Start viewer if needed. + if ( ($failure > 0) && (! $force_mode) ) { + # No viewer yet + } + elsif ( ($view_file ne '') && (-e $view_file) && $updated && $viewer_running ) { + # A viewer is running. Explicitly get it to update screen if we have to do it: + rdb_one_rule( 'update_view', \&rdb_run1 ); + } + elsif ( ($view_file ne '') && (-e $view_file) && !$viewer_running ) { + # Start the viewer + if ( !$silent ) { + if ($new_viewer_always) { + warn "$My_name: starting previewer for '$view_file'\n", + "------------\n"; + } + else { + warn "$My_name: I have not found a previewer that ", + "is already running. \n", + " So I will start it for '$view_file'\n", + "------------\n"; + } + } + local $retcode = 0; + rdb_one_rule( 'view', sub { $retcode = &rdb_run1;} ); + if ( $retcode != 0 ) { + if ($force_mode) { + warn "$My_name: I could not run previewer\n"; + } + else { + &exit_msg1( "I could not run previewer", $retcode); + } + } + else { + $viewer_running = 1; + $$Pneed_to_get_viewer_process = 1; + } # end analyze result of trying to run viewer + } # end start viewer + if ( $failure > 0 ) { + if ( !$failure_msg ) { + $failure_msg = 'Failure to make the files correctly'; + } + @pre_primary = (); # Array of rules + @post_primary = (); # Array of rules + @unusual_one_time = (); # Array of rules + &rdb_classify_rules( \%possible_primaries, keys %requested_filerules ); + # There will be files changed during the run that are irrelevant. + # We need to wait for the user to change the files. + + # So set the GENERATED files from (pdf)latex as up-to-date: + rdb_for_some( [keys %current_primaries], \&rdb_update_gen_files ); + + # And don't watch for changes for post_primary rules (ps and pdf + # from dvi, etc haven't been run after an error in (pdf)latex, so + # are out-of-date by filetime criterion, but they should not be run + # until after another (pdf)latex run: + foreach (@post_primary) { delete $rules_to_watch{$_}; } + + $failure_msg =~ s/\s*$//; #Remove trailing space + warn "$My_name: $failure_msg\n", + " ==> You will need to change a source file before I do another run <==\n"; + if ($failure_cmd) { + Run_subst( $failure_cmd ); + } + } + else { + if ($success_cmd) { + Run_subst( $success_cmd ); + } + } + rdb_show_rule_errors(); + if ($rules_list) { rdb_list(); } + if ($show_time && ! $first_time) { show_timing(); } + if ( $dependents_list && ($updated || $failure) ) { + my $deps_handle = new FileHandle "> $deps_file"; + if ( defined $deps_handle ) { + deps_list($deps_handle); + close($deps_handle); + } + else { + warn "Cannot open '$deps_file' for output of dependency information\n"; + } + } + if ( $first_time || $updated || $failure ) { + print "\n=== Watching for updated files. Use ctrl/C to stop ...\n"; + } + $waiting = 1; if ($diagnostics) { warn "WAITING\n"; } +# During waiting for file changes, handle ctrl/C and ctrl/break here, rather than letting +# system handle them by terminating script (and any script that calls it). This allows, +# for example, the clean up code in the following command line to work: +# latexmk -pvc foo; cleanup; + &catch_break; + $have_break = 0; + WAIT: while (1) { + sleep( $sleep_time ); + if ($have_break) { last WAIT; } + if ( rdb_new_changes(keys %rules_to_watch) ) { + if (!$silent) { + warn "$My_name: Need to remake files.\n"; + &rdb_diagnose_changes( ' ' ); + } + last WAIT; + } + # Don't count waiting time in processing: + $processing_time1 = processing_time(); + # Does this do this job???? + local $new_files = 0; + rdb_for_some( [keys %current_primaries], sub{ $new_files += &rdb_find_new_files } ); + if ($new_files > 0) { + warn "$My_name: New file(s) found.\n"; + last WAIT; + } + if ($have_break) { last WAIT; } + } # end WAIT: + &default_break; + if ($have_break) { + print "$My_name: User typed ctrl/C or ctrl/break. I'll finish.\n"; + return; + } + $waiting = 0; if ($diagnostics) { warn "NOT WAITING\n"; } + } #end infinite_loop CHANGE: +} #END sub make_preview_continuous + +#************************************************************ + +sub process_rc_file { + # Usage process_rc_file( filename ) + # NEW VERSION + # Run rc_file whose name is given in first argument + # Exit with code 0 on success + # Exit with code 1 if file cannot be read or does not exist. + # Stop if there is a syntax error or other problem. + # PREVIOUSLY: + # Exit with code 2 if is a syntax error or other problem. + my $rc_file = $_[0]; + my $ret_code = 0; + warn "$My_name: Executing Perl code in file '$rc_file'...\n" + if $diagnostics; + # I could use the do command of perl, but the preceeding -r test + # to get good diagnostics gets the wrong result under cygwin + # (e.g., on /cygdrive/c/latexmk/LatexMk) + my $RCH = new FileHandle; + if ( !-e $rc_file ) { + warn "$My_name: The rc-file '$rc_file' does not exist\n"; + return 1; + } + elsif ( -d $rc_file ) { + warn "$My_name: The supposed rc-file '$rc_file' is a directory; but it\n", + " should be a normal text file\n"; + return 1; + } + elsif ( open $RCH, "<$rc_file" ) { + { local $/; eval <$RCH>; } + close $RCH; + } + else { + warn "$My_name: I cannot read the rc-file '$rc_file'\n"; + return 1; + } + # PREVIOUS VERSION +# if ( ! -r $rc_file ) { +# warn "$My_name: I cannot read the rc-file '$rc_file'\n", +# " or at least that's what Perl (for $^O) reports\n"; +# return 1; +# } +# do( $rc_file ); + if ( $@ ) { + # Indent each line of possibly multiline message: + my $message = prefix( $@, " " ); + warn "$My_name: Initialization file '$rc_file' gave an error:\n", + "$message\n"; + die "$My_name: Stopping because of problem with rc file\n"; + # Use the following if want non-fatal error. + return 2; + } + return 0; +} #END process_rc_file + +#************************************************************ + +sub execute_code_string { + # Usage execute_code_string( string_of_code ) + # Run the perl code contained in first argument + # Halt if there is a syntax error or other problem. + # ???Should I leave the exiting to the caller (perhaps as an option)? + # But I can always catch it with an eval if necessary. + # That confuses ctrl/C and ctrl/break handling. + my $code = $_[0]; + warn "$My_name: Executing initialization code specified by -e:\n", + " '$code'...\n" + if $diagnostics; + eval $code; + # The return value from the eval is not useful, since it is the value of + # the last expression evaluated, which could be anything. + # The correct test of errors is on the value of $@. + + if ( $@ ) { + # Indent each line of possibly multiline message: + my $message = prefix( $@, " " ); + die "$My_name: ", + "Stopping because executing following code from command line\n", + " $code\n", + "gave an error:\n", + "$message\n"; + } +} #END execute_code_string + +#************************************************************ + +sub cleanup1 { + # Usage: cleanup1( directory, exts_without_period, ... ) + # + # The directory and the root file name are fixed names, so I must escape + # any glob metacharacters in them: + my $dir = fix_pattern( shift ); + my $root_fixed = fix_pattern( $root_filename ); + foreach (@_) { + (my $name = /%R/ ? $_ : "%R.$_") =~ s/%R/$dir$root_fixed/; + unlink_or_move( glob( "$name" ) ); + } +} #END cleanup1 + +#************************************************************ + +sub cleanup_cusdep_generated { + # Remove files generated by custom dependencies + rdb_for_all( \&cleanup_one_cusdep_generated ); +} #END cleanup_cusdep_generated + +#************************************************************ + +sub cleanup_one_cusdep_generated { + # Remove destination file generated by one custom dependency + # Assume rule context, but not that the rule is a custom dependency. + # Only delete destination file if source file exists (so destination + # file can be recreated) + if ( $$Pcmd_type ne 'cusdep' ) { + # NOT cusdep + return; + } + if ( (-e $$Pdest) && (-e $$Psource) ) { + unlink_or_move( $$Pdest ); + } + elsif ( (-e $$Pdest) && (!-e $$Psource) ) { + warn "$My_name: For custom dependency '$rule',\n", + " I won't delete destination file '$$Pdest'\n", + " because the source file '$$Psource' doesn't exist,\n", + " so the destination file may not be able to be recreated\n"; + } +} #END cleanup_one_cusdep_generated + +#************************************************************ +#************************************************************ +#************************************************************ + +# Error handling routines, warning routines, help + +#************************************************************ + +sub die_trace { + # Call: die_trace( message ); + &traceback; # argument(s) passed unchanged + die "\n"; +} #END die_trace + +#************************************************************ + +sub traceback { + # Call: &traceback + # or traceback( message, ) + my $msg = shift; + if ($msg) { warn "$msg\n"; } + warn "Traceback:\n"; + my $i=0; # Start with immediate caller + while ( my ($pack, $file, $line, $func) = caller($i++) ) { + if ($func eq 'die_trace') { next; } + warn " $func called from line $line\n"; + } +} #END traceback + +#************************************************************ + +sub exit_msg1 +{ + # exit_msg1( error_message, retcode [, action]) + # 1. display error message + # 2. if action set, then restore aux file + # 3. exit with retcode + warn "\n------------\n"; + warn "$My_name: $_[0].\n"; + warn "-- Use the -f option to force complete processing.\n"; + + my $retcode = $_[1]; + if ($retcode >= 256) { + # Retcode is the kind returned by system from an external command + # which is 256 * command's_retcode + $retcode /= 256; + } + exit $retcode; +} #END exit_msg1 + +#************************************************************ + +sub warn_running { + # Message about running program: + if ( $silent ) { + warn "$My_name: @_\n"; + } + else { + warn "------------\n@_\n------------\n"; + } +} #END warn_running + +#************************************************************ + +sub exit_help +# Exit giving diagnostic from arguments and how to get help. +{ + warn "\n$My_name: @_\n", + "Use\n", + " $my_name -help\nto get usage information\n"; + exit 10; +} #END exit_help + + +#************************************************************ + +sub print_help +{ + print + "$My_name $version_num: Automatic LaTeX document generation routine\n\n", + "Usage: $my_name [latexmk_options] [filename ...]\n\n", + " Latexmk_options:\n", + " -aux-directory=dir or -auxdir=dir \n", + " - set name of directory for auxiliary files (aux, log)\n", + " - Currently this only works with MiKTeX\n", + " -bibtex - use bibtex when needed (default)\n", + " -bibtex- - never use bibtex\n", + " -bibtex-cond - use bibtex when needed, but only if the bib files exist\n", + " -bm - Print message across the page when converting to postscript\n", + " -bi - Set contrast or intensity of banner\n", + " -bs - Set scale for banner\n", + " -commands - list commands used by $my_name for processing files\n", + " -c - clean up (remove) all nonessential files, except\n", + " dvi, ps and pdf files.\n", + " This and the other clean-ups are instead of a regular make.\n", + " -C - clean up (remove) all nonessential files\n", + " including aux, dep, dvi, postscript and pdf files\n", + " and file of database of file information\n", + " -CA - clean up (remove) all nonessential files.\n", + " Equivalent to -C option.\n", + " -CF - Remove file of database of file information before doing \n", + " other actions\n", + " -cd - Change to directory of source file when processing it\n", + " -cd- - Do NOT change to directory of source file when processing it\n", + " -dependents or -deps - Show list of dependent files after processing\n", + " -dependents- or -deps- - Do not show list of dependent files\n", + " -deps-out=file - Set name of output file for dependency list,\n", + " and turn on showing of dependency list\n", + " -dF - Filter to apply to dvi file\n", + " -dvi - generate dvi\n", + " -dvi- - turn off required dvi\n", + " -e - Execute specified Perl code (as part of latexmk start-up\n", + " code)\n", + " -f - force continued processing past errors\n", + " -f- - turn off forced continuing processing past errors\n", + " -gg - Super go mode: clean out generated files (-CA), and then\n", + " process files regardless of file timestamps\n", + " -g - process regardless of file timestamps\n", + " -g- - Turn off -g\n", + " -h - print help\n", + " -help - print help\n", + " -jobname=STRING - set basename of output file(s) to STRING.\n", + " (Like --jobname=STRING on command line for many current\n", + " implementations of latex/pdflatex.)\n", + " -l - force landscape mode\n", + " -l- - turn off -l\n", + " -latex= - set program used for latex.\n", + " (replace '' by the program name)\n", + " -latexoption=